PhoneGap:检测是不是在桌面浏览器上运行
Posted
技术标签:
【中文标题】PhoneGap:检测是不是在桌面浏览器上运行【英文标题】:PhoneGap: Detect if running on desktop browserPhoneGap:检测是否在桌面浏览器上运行 【发布时间】:2011-12-25 11:11:13 【问题描述】:我正在开发一个使用 PhoneGap:Build 移动版本的 Web 应用程序,并希望为“桌面”和移动版本提供一个代码库。我希望能够检测 PhoneGap 呼叫是否可以正常工作(即用户是否使用支持 PhoneGap 的移动设备)。
我已经搜索过了,无法相信没有简单的方法可以做到这一点。很多人提出了建议;
http://www.sencha.com/forum/showthread.php?144127-Checking-if-running-in-PhoneGap-or-Mobile-Web-Browser http://groups.google.com/group/phonegap/browse_thread/thread/322e80bd41bb1a54/a421300eb2a2029f?lnk=gst&q=detect+desktop#a421300eb2a2029f http://groups.google.com/group/phonegap/browse_thread/thread/8a95dfeb0f313792/3ff10d8f35211739?lnk=gst&q=detect+desktop+browser#3ff10d8f35211739这些都不起作用,除非您从应用程序的桌面版本中删除 PhoneGap javascript 文件,这违背了我拥有一个代码库的目标。
到目前为止,我想出的唯一解决方案是浏览器/用户代理嗅探,但至少可以说这并不可靠。欢迎任何更好的解决方案!
编辑:稍微好一点的解决方案是在一些小的超时后尝试调用 PhoneGap 函数 - 如果它不起作用,则假设用户在桌面网络浏览器上。
【问题讨论】:
由于您使用的是 Build,请参阅下面的 @b-t 答案:***.com/a/18478002/241244。似乎它可能比接受和投票最多的答案更好。 我避免运行时检测以支持显式构建时配置,因为它是 100% 有效的。我只需将本地变量传递给我的 index.jade 模板,例如 isPhonegap: true,然后在模板中我可以有条件地包含 phonegap.js 脚本,并执行我想要的所有 phonegap 特定的初始化。 【参考方案1】:亚伦,试试
if (PhoneGap.available)
do PhoneGap stuff;
【讨论】:
不,我没有。查看 phonegap-1.1.0.js 源代码。 PhoneGap.available = DeviceInfo.uuid !== 未定义;【参考方案2】:GeorgeW 的解决方案是可以的,但是即使在真实设备上,PhoneGap.available 也只有在 PhoneGap 的东西加载后才为真,例如document.addEventListener('deviceready', onDeviceReady, false) 中的 onDeviceReady 已被调用。
在那之前,如果你想知道,你可以这样做:
runningInPcBrowser =
navigator.userAgent.indexOf('Chrome') >= 0 ||
navigator.userAgent.indexOf('Firefox') >= 0
此解决方案假定大多数开发人员使用 Chrome 或 Firefox 进行开发。
【讨论】:
OP 正在为生产网站寻找解决方案,而不仅仅是开发。【参考方案3】:我知道它已在不久前得到答复,但“PhoneGap.available”不再存在。 你应该使用:
if (window.PhoneGap)
//do stuff
或者从 1.7 开始,更喜欢:
if (window.cordova)
//do stuff
EDIT 2019:如 cmets 中所述,这仅在您未将 cordova lib 包含到桌面浏览器构建中时才有效。当然,最好只为您定位的每个设备包含严格的最低限度的 javascript/html/css 文件
【讨论】:
这不是真的,因为如果你包含脚本cordova-x.x.x.js,window.PhoneGap或window.cordova总是会被定义,即使它是在浏览器上加载的。 你能帮我举个例子吗?简单地加载 index.html。我正在做的是我已经上传了本地服务器 www 文件夹下的所有文件,我正在加载索引.html。但是准备好的设备没有被触发。 这似乎是现在的正确答案(至少在 Cordova 3.4 中)。所有其他方法都只是浪费时间,因为现在使用简单的 将 cordova.js 注入应用程序。您实际上并不指向真实文件,因此在浏览器中运行时不会加载它。它仅存在于在移动设备上运行的 Cordova 构建中。 如果使用PhoneGap Build,这似乎会特别好。 @SlavikMe 不要在非cordova构建中包含cordova脚本。【参考方案4】:我使用这个代码:
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
如此处所示:Detect between a mobile browser or a PhoneGap application
【讨论】:
感谢您 - 在等了很长时间后看到其他人的建议,这似乎是最好的解决方案。干杯。 这不准确,因为如果我将在设备浏览器上打开同一页面,onDeviceReady() 将永远不会调用。另外,如果我要更改浏览器中的 UserAgent(出于调试目的),onDeviceReady() 也永远不会调用。 不确定您在说什么 - 但您似乎在暗示这会导致使用手机浏览器出现问题...这是在您的桌面浏览器而不是手机上进行测试的解决方案。跨度> 当您在设备浏览器中打开应用程序时,这无济于事。更好的解决方案:检查 window.cordova。在 iPhone 模拟器(浏览器)或 Android 设备(浏览器)上进行测试也应该检测到 PhoneGap。我就是这样发展的。但是有很多可能性可以完成工作。 ;-) 感谢您发布您的解决方案! 我很困惑,其他平台比如windows phone呢?他们是否有与该正则表达式匹配的 userAgent?快速的谷歌搜索并不意味着:madskristensen.net/post/Windows-Phone-7-user-agents.aspx【参考方案5】:这对我有用(运行 1.7.0)
if (window.device)
// Running on PhoneGap
在桌面 Chrome 和 Safari 上测试。
【讨论】:
这与绑定到 'deviceready' 事件几乎相同。如果 window.device 没有定义,你无法判断 phonegap/cordova 是否加载缓慢,或者事件是否永远不会触发。 window.device 在“deviceready”事件触发之前没有定义。 并祈祷没有其他程序员有定义一个名为“device”的新全局变量的快乐想法。【参考方案6】:问题的本质在于,只要 cordova.device 未定义,您的代码就无法确定这是因为cordova 已确定您的设备不受支持,还是因为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
【讨论】:
【参考方案7】:我实际上发现这里列出的两种技术的组合效果最好,首先检查是否可以访问cordova / phonegap,并检查设备是否可用。像这样:
function _initialize()
//do stuff
if (window.cordova && window.device)
document.addEventListener('deviceready', function ()
_initialize();
, false);
else
_initialize();
【讨论】:
【参考方案8】:试试这个方法:
/**
* 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);
);
【讨论】:
【参考方案9】:我认为这是最简单的:
var isPhoneGap = (location.protocol == "file:")
编辑 对于一些没有工作的人。那你可以试试(没测试过)
var isPhoneGap = ! /^http/.test(location.protocol);
【讨论】:
我认为 PhoneGap 为所有设备上的文件运行了一个内部服务器? 我喜欢。在 localhost 上开发时,这是最好的解决方案。 (经过大量尝试,我希望这适用于所有场景。)谢谢! 当我测试远程文件时,这在波纹模拟器中不起作用 在 WP8 中也不起作用,协议是“x-wmapp0:”。无法确定将来会使用哪些其他“协议”。 嗯,你也可以 --tryvar isPhoneGap = ! /^http/.test(document.location.protocol)
【参考方案10】:
我使用GeorgeW 和mkprogramming 建议的组合:
if (!navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/))
onDeviceReady();
else if (Phonegap.available)
onDeviceReady();
else
console.log('There was an error loading Phonegap.')
【讨论】:
【参考方案11】:我也有同样的问题。
我倾向于将 #cordova=true 添加到由 cordova 客户端加载的 URL 并在我的网页中测试 location.hash.indexOf("cordova=true") > -1。
【讨论】:
最后,我按照 Al Renaud 在第 4 点建议的路线,让构建脚本决定。将网站代码复制到 android assets 文件夹时,它会取消 index.html 中的标志。 // UNCOMMENT-ON-DEPLOY: window._appInfo.isCordova = true;当构建脚本将 index.html 复制到我的 android assets/www 文件夹中时,我在其上运行 ed 以删除 // UNCOMMENT-ON-DEPLOY: 字符串。 # 按摩 index.html 告诉它正在运行 cordova ed "$DEST/index.html" 【参考方案12】:以下适用于我最新的 PhoneGap / Cordova (2.1.0)。
它是如何工作的:
概念非常简单 我颠倒了上述一些超时解决方案的逻辑。 注册 device_ready 事件(如recommended by the PhoneGap docs) 如果事件在超时后仍未触发,则回退到假设浏览器。 相比之下,上述其他解决方案依赖于测试某些 PhoneGap 功能或其他功能,并观察它们的测试中断。优点:
使用 PhoneGap 推荐的 device_ready 事件。 移动应用程序没有延迟。一旦 device_ready 事件触发,我们就会继续。 没有用户代理嗅探(我喜欢将我的应用程序作为移动网站进行测试,因此浏览器嗅探不是我的选择)。 不依赖未记录的(因此脆弱的)PhoneGap 功能/属性。 即使在使用桌面或移动浏览器时,也可以将 cordova.js 保存在代码库中。因此,这回答了 OP 的问题。 Wytze 上面说过:“我希望科尔多瓦在某处设置一个参数来说明“我们已尝试找到支持的设备并放弃了”,但似乎没有这样的参数。所以我在这里提供一个。缺点:
超时很糟糕。但是我们的移动应用逻辑不依赖于延迟;相反,当我们处于网络浏览器模式时,它被用作后备。==
创建一个全新的空白 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"));
【讨论】:
【参考方案13】:与原始海报一样,我正在使用 phonegap 构建服务。经过两天和近 50 次测试构建后,我想出了一个非常适合我的优雅解决方案。
我无法使用 UA 嗅探,因为我想在移动浏览器中进行测试和运行。我最初选择了鞋匠的实用技术。这对我不起作用,因为“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!
【讨论】:
【参考方案14】:我想在某些方面他们并没有那么不同,是吗?哈哈……不好笑。谁不认为这不会是一个问题? 这是供您考虑的最简单的解决方案。 将不同的文件推送到您的服务器,然后再推送到 PhoneGap。 我也会暂时使用上面建议的 http: 检查。
var isMobileBrowserAndNotPhoneGap = (document.location.protocol == "http:");
我的兴趣是将浏览器导航栏向上推,所以实际上我可以删除隔离脚本的标签并按下重建 [在 DW 中](无论如何它们都会对部署进行一些清理,所以这可能是其中一项任务。) 无论如何,我觉得这是一个不错的选择(考虑到没有太多可用的东西),只需在推送到 PG 时使用 isMobileBrowserAndNotPhoneGap 有效地手动注释掉内容)。 再次对我来说,在我的情况下,我将简单地删除(隔离代码)文件的标签,当它是移动浏览器时,它会向上推导航栏(它会更快更小)。 [所以,如果您可以隔离该优化但手动解决方案的代码。]
【讨论】:
【参考方案15】:几天前我写了一封post。这是你能找到的最好的解决方案(直到 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
Bada - src/WebForm.cpp
(第 56 行)
Window Phone 7 - 不知道在哪里(有人还在那个平台上开发?!)
最后,您可以在您网站的任何地方使用它,无论它是否在 PhoneGap 上运行:
if ( localStorage.getItem("isPhoneGap") )
alert("Running on PhoneGap!");
else
alert("Not running on PhoneGap!");
希望对您有所帮助。 :-)
【讨论】:
发现这个答案是最好的! 是的,它可以工作,但有时代码的下一部分不是真的/^file:\/3[^\/]/i.test(window.location.href)
但我们正在使用 PhoneGap,例如从另一个页面加载 index.html 时,在 config.xml 上类似这样<content src="http://10.100.1.147/" />
如果没有定义任何这些变量,表达式(cordova || PhoneGap || phonegap)
将抛出ReferenceError。您应该使用typeof cordova !== undefined
进行测试,对吧?
@rblakeley 你是对的。我将第一行改为:return ( typeof cordova !== undefined || typeof PhoneGap !== undefined || typeof phonegap !== undefined )
@rojobuffalo:看起来答案已被修改,使其再次按预期工作(ie由于window
,它不再抛出ReferenceError
字首)。只是想我会指出这一点,因为这实际上使评论链过时(因此不正确)。【参考方案16】:
这似乎是可行的,我已经在生产中使用它:
if (document.location.protocol == "file:")
// file protocol indicates phonegap
document.addEventListener("deviceready", function() $(initInternal); , false);
else
// no phonegap, start initialisation immediately
$(initInternal);
来源:http://tqcblog.com/2012/05/09/detecting-phonegap-cordova-on-startup/
【讨论】:
【参考方案17】:几个月前我在开始我们的应用程序时偶然发现了这个问题,因为我们希望应用程序也是“browser-compatible
”(理解在这种情况下某些功能会被阻止:录音,指南针,等等。)。
预先确定应用程序执行上下文的唯一100%
(我坚持 100% 的条件)解决方案是:
初始化一个JS“flag”变量为true,在全web上下文中改为false;
1234563然后你说:“but how do you determine the execution context
?”;答案是:“你不”(因为我认为你不能可靠,除非 PG 的那些聪明人会在他们的 API 代码中做到这一点);
您编写了一个构建脚本来为您完成它:一个代码库有两个变体。
【讨论】:
【参考方案18】:为了保持一个代码库,感兴趣的是代码运行的“平台”。对我来说,这个“平台”可以是三个不同的东西:
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 后运行(body onload(...), $(document).ready(...))
document.documentElement 中的'ontouchstart' 将出现在具有触摸屏的笔记本电脑和台式机显示器中,因此即使它是台式机,它也会报告移动浏览器。有多种方法可以进行更精确的检查,但我使用它是因为它仍然可以处理我需要的 99% 的案例。你总是可以用这条线来代替更健壮的东西。
【讨论】:
我建议使用typeof cordova !== 'undefined'
而不是寻找异常。【参考方案19】:
稍作修改,但对我来说非常完美,没有任何问题。
意图是仅在嵌入式设备上加载 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>
让您的工作轻松起来! :)
【讨论】:
【参考方案20】:我这样做的方式是使用一个全局变量,该变量被仅浏览器版本的 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 文件),因此这种方法的好处是无论协议、userAgents 怎样都100% 正确,或库变量(可能会改变)。我可能还应该在 cordova.js 中包含其他内容,但我还不知道它们是什么。
【讨论】:
非常有趣的方法。 虽然,您并不真的需要初始脚本。你可以测试它是否被设置:if ( typeof __cordovaRunningOnBrowser__ !== 'undefined' ) stuff();
..right?
是的,虽然未定义可能表明其他问题。【参考方案21】:
if ( "device" in window )
// phonegap
else
// browser
【讨论】:
【参考方案22】:另一种方式,基于 SlavikMe 的解决方案:
只需使用从 PhoneGap 源传递给 index.html
的查询参数即可。即,在 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");
【讨论】:
我使用的是 Cordova 3.4.1,它更简单:您只需将 config.xml 文件中的<content src="index.html" />
选项更改为 <content src="index.html?cordova=1" />
。到目前为止,它似乎有效,并且是迄今为止建议的最佳解决方案。【参考方案23】:
真的不是问题的答案,但是当我在桌面浏览器中进行测试时,我只是设置了一个 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();
);
【讨论】:
【参考方案24】:这些都不起作用,除非您从应用程序的桌面版本中删除 PhoneGap Javascript 文件,这违背了我拥有一个代码库的目标。
另一种选择是使用 merges 文件夹,请参见下面的屏幕截图。
您可以添加特定于平台的文件/覆盖默认文件。
(在某些情况下应该可以解决问题)
换句话说:您没有检测浏览器,只是不包含某些文件用于桌面构建/仅附加某些用于 iOS 的文件。
【讨论】:
【参考方案25】:有趣的是,有很多答案,但它们不包括这三个选项:
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 脚本的加载事件来检测上下文。脚本包含可以在构建过程中轻松删除,否则脚本加载将在浏览器中失败。这样这个全局变量就不会被设置了。
<script src="../cordova.js" onload="javascript:window.isCordovaApp = true;"></script>
归功于Damien Antipa from Adobe
【讨论】:
【参考方案26】:仅供参考 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
【讨论】:
【参考方案27】:我用这个方法:
debug = (window.cordova === undefined);
debug
在浏览器环境中为true
,在设备上为false
。
【讨论】:
【参考方案28】:即使模拟设备处于活动状态也检测桌面浏览器
适用于 Windows 和 Mac 机器。需要找linux的解决方案View details
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
【讨论】:
【参考方案29】:我正在尝试使用窗口对象,但它没有工作,因为我在 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");
【讨论】:
【参考方案30】:我们发现判断我们是否在cordova/phonegap 应用程序中最可靠的方法是使用此配置AppendUserAgent 修改cordova 应用程序的用户代理。
在config.xml
中添加:
<preference name="AppendUserAgent" value="Cordova" />
然后调用:
var isCordova = navigator.userAgent.match(/Cordova/i))
为什么?
window.cordova
和 document.addEventListener('deviceready', function());
受比赛条件限制
当<content src="index.html" />
是网站时,navigator.standalone
不起作用(例如:<content src="https://www.example.com/index.html" />
或 cordova-plugin-remote-injection)
尝试将用户代理列入白名单以猜测它是否是真正的浏览器非常复杂。 Android 浏览器通常是自定义 Web 视图。
【讨论】:
我们甚至可以在那里添加应用程序版本! (理想情况下带有一些自动版本的碰撞逻辑)例如;Cordova AppName/v0.0.1
这似乎是最万无一失的方法。亚军似乎正在测试文档 URL 中是否缺少 http:// 或 https://,但我可以设想可能出现的情况。
这毕竟是对我有用的。谢谢!以上是关于PhoneGap:检测是不是在桌面浏览器上运行的主要内容,如果未能解决你的问题,请参考以下文章
PhoneGap 中的 screen.width/device-width 与常规浏览器不同
如何以编程方式检测是不是在 Windows 桌面应用程序中启用/禁用了 javascript? (网络浏览器控件)