我正在以多页面形式使用jQuery mobile。当用户单击标有下一页的按钮时,我想运行一个AJAX请求。根据AJAX请求的结果,我希望阻止用户访问下一页。
我认为我遇到的问题是我的AJAX请求比下一页事件需要更长的时间来回复。因此,它允许用户在不让AJAX请求完成的情况下进入下一页。
至少我认为这是正在发生的事情。有没有人遇到过此问题或知道解决这个问题的方法?
<div id="page1" data-role="page">
<div data-role="header" data-position="fixed" data-theme="d">
<a href="#page2" data-role="button" id="btnPage2" class="ui-btn-right" data-icon="arrow-r">Next Page</a>
</div>
<div role="main" class="ui-content">
<label for="testVal">Test Val:</label>
<input type="text" id="testVal" name="testVal"/>
</div>
</div>
<div id="page2" data-role="page">
<div role="main" class="ui-content">
</div>
</div>
$('#btnPage2').click(function(){
var isValid = '';
var aValue = $('#testVal').val();
$.ajax({
type: "POST",
url: "php-file.php",
data: {"something":aValue },
success: function(data){
var json = $.parseJSON(data);
if(json.hasOwnProperty('error')){
console.log("the user is not allowed on page 2");
isValid = false;
}else{
isValid = true;
}
}
});
if(!isValid){
alert('sorry you can not enter page 2');
return false;
}
});
在上面的代码示例中,当我单击Next Page按钮(即#btnPage2
)时,它允许我访问第2页,即使我检查控制台日志并且我看到“不允许用户在第2页“。
我尝试将代码调整为以下内容。它有点工作,但是,只有当用户不被允许访问page2时。 e.preventDefault
让ajax完成但是,我无法找到一种方法来强制更改page2。如果允许用户访问第2页的行
$(":mobile-pagecontainer").pagecontainer("change", "#page2");
似乎导致了这个问题......它只是创建了一个无限循环来调用pageChange事件。我认为这是强制页面更改为page2的方法,但我认为我错了,我无法弄清楚如何强制它更改为page2
$(document).bind('pagebeforechange', function(e, data) {
var to = data.toPage,
from = data.options.fromPage;
if (typeof to === 'string') {
var u = $.mobile.path.parseUrl(to);
to = u.hash || '#' + u.pathname.substring(1);
if (from) from = '#' + from.attr('id');
if (from === '#page1' && to === '#page2') {
e.preventDefault();
var aValue = $('#testVal').val();
$.ajax({
type: "POST",
url: "php-file.php",
data: {"something":aValue },
cache: false,
success: function(data){
var json = $.parseJSON(data);
if(json.hasOwnProperty('canNotPass')){
alert('Sorry you can not view page 2');
}else{
/// if json does not contain canNotPass then continue to page2
$(":mobile-pagecontainer").pagecontainer("change", "#page2");
}
},
beforeSend: function() {
$.mobile.loading("show");
},
complete: function() {
$.mobile.loading("hide");
}
});
}
}
});
我尝试实现@deblocker修复,但我仍然遇到同样的问题。当我在ajax将canNotPass
设置为true
的情况下运行以下代码时,代码似乎永远不会达到测试canNotPass
的值的程度。因此,它永远不会设置e.preventDefault
,并且允许用户访问page2。
我认为该解决方案与设置延迟对象有关,这将允许ajax在页面更改发生之前完成的时间。唯一的问题是我知道如何设置/使用延迟对象。
答案 0 :(得分:2)
使用按钮代替锚:
<button id="btnPage2" class="ui-btn-right ui-icon-arrow-r">Next Page</a>
...并按success
处理程序中的代码导航:
$(":mobile-pagecontainer").pagecontainer("change", "#page2")
;
$.ajax({
type:...
url:...
data:...
success: ...
beforeSend: function() {
$.mobile.loading("show");
},
complete: function() {
$.mobile.loading("hide");
},
error: function (request,error) {
alert('sorry you can not enter page 2');
});
<强>更新强>
根据Omar的建议,在pagecontainerbeforechange
处理程序的第一部分内部,你应该打破导航,因为你已经在第2页的一半。因此,您不再需要告诉pagecontainer
切换到pagecontainerbeforechange
事件中的page2。您只需将您的ajax请求和canNotPass
标记保留在$('#btnPage2').click()
内。
样本:
$(document).on("pagecontainerbeforechange", function(e, ui) {
var from = "#" + $(":mobile-pagecontainer").pagecontainer("getActivePage").prop("id");
var to = ui.toPage;
if (typeof ui.toPage == "string") {
var u = $.mobile.path.parseUrl(to);
to = u.hash || "#" + u.pathname.substring(1);
if (from === "#page-one" && to === "#page-two") {
var canNotPass = !$("#canPass").prop("checked");
if(canNotPass) {
e.preventDefault();
$.mobile.activePage.find('.ui-btn-active').removeClass('ui-btn-active').blur();
}
}
}
});
&#13;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>
</head>
<body>
<div data-role="page" id="page-one">
<div data-theme="a" data-role="header" data-position="fixed">
<h1>First Page</h1>
<a href="#page-two" class="ui-btn-left">Next</a>
</div>
<div data-role="content">
<label for="canPass">Can Navigate to Page 2 ?</label>
<input data-role="flipswitch" name="canPass" id="canPass" data-on-text="Yes" data-off-text="No" type="checkbox">
</div>
<div data-theme="a" data-role="footer" data-position="fixed">
<h1>Footer</h1>
</div>
</div>
<div data-role="page" id="page-two">
<div data-theme="a" data-role="header" data-position="fixed">
<h1>Second Page</h1>
<a href="#page-one" class="ui-btn-left">Back</a>
</div>
<div data-role="content">
</div>
<div data-theme="a" data-role="footer" data-position="fixed">
<h1>Footer</h1>
</div>
</div>
</body>
</html>
&#13;
EDIT2:(致谢:Omar) - 以下是如何将直接导航捕获到&#34;受保护的&#34;页
$(document).on("pagecontainerbeforechange", function(e, ui) {
/* in case user enter foo.com/#page2 directly */
if (typeof ui.toPage === "object" && ui.absUrl === undefined && ui.toPage[0].id == "page2") {
/* make ajax call */
var ajaxCall = true;
if (ajaxCall) {
$.noop
} else {
ui.toPage = "#noAccessPage"
}
}
/* internal navigation from page1 to page2 */
if (typeof ui.toPage === "string" && ui.absUrl !== undefined && $.mobile.path.parseUrl(ui.absUrl).hash == "#page2") {
/* make ajax call */
var ajaxCall = true;
if (ajaxCall) {
$.noop
} else {
ui.toPage = "#noAccessPage"
}
}
});