PhoneGap:检测是否在桌面浏览器上运行


118

我正在开发一个将PhoneGap:Build用于移动版本的Web应用程序,并希望针对“桌面”和移动版本使用单个代码库。我希望能够检测到PhoneGap呼叫是否可以正常工作(即,在支持PhoneGap的移动设备上的用户)。

我已经搜索过,无法相信没有简单的方法可以做到这一点。许多人提出了建议。

除非您从应用程序的桌面版本中删除PhoneGap Javascript文件,否则所有这些都不起作用,这违背了我拥有一个代码库的目标。

到目前为止,我想出的唯一解决方案是浏览器/用户代理嗅探,但这至少可以说是不可靠的。欢迎任何更好的解决方案!

编辑:稍微好一点的解决方案是尝试在一些小的超时后调用PhoneGap函数-如果它不起作用,则假定用户在桌面Web浏览器上。


由于您使用的是Build,请参见下面的@bt答案:stackoverflow.com/a/18478002/241244。似乎它可能比被接受和投票最多的答案更好。

我避免使用运行时检测来支持显式的构建时配置,因为它是100%有效的。我只是将一个本地变量传递给我的index.jade模板,例如{isPhonegap:true},然后可以在模板中有条件地包含phonegap.js脚本,并执行我想要的所有特定于phonegap的初始化。
Jesse Hattabaugh 2015年

Answers:


115

我使用以下代码:

if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/)) {
  document.addEventListener("deviceready", onDeviceReady, false);
} else {
  onDeviceReady(); //this is the browser
}

更新

还有许多其他方法可以检测phonegap是否在浏览器上运行,这是另一个不错的选择:

var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
    // PhoneGap application
} else {
    // Web page
}  

如此处所示:在移动浏览器或PhoneGap应用程序之间进行检测


感谢您这样做-等待了很长时间,看看其他人的建议后,这似乎是最好的解决方案。干杯。
aaronsnoswell 2012年

35
这是不准确的,因为如果我将在设备浏览器中打开同一页面,则onDeviceReady()将永远不会调用。另外,如果我将在浏览器中更改UserAgent(出于调试目的),则onDeviceReady()将永远不会调用二者之一。
Slavik Meltser 2012年

3
不知道您在说什么-但似乎是在暗示这将导致使用手机浏览器出现问题...这是一种在台式机浏览器而非手机上进行测试的解决方案。
sirmdawg

7
在设备浏览器中打开应用程序时,这无济于事。更好的解决方案:检查window.cordova。在iPhone Simulator(浏览器)或Android设备(浏览器)中进行的测试也应检测到PhoneGap。那就是我发展的方式。但是有很多可能性可以完成任务。;-) Thx发布您的解决方案!
马里奥

我很困惑,Windows Phone等其他平台又如何呢?他们是否有与该正则表达式匹配的userAgent?快速的Google搜索意味着:madskristensen.net/post/Windows-Phone-7-user-agents.aspx
2013年

49

我几天前写了一篇关于它的文章。这是您可以找到的最佳解决方案(直到PhoneGap会发布某些内容,也许有可能没有),它简短,简单且完美(我已经以各种可能的方式和平台对其进行了检查)。

此功能将完成98%的情况。

/**
 * Determine whether the file loaded from PhoneGap or not
 */
function isPhoneGap() {
    return (window.cordova || window.PhoneGap || window.phonegap) 
    && /^file:\/{3}[^\/]/i.test(window.location.href) 
    && /ios|iphone|ipod|ipad|android/i.test(navigator.userAgent);
}

if ( isPhoneGap() ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

要完成另外2%的情况,请按照以下步骤操作(这需要对本机代码进行一些更改):

创建一个名为__phonegap_index.html的文件,其源代码为:

<!-- __phonegap_index.html -->
<script type="text/javascript">
    function isPhoneGap() {
        //the function's content is as described above
    }

    //ensure the 98% that this file is called from PhoneGap.
    //in case somebody accessed this file directly from the browser.
    if ( isPhoneGap() )
        localStorage.setItem("isPhoneGap","1");

    //and redirect to the main site file.
    window.location = "index.html";
</script>

现在,在本机上,只需在所有PhoneGap平台上将起始页面从index.html更改为__phonegap_index.html。假设我的项目名称为example,您需要更改的文件为(与PhoneGap版本2.2.0一样):

  • iOS版 -CordovaLibApp/AppDelegate.m
  • Android的 -src/org/apache/cordova/example/cordovaExample.java
  • Windows 8的 -example/package.appxmanifest
  • 黑莓 -www/config.xml
  • WebOS的 -framework/appinfo.json
  • 巴达 - src/WebForm.cpp(第56行)
  • Window Phone 7-不知道在哪里(有人还在该平台上开发?!)

最后,无论它是否在PhoneGap上运行,您都可以在网站上的任何位置使用它:

if ( localStorage.getItem("isPhoneGap") ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

希望能帮助到你。:-)


4
发现这个答案是最好的!
blong824

3
是的,它可以工作,但是有时下一部分代码不是正确的,/^file:\/{3}[^\/]/i.test(window.location.href)但是我们正在使用PhoneGap,例如,当从另一个页面在config.xml上加载index.html时,就像这样<content src="http://10.100.1.147/" />
vudduu 2013年

3
(cordova || PhoneGap || phonegap) 如果未定义任何变量,则表达式将引发ReferenceError。您应该用进行测试typeof cordova !== undefined,对吧?
rojobuffalo 2015年

1
@rblakeley你是对的。我将第一行切换为:return ( typeof cordova !== undefined || typeof PhoneGap !== undefined || typeof phonegap !== undefined )
ethanpil

1
@rojobuffalo:答案似乎已经被修改,使它再次按预期工作(ReferenceError由于window前缀,它不再抛出异常)。只是以为我会指出这一点,因为这实际上会使评论链过时(因此不正确)。
Priidu Neemre '17

27

我知道它已经回答了一段时间,但是“ PhoneGap.available”已经不存在了。您应该使用:

if (window.PhoneGap) {
  //do stuff
}

或从1.7开始,首选:

if (window.cordova) {
  //do stuff
}

EDIT 2019:如评论中所述,仅当您不将cordova lib包含在桌面浏览器版本中时,此方法才有效。当然,对于您定位的每个设备,仅包含严格的最低javascript / html / css文件是一种很好的做法


18
这是不正确的,因为如果包括脚本cordova-xxxjs,即使已加载到浏览器中,也将始终定义window.PhoneGap或window.cordova。
Slavik Meltser 2012年

您能帮我一个例子吗?仅加载index.html。我正在做的是我已将本地服务器www文件夹下的所有文件上传到本地,我正在加载index.html。但是设备已准备就绪不被解雇。
纳西夫

5
现在,这似乎是正确的答案(至少使用Cordova 3.4)。所有其他方法都只是浪费时间,因为现在将cordova.js通过简单的<script type =“ text / javascript” src =“ cordova.js”> </ script>注入到应用程序中。您实际上并未指向实际文件,因此在浏览器中运行时不会加载该文件。它仅在移动设备上运行的Cordova构建中存在。
Michael Oryl

如果使用PhoneGap Build,这似乎会特别好用。

4
@SlavikMe不要在非cordova版本中包含cordova脚本。
杰克逊

21

我们发现告诉我们是否在cordova / phonegap应用程序中的最可靠方法是使用此配置AppendUserAgent修改cordova应用程序的用户代理。

config.xml添加:

<preference name="AppendUserAgent" value="Cordova" />

然后致电:

var isCordova = navigator.userAgent.match(/Cordova/i))

为什么?

  1. window.cordovadocument.addEventListener('deviceready', function(){});受赛车条件的约束
  2. navigator.standalone<content src="index.html" />网站(例如:<content src="https://www.example.com/index.html" />或使用cordova-plugin-remote-jection)时不起作用
  3. 尝试将用户代理列入白名单以猜测它是否是真正的浏览器非常复杂。Android浏览器通常是自定义Web视图。

2
我们甚至可以在其中添加应用程序版本!(最好是带有一些自动版本的凹凸逻辑)ex; Cordova AppName/v0.0.1<3这样,您甚至可以以某种方式使用它进行跟踪(但请注意,任何人都可以修改其用户代理,因此不要依赖它进行安全性关键验证)
GabLeRoux

这似乎是最简单的方法。亚军似乎正在测试文档URL中是否缺少http://或https://,但是我可以设想可能无法实现的情况。
JD史密斯

14

我认为这是最简单的: var isPhoneGap = (location.protocol == "file:")

编辑 对于一些没有用的人。然后,您可以尝试(尚未测试)

var isPhoneGap = ! /^http/.test(location.protocol);

1
我以为PhoneGap会为其所有设备上文件运行内部服务器?
aaronsnoswell,2012年

我喜欢。在localhost上开发时,这是最好的解决方案。(尝试了很多之后,我希望这可以在所有情况下都起作用。)谢谢!
马里奥

1
当我测试远程文件时,这在波纹模拟器中不起作用
Jesse Hattabaugh 2013年

在WP8中也不起作用,协议为“ x-wmapp0:”。不能确定将来还会使用其他“协议”。
阿德里安

好吧,您也可以--tryvar isPhoneGap = ! /^http/.test(document.location.protocol)
Yuval

8

这对我有效(运行1.7.0)

if (window.device) {
  // Running on PhoneGap
}

在台式机Chrome和Safari上进行了测试。


3
这几乎与绑定到“ deviceready”事件相同。如果未定义window.device,则无法确定phonegap / cordova加载速度是否缓慢,或者该事件永远不会触发。
Wytze

8
在触发“ deviceready”事件之前未定义window.device。
Slavik Meltser 2012年

2
并祈祷没有其他程序员拥有定义一个称为“设备”的新全局变量的快乐主意。
史密斯先生

7

像原始海报一样,我正在使用phonegap构建服务。经过两天的时间和近50个测试构建,我提出了一个非常适合我的优雅解决方案。

我无法使用UA嗅探,因为我想测试并在移动浏览器中运行。我最初决定使用cobberboy的功能齐全的技术。这对我不起作用,因为“ howPatientAreWe:10000”延迟/超时对于浏览器内开发来说太麻烦了。并将其设置为较低值有时会导致应用/设备模式下的测试失败。必须有另一种方式...

phonegap构建服务要求phonegap.js在将应用程序的文件提交到服务之前,从代码存储库中删除该文件。因此,我能够测试它的存在,以确定是否在浏览器与应用程序中运行。

另一个警告,我也使用jQueryMobile,因此jQM和phonegap必须先初始化,然后才能开始任何自定义脚本。以下代码放在该应用程序的自定义index.js文件的开头(在jQuery之后,在jQM之前)。同样,phonegap构建文档说要放置<script src="phonegap.js"></script>在HTML中的某个位置。我将其完全省略,并使用$ .getScript()加载它以测试其存在。

isPhoneGap = false;
isPhoneGapReady = false;
isjQMReady = false;

$.getScript("phonegap.js")
.done(function () {
    isPhoneGap = true;
    document.addEventListener("deviceready", function () {
        console.log("phonegap ready - device/app mode");
        isPhoneGapReady = true;
        Application.checkReadyState();
    }, false);
})
.fail(function () {
    console.log("phonegap load failed - browser only");
    isPhoneGapReady = true;
    Application.checkReadyState();
});

$(document).bind("mobileinit", function () {
    Application.mobileInit();
    $(document).one("pageinit", "#Your_First_jQM_Page", function () {
        isjQMReady = true;
        Application.checkReadyState();
    });
});

Application = {
    checkReadyState: function () {
        if (isjQMReady && isPhoneGapReady) {
            Application.ready();
        }
    },
    mobileInit: function () {
        // jQM initialization settings go here
        // i.e. $.mobile.defaultPageTransition = 'slide';
    },
    ready: function () {
        // Both phonegap (if available) and jQM are fired up and ready
        // let the custom scripting begin!
    }
}

6

有趣的是,有很多答案,但是它们不包括以下三个选项:

1 – cordova.js将在全局范围内设置cordova对象。如果有,那么您很可能在Cordova示波器上运行。

var isCordovaApp = !!window.cordova;

2 – Cordova将运行您的应用程序,就像您从桌面打开HTML文档一样。代替HTTP协议,它将使用FILE。检测到这一点将使您有机会假设您的应用已在本地加载。

var isCordovaApp = document.URL.indexOf('http://') === -1
  && document.URL.indexOf('https://') === -1;

3 –使用cordova脚本的load事件检测上下文。脚本include可以在构建过程中轻松删除,否则脚本加载只会在浏览器中失败。这样就不会设置此全局变量。

<script src="../cordova.js" onload="javascript:window.isCordovaApp = true;"></script>

信誉来自Adobe的Damien Antipa


5

我使用这种方法:

debug = (window.cordova === undefined);

debug将在设备true上的浏览器环境中false



3

问题的实质在于,只要未定义cordova.device,您的代码就无法确定这是因为cordova确定不支持您的设备,还是因为cordova仍在准备自身,并且deviceready将在以后触发(或第三种选择:cordova无法正确加载)。

唯一的解决方案是定义等待时间,并确定在此时间之后,您的代码必须假定不支持该设备。我希望cordova在某个地方设置一个参数,说“我们已经尝试找到一种受支持的设备并放弃了”,但是似乎没有这样的参数。

一旦建立,您可能需要在没有支持的设备的情况下精确地做一些特定的事情。就我而言,就像隐藏指向该设备的应用市场的链接一样。

我拼凑了这个功能,它应该涵盖几乎所有情况。它使您可以定义设备就绪处理程序,设备永不就绪处理程序和等待时间。

//Deals with the possibility that the code will run on a non-phoneGap supported
//device such as desktop browsers. Gives several options including waiting a while
//for cordova to load after all.
//In:
//onceReady (function) - performed as soon as deviceready fires
//patience 
//  (int) - time to wait before establishing that cordova will never load
//  (boolean false) - don't wait: assume that deviceready will never fire
//neverReady 
//  (function) - performed once it's established deviceready will never fire
//  (boolean true) - if deviceready will never fire, run onceReady anyhow
//  (boolean false or undefined) - if deviceready will never fire, do nothing
function deviceReadyOrNot(onceReady,patience,neverReady){

    if (!window.cordova){
            console.log('Cordova was not loaded when it should have been')
            if (typeof neverReady == "function"){neverReady();}
        //If phoneGap script loaded...
        } else {
            //And device is ready by now...
            if  (cordova.device){
                callback();
            //...or it's loaded but device is not ready
            } else {
                //...we might run the callback after
                if (typeof patience == "number"){
                    //Run the callback as soon as deviceready fires
                    document.addEventListener('deviceready.patience',function(){
                        if (typeof onceReady == "function"){onceReady();}
                    })
                    //Set a timeout to disable the listener
                    window.setTimeout(function(){
                        //If patience has run out, unbind the handler
                        $(document).unbind('deviceready.patience');
                        //If desired, manually run the callback right now
                        if (typeof neverReady == 'function'){neverReady();}
                    },patience);
                //...or we might just do nothing
                } else {
                    //Don't bind a deviceready handler: assume it will never happen
                    if (typeof neverReady == 'function'){neverReady();} 
                    else if (neverReady === true){onceReady();} 
                    else {
                       //Do nothing
                    }
                }
            }
    }

}

3

我这样做的方式是使用一个全局变量,该变量被仅浏览器版本的cordova.js覆盖。在您的主要html文件中(通常是index.html),我有以下与顺序相关的脚本:

    <script>
        var __cordovaRunningOnBrowser__ = false
    </script>
    <script src="cordova.js"></script> <!-- must be included after __cordovaRunningOnBrowser__ is initialized -->
    <script src="index.js"></script> <!-- must be included after cordova.js so that __cordovaRunningOnBrowser__ is set correctly -->

在里面,cordova.js我简单地说:

__cordovaRunningOnBrowser__ = true

在为移动设备构建时,将不使用cordova.js(而是使用特定于平台的cordova.js文件),因此此方法的好处是无论协议,userAgent或库如何都是100%正确的变量(可能会更改)。我可能还应该在cordova.js中包含其他内容,但是我还不知道它们是什么。


非常有趣的方法。

不过,您实际上并不需要初始脚本。您可以测试一下它是否已完全设置:if ( typeof __cordovaRunningOnBrowser__ !== 'undefined' ) { stuff(); } ..对吗?

是的,未定义可能表明其他问题。
BT

3

基于SlavikMe解决方案的另一种方法:

只需使用index.html从您的PhoneGap源传递给的查询参数即可。即在Android中,而不是

super.loadUrl("file:///android_asset/www/index.html");

super.loadUrl("file:///android_asset/www/index.html?phonegap=1");

SlavikMe提供了在其他平台上执行此操作的清单。

然后,您index.html可以简单地执行以下操作:

if (window.location.href.match(/phonegap=1/)) {
  alert("phonegap");
}
else {
  alert("not phonegap");
}

1
我正在使用Cordova 3.4.1,它甚至更简单:您只需要将<content src="index.html" />config.xml文件中的选项更改为即可<content src="index.html?cordova=1" />。到目前为止,它似乎可行,并且是此处建议的最佳解决方案。
Martin M.

2

为了保留一个代码库,有趣的是代码在其上运行的“平台”。对我来说,这个“平台”可以是三种不同的东西:

  • 0:计算机浏览器
  • 1:移动浏览器
  • 2:phonegap / cordova

检查平台的方式:

var platform;
try {
 cordova.exec(function (param) {
   platform = 2;
  }, function (err) {}, "Echo", "echo", ["test"]);
} catch (e) {
  platform = 'ontouchstart' in document.documentElement ? 1 : 0;
}

注意:

  • 这必须只能运行cordova.js加载后(身体的onload(...),$(文件)。就绪(...))

  • 具有触摸屏的笔记本电脑和台式机显示器中将出现document.documentElement中的“ ontouchstart”,因此即使它是台式机,它也会报告移动浏览器。有多种方法可以进行更精确的检查,但是我使用它是因为它仍然可以满足我需要的99%的情况。您始终可以用该行代替更可靠的内容。


1
我建议使用typeof cordova !== 'undefined'而不是钓鱼作为例外。
卡拉托阿

1

阿龙,尝试

if (PhoneGap.available){
    do PhoneGap stuff;
}

不,我没有。查看phonegap-1.1.0.js源代码。PhoneGap.available = DeviceInfo.uuid!==未定义;
GeorgeW 2012年

1

GeorgeW的解决方案还可以,但是即使在真实设备上,PhoneGap.available也仅在加载PhoneGap的内容之后才为true,例如,调用了document.addEventListener('deviceready',onDeviceReady,false)中的onDeviceReady。

在此之前,如果您想知道,可以这样做:

runningInPcBrowser =
    navigator.userAgent.indexOf('Chrome')  >= 0 ||
    navigator.userAgent.indexOf('Firefox') >= 0

该解决方案假定大多数开发人员使用Chrome或Firefox进行开发。


OP正在寻找一个针对生产网站的解决方案,而不仅仅是开发人员。
Jesse Hattabaugh

1

我有同样的问题。

我倾向于将#cordova = true添加到cordova客户端加载的URL并测试我的网页中的location.hash.indexOf(“ cordova = true”)> -1。


最后,我走了Al Renaud在他的第4点建议的路线,然后让构建脚本决定了。将网站代码复制到android资产文件夹时,它会取消注释index.html中的标志。// UNCOMMENT-ON-DEPLOY:window._appInfo.isCordova = true; 当构建脚本将index.html复制到我的android资产/ www文件夹中时,我在其上运行ed以删除// UNCOMMENT-ON-DEPLOY:字符串。#Massage index.html告诉它正在运行cordova ed“ $ DEST / index.html” <<-EOF 1,\ $ s / \ / \ / UNCOMMENT-ON-DEPLOY:// wq EOF
Austin France

1

以下内容适用于最新的PhoneGap / Cordova(2.1.0)。

这个怎么运作:

  • 概念很简单
  • 我颠倒了上述某些超时解决方案的逻辑。
  • 注册device_ready事件(根据PhoneGap docs的建议
    • 如果事件在超时后仍未触发,则退回至假定浏览器。
    • 相反,以上其他解决方案则依赖于测试某些PhoneGap功能或其他功能,并观察其测试中断。

优点:

  • 使用推荐的PhoneGap device_ready事件。
  • 移动应用程序没有延迟。一旦device_ready事件触发,我们就继续。
  • 没有用户代理嗅探(我喜欢将我的应用作为移动网站进行测试,因此浏览器嗅探对我而言不是一种选择)。
  • 不依赖未记录的(因此易碎的)PhoneGap功能/属性。
  • 即使使用台式机或移动浏览器,也应将cordova.js保留在代码库中。因此,这回答了OP的问题。
  • Wytze在上面说过:“我希望Cordova在某个地方设置一个参数,说“我们试图找到一种受支持的设备并放弃了”,但似乎没有这样的参数。所以我在这里提供一个。

缺点:

  • 超时很糟糕。但是我们的移动应用逻辑并不依赖于延迟。相反,当我们处于网络浏览器模式时,它用作备用。

==

创建一个全新的空白PhoneGap项目。在提供的样本index.js中,将底部的“ app”变量替换为此:

var app = {
    // denotes whether we are within a mobile device (otherwise we're in a browser)
    iAmPhoneGap: false,
    // how long should we wait for PhoneGap to say the device is ready.
    howPatientAreWe: 10000,
    // id of the 'too_impatient' timeout
    timeoutID: null,
    // id of the 'impatience_remaining' interval reporting.
    impatienceProgressIntervalID: null,

    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // `load`, `deviceready`, `offline`, and `online`.
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
        // after 10 seconds, if we still think we're NOT phonegap, give up.
        app.timeoutID = window.setTimeout(function(appReference) {
            if (!app.iAmPhoneGap) // jeepers, this has taken too long.
                // manually trigger (fudge) the receivedEvent() method.   
                appReference.receivedEvent('too_impatient');
        }, howPatientAreWe, this);
        // keep us updated on the console about how much longer to wait.
        app.impatienceProgressIntervalID = window.setInterval(function areWeThereYet() {
                if (typeof areWeThereYet.howLongLeft == "undefined") { 
                    areWeThereYet.howLongLeft = app.howPatientAreWe; // create a static variable
                } 
                areWeThereYet.howLongLeft -= 1000; // not so much longer to wait.

                console.log("areWeThereYet: Will give PhoneGap another " + areWeThereYet.howLongLeft + "ms");
            }, 1000);
    },
    // deviceready Event Handler
    //
    // The scope of `this` is the event. In order to call the `receivedEvent`
    // function, we must explicity call `app.receivedEvent(...);`
    onDeviceReady: function() {
        app.iAmPhoneGap = true; // We have a device.
        app.receivedEvent('deviceready');

        // clear the 'too_impatient' timeout .
        window.clearTimeout(app.timeoutID); 
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
        // clear the "areWeThereYet" reporting.
        window.clearInterval(app.impatienceProgressIntervalID);
        console.log('Received Event: ' + id);
        myCustomJS(app.iAmPhoneGap); // run my application.
    }
};

app.initialize();

function myCustomJS(trueIfIAmPhoneGap) {
    // put your custom javascript here.
    alert("I am "+ (trueIfIAmPhoneGap?"PhoneGap":"a Browser"));
}

1

几个月前,在启动我们的应用程序时,我偶然发现了这个问题,因为我们希望该应用程序也成为“ browser-compatible”(了解到某些功能在这种情况下会被阻止:录音,指南针等)。

100%用来预先确定应用程序执行上下文的唯一(并且我坚持要达到100%的条件)解决方案是:

  • 将JS“标志”变量初始化为true,并在全网络环境中将其更改为false;

  • 因此,您可以使用“ willIBeInPhoneGapSometimesInTheNearFuture()”之类的调用(这是PRE-PG,当然,您仍然需要一种POST-PG方法来检查是否可以调用PG API,但这很简单)。

  • 然后你说:“ but how do you determine the execution context?”;答案是:“您不要”(因为我认为您不能可靠地进行工作,除非PG的杰出人才会在其API代码中做到这一点);

  • 您编写了一个可为您完成的构建脚本:一个具有两个变体的代码库。


1

这并不是一个真正的问题的答案,但是,当我在台式机浏览器中进行测试时,我只是设置了一个localstorage值,以使浏览器在设备未准备好启动时加载该应用程序。

function main() {

    // Initiating the app here.
};

/* Listen for ready events from pheongap */
document.addEventListener("deviceready", main, false);

// When testing outside ipad app, use jquerys ready event instead. 
$(function() {

    if (localStorage["notPhonegap"]) {

        main();
    }
});

1

除非您从应用程序的桌面版本中删除PhoneGap Javascript文件,否则所有这些都不起作用,这违背了我拥有一个代码库的目标。

另一种选择是使用合并文件夹,请参见下面的屏幕截图。

您可以添加特定于平台的文件/覆盖默认文件。

(在某些情况下应该可以解决问题)

在此处输入图片说明


换句话说:您不会检测到浏览器,而只是不包​​含用于桌面构建的某些文件/仅针对iOS附加某些文件。


1

即使模拟设备处于活动状态,也可以检测桌面浏览器

在Windows和Mac计算机上均可使用。需要找到针对Linux的解决方案查看详细信息

var mobileDevice = false;
if(navigator.userAgent.match(/iPhone|iPad|iPod|Android|BlackBerry|IEMobile/))
    mobileDevice = true; 

if(mobileDevice && navigator.platform.match(/Win|Mac/i))
    mobileDevice = false; // This is desktop browser emulator

if(mobileDevice) {
    // include cordova files
}

0

我实际上发现这里列出的两种技术的组合效果最好,首先检查是否可以访问cordova / phonegap,还检查设备是否可用。像这样:

function _initialize() {
    //do stuff
}

if (window.cordova && window.device) {
    document.addEventListener('deviceready', function () {
      _initialize();
    }, false);
} else {
   _initialize();
}

0

试试这个方法:

/**
 * Returns true if the application is running on an actual mobile device.
 */
function isOnDevice(){
    return navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/);
}

function isDeviceiOS(){
    return navigator.userAgent.match(/(iPhone)/);
}

/**
 * Method for invoking functions once the DOM and the device are ready. This is
 * a replacement function for the JQuery provided method i.e.
 * $(document).ready(...).
 */
function invokeOnReady(callback){
    $(document).ready(function(){
        if (isOnDevice()) {
            document.addEventListener("deviceready", callback, false);
        } else {
            invoke(callback);
        }
    });
}

0

我结合了GeorgeWmkprogramming的建议:

   if (!navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
      onDeviceReady();
   } else if (Phonegap.available){
      onDeviceReady();
   } else {
      console.log('There was an error loading Phonegap.')
   }

0

我想它们在某种程度上并没有什么不同?哈哈...不好笑。谁不认为这不会成为问题?这是您考虑的最简单的解决方案。将其他文件推送到服务器,然后再对PhoneGap进行操作。我也会暂时使用上面建议的http:检查。

var isMobileBrowserAndNotPhoneGap = (document.location.protocol == "http:");

我的兴趣是提高浏览器的导航栏,所以实际上我可以删除孤立脚本的标签并按[在DW中]进行重建(无论如何,它们都会进行一些清理以便部署,因此这可以是其中的一项任务。)这是一个很好的选择(考虑到可用的东西不多),当推送到PG时,只需使用isMobileBrowserAndNotPhoneGap手动将其注释掉即可。在我的情况下,再次对我来说,我将简单删除(隔离代码)文件的标签,该标签在移动浏览器时会推高导航栏(速度会更快,更小)。[是的,如果您可以隔离该优化但手动的解决方案的代码。]


0

稍作修改,但对我来说完美无任何问题。

目的是仅在嵌入式设备而非台式机上加载Cordova,因此我完全避免在台式机浏览器上加载cordova。UI和MVVM的测试和开发非常方便。

把这个代码例如。在cordovaLoader.js文件中

function isEmbedded() {
    return  
    // maybe you can test for better conditions
    //&& /^file:\/{3}[^\/]/i.test(window.location.href) && 
     /ios|iphone|ipod|ipad|android/i.test(navigator.userAgent);
}

if ( isEmbedded() )
{
   var head= document.getElementsByTagName('head')[0];
   var script= document.createElement('script');
   script.type= 'text/javascript';
   script.src= 'cordova-2.7.0.js';
   head.appendChild(script);
}

然后,不包含cordova javascript,而是包含cordovaLoader.js

<head>
  <script src="js/cordovaLoader.js"></script>
  <script src="js/jquery.js"></script>
  <script src="js/iscroll.js"></script>
  <script src="js/knockout-2.3.0.js"></script>
</head> 

轻松工作!:)



0

仅供参考,以 PhoneGap 3.x移动应用程序开发热点中的方式

var userLocale = "en-US";
function startApp()
{
// do translations, format numbers, etc.
}
function getLocaleAndStartApp()
{
    navigator.globalization.getLocaleName (
        function (locale) {
            userLocale = locale.value;
            startApp();
        },
        function () {
            // error; start app anyway
            startApp();
        });
}
function executeWhenReady ( callback ) {
    var executed = false;
    document.addEventListener ( "deviceready", function () {
        if (!executed) {
            executed = true;
            if (typeof callback === "function") {
                callback();
            }
        }
    }, false);
    setTimeout ( function () {
        if (!executed) {
            executed = true;
            if (typeof callback === "function") {
                callback();
            }
        }
    }, 1000 );
};
executeWhenReady ( function() {
    getLocaleAndStartApp();
} );

在YASMF框架中

https://github.com/photokandyStudios/YASMF-Next/blob/master/lib/yasmf/util/core.js#L152


0

我正在尝试使用窗口对象,但是当我在InAppBrowser中打开远程URL时,它不起作用。无法完成。因此,实现它的最佳和最简单的方法是将一个字符串附加到需要从phonegap应用程序打开的url中。然后检查文档位置是否附加了字符串。

下面是它的简单代码

var ref = window.open('http://yourdomain.org#phonegap', '_blank', 'location=yes');

您会看到一个字符串被添加到URL“ #phonegap”。因此,在域URL中添加以下脚本

if(window.location.indexOf("#phonegap") > -1){
     alert("Url Loaded in the phonegap App");
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.