覆盖 Android 后退按钮是一个挑战 Cordova
Overriding Android back button is being a challenge Cordova
我正在使用 Cordova 包装的 JQuery Mobile 开发混合移动应用程序。
我的Jquery版本是2.1.4,Jquery手机版是1.4.5。同样,我的 Cordova CLI 版本是 5.3.3。
我需要重写 Android 后退按钮行为,这会杀死 activity。所以我使用了 Cordova 的 backbutton
监听器。我在 deviceready
上召集此活动。但是,在点击 Android 返回时,我没有调用事件并且应用程序正在被杀死。
我的index.html是,
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" href="css/jquery.mobile.theme.min.css"/>
<link rel="stylesheet" href="css/jquery.mobile.icons.min.css"/>
<link rel="stylesheet" type="text/css" href="libs/JQuery/jquery.mobile.icons-1.4.5.min.css"/>
<link rel="stylesheet" type="text/css" href="libs/JQuery/jquery.mobile.structure-1.4.5.min.css"/>
<!-- PAGE/APPLICATION STYLE SHEETS -->
<link rel="stylesheet" type="text/css" href="css/index.css">
<script src="libs/JQuery/jquery-2.1.4.min.js"></script>
<script src="libs/JQuery/jquery.mobile-1.4.5.min.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<title>Override Back</title>
</head>
<body>
<div id="page-index" data-role="page">
<div role="main">
<div class="ui-content"></div>
</div>
</div>
</body>
</html>
而我的 index.js 是,
var app = {
// 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);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
document.addEventListener("backbutton", function (e) {
e.preventDefault();
}, false );
app.OrganizationInformation();
},
// Update DOM on a Received Event
receivedEvent: function(id) {
/*var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);*/
}
};
app.initialize();
我使用的插件是,
com.phonegap.plugins.facebookconnect 0.4.0 "Facebook Connect"
cordova-plugin-splashscreen 2.1.0 "Splashscreen"
cordova-plugin-whitelist 1.0.0 "Whitelist"
phonegap-plugin-push 1.4.4 "PushPlugin"
任何人都可以帮助我理解为什么这个侦听器没有被调用。我关注了许多博客和答案,但没有成功。感谢您提前提供帮助。
@约瑟夫,
你有三个问题。一个效果较小,但总有一天会赶上来。另一个问题,无法捕获 [backbutton]
,更容易看到。
在 #1 上,e.preventDefault();
不执行任何操作。该事件与浏览器无关,并且不受通常的“事件冒泡”的影响。参见 Event Order – and older post on subject
在#2,你需要等到 deviceready
事件触发后再做任何事情。这包括调用其他库。
如 deviceready
event 的文档中所述:
Cordova consists of two code bases: native and JavaScript. While the native code loads, a custom loading image displays. However, JavaScript only loads once the DOM loads. This means the web app may potentially call a Cordova JavaScript function before the corresponding native code becomes available.
The deviceready
event fires once Cordova has fully loaded. Once the event fires, you can safely make calls to Cordova APIs. Applications typically attach an event listener with document.addEventListener
once the HTML document's DOM has loaded.
The deviceready
event behaves somewhat differently from others. Any event handler registered after the deviceready
event fires has its callback function called immediately.
强烈建议您重新组织代码。
关于#3,您的代码中存在一个常见错误。当调用事件时,代码中的 this
超出范围。这意味着以下代码不起作用:
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
有几种方法可以解决这个问题。
- 使
onDeviceReady()
函数成为全局函数,因为这是您的代码所调用的。
- 直接调用库,就好像它是库的外部调用一样。
像这样:
bindEvents: function() {
document.addEventListener('deviceready', app.onDeviceReady, false);
},
需要明确的是,当 this.onDeviceReady()
最终生成时,它是“超出范围”并且是全局的。
更详细的解释,阅读下面的SOpost:
祝你好运
我正在使用 Cordova 包装的 JQuery Mobile 开发混合移动应用程序。
我的Jquery版本是2.1.4,Jquery手机版是1.4.5。同样,我的 Cordova CLI 版本是 5.3.3。
我需要重写 Android 后退按钮行为,这会杀死 activity。所以我使用了 Cordova 的 backbutton
监听器。我在 deviceready
上召集此活动。但是,在点击 Android 返回时,我没有调用事件并且应用程序正在被杀死。
我的index.html是,
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" href="css/jquery.mobile.theme.min.css"/>
<link rel="stylesheet" href="css/jquery.mobile.icons.min.css"/>
<link rel="stylesheet" type="text/css" href="libs/JQuery/jquery.mobile.icons-1.4.5.min.css"/>
<link rel="stylesheet" type="text/css" href="libs/JQuery/jquery.mobile.structure-1.4.5.min.css"/>
<!-- PAGE/APPLICATION STYLE SHEETS -->
<link rel="stylesheet" type="text/css" href="css/index.css">
<script src="libs/JQuery/jquery-2.1.4.min.js"></script>
<script src="libs/JQuery/jquery.mobile-1.4.5.min.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<title>Override Back</title>
</head>
<body>
<div id="page-index" data-role="page">
<div role="main">
<div class="ui-content"></div>
</div>
</div>
</body>
</html>
而我的 index.js 是,
var app = {
// 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);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
document.addEventListener("backbutton", function (e) {
e.preventDefault();
}, false );
app.OrganizationInformation();
},
// Update DOM on a Received Event
receivedEvent: function(id) {
/*var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);*/
}
};
app.initialize();
我使用的插件是,
com.phonegap.plugins.facebookconnect 0.4.0 "Facebook Connect"
cordova-plugin-splashscreen 2.1.0 "Splashscreen"
cordova-plugin-whitelist 1.0.0 "Whitelist"
phonegap-plugin-push 1.4.4 "PushPlugin"
任何人都可以帮助我理解为什么这个侦听器没有被调用。我关注了许多博客和答案,但没有成功。感谢您提前提供帮助。
@约瑟夫,
你有三个问题。一个效果较小,但总有一天会赶上来。另一个问题,无法捕获 [backbutton]
,更容易看到。
在 #1 上,e.preventDefault();
不执行任何操作。该事件与浏览器无关,并且不受通常的“事件冒泡”的影响。参见 Event Order – and older post on subject
在#2,你需要等到 deviceready
事件触发后再做任何事情。这包括调用其他库。
如 deviceready
event 的文档中所述:
Cordova consists of two code bases: native and JavaScript. While the native code loads, a custom loading image displays. However, JavaScript only loads once the DOM loads. This means the web app may potentially call a Cordova JavaScript function before the corresponding native code becomes available.
The
deviceready
event fires once Cordova has fully loaded. Once the event fires, you can safely make calls to Cordova APIs. Applications typically attach an event listener withdocument.addEventListener
once the HTML document's DOM has loaded.The
deviceready
event behaves somewhat differently from others. Any event handler registered after thedeviceready
event fires has its callback function called immediately.
强烈建议您重新组织代码。
关于#3,您的代码中存在一个常见错误。当调用事件时,代码中的 this
超出范围。这意味着以下代码不起作用:
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
有几种方法可以解决这个问题。
- 使
onDeviceReady()
函数成为全局函数,因为这是您的代码所调用的。 - 直接调用库,就好像它是库的外部调用一样。
像这样:
bindEvents: function() {
document.addEventListener('deviceready', app.onDeviceReady, false);
},
需要明确的是,当 this.onDeviceReady()
最终生成时,它是“超出范围”并且是全局的。
更详细的解释,阅读下面的SOpost:
祝你好运