Javascript 如何修改 jQuery 移动历史后退按钮行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10262629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to modify jQuery mobile history Back Button behavior
提问by bmartinek
I'll start this off with I have researched a bit, but no solution that solves what seems like it should be a simple JQM modification.
我将从我研究过的开始,但没有解决方案可以解决似乎应该是简单的 JQM 修改的问题。
I have a wine review webapp that has the following view user flow: http://5buckchuck.com/
我有一个 Wine Review webapp,它具有以下视图用户流程:http: //5buckchuck.com/
Wine type > Wine list > Wine Details > Wine review (redirect via django backto ) > Wine Details updated from review
Wine type > Wine list > Wine Details > Wine review (redirect via django backto ) > Wine Details 通过review更新
What I want to happen is when the user presses the back button it should go back to the wine list. What currently happens is the the Wine Detail view is reloaded. It takes pressing back three times to get back to the Wine List. :-(
我想要发生的是当用户按下后退按钮时,它应该返回到酒单。当前发生的是重新加载 Wine Detail 视图。返回酒单需要按三下。:-(
My thoughts to solve this were two:
我解决这个问题的想法有两个:
Splice the last 3 items from the history stack, if the last items in the history stack was Wine Review. I had a hard time trying to introspect the last history object to get the pageURL. I have a feeling that this solution is a bit too fragile though.
var last_hist = $.mobile.urlHistory.getActive(); last_hist.data.pageURL;
The second thought was to override the back button behavior so that the back button from the Wine Detail view would always go back to the Wine list view
$('div#wine_detail').live('pageshow',function(event, ui){ $("a.ui-btn-left").bind("click", function(){ location.replace("/wines/{{wine.wine_type}}/#"); }); });
如果历史堆栈中的最后一个项目是 Wine Review,则拼接历史堆栈中的最后 3 个项目。我很难反省最后一个历史对象以获取 pageURL。我觉得这个解决方案有点太脆弱了。
var last_hist = $.mobile.urlHistory.getActive(); last_hist.data.pageURL;
第二个想法是覆盖后退按钮行为,以便 Wine Detail 视图中的后退按钮始终返回到 Wine 列表视图
$('div#wine_detail').live('pageshow',function(event, ui){ $("a.ui-btn-left").bind("click", function(){ location.replace("/wines/{{wine.wine_type}}/#"); }); });
There is probably a better way to do this, but I'm a bit out of ideas.
可能有更好的方法来做到这一点,但我有点想法。
Update:
So I continue to hack on this with somewhat negligible results. On thing I have found was this is what I basically need to work: window.history.go(-3)
更新:所以我继续破解这个问题,结果几乎可以忽略不计。我发现这是我基本上需要做的事情:window.history.go(-3)
from the console it does exactly what I need.
从控制台它完全符合我的需要。
So I tried binding it the the back button like such:
所以我尝试将它绑定到后退按钮,如下所示:
$('div#wine_detail').live('pageshow',function(event, ui){
var last = $.mobile.urlHistory.stack.length - 1;
var last_url = $.mobile.urlHistory.stack[last].url;
var review_url = /review/g;
if (last_url.match(review_url) )
{
$('div#wine_detail a.ui-btn-left').bind( 'click', function( ) {
console.log("click should be bound and going back in time...")
window.history.go(-2);
});
}
else
{
console.log('err nope its: ' + last_url);
}
});
No dice, something interupts the transaction...
没有骰子,有什么东西打断了交易......
采纳答案by bmartinek
Okay so the solution was close to the update I posted. The issue with the previous solution was that there were to many things bind-ed to the "Back" button. While my new bind action may have been working sometimes, the other actions would take place too, I tried unbind()
but still no worky.
好的,所以解决方案接近我发布的更新。以前的解决方案的问题是有很多东西绑定到“返回”按钮。虽然我的新绑定操作有时可能会起作用,但其他操作也会发生,我尝试过unbind()
但仍然没有工作。
My solution is a bit of smoke and mirrors. I check to see if the the previous page was the review page and then if so, I swap out the old back button for my new faux button with the history back step like so:
我的解决方案是有点烟雾和镜子。我检查上一页是否是评论页面,然后如果是,我将旧的后退按钮换成新的人造按钮,历史记录后退步骤如下:
$('div#wine_detail').live('pageshow',function(event, ui){
var last = $.mobile.urlHistory.stack.length - 1;
var last_url = $.mobile.urlHistory.stack[last].url;
var review_url = /review/g;
if (last_url.match(review_url) )
{
$('a.ui-btn-left').replaceWith('<a href="" id="time_machine" class="ui-btn-left ui-btn ui-btn-icon-left ui-btn-corner-all ui-shadow ui-btn-up-a" data-icon="arrow-l"><span class="ui-btn-inner ui-btn-corner-all"><span class="ui-btn-text">Back</span><span class="ui-icon ui-icon-arrow-l ui-icon-shadow"></span></span></a>');
$('#time_machine').bind( 'click', function( ) {
console.log("click should be bound and going back in time...")
window.history.go(-3);
});
}
else
{
console.log('err nope its: ' + last_url);
}
It looks exactly the same, and no one is the wiser. it could probably be improved by using the the jQm method pagebeforeshow
so user could never see the swap. Hope this helps someone.
它看起来完全一样,没有人更聪明。它可能可以通过使用 jQm 方法进行改进,pagebeforeshow
因此用户永远看不到交换。希望这可以帮助某人。
回答by frequent
I'd prefer not to splice/pop/push with the urlHistory. How about redirect on pagebeforechange like so:
我不想与 urlHistory 拼接/弹出/推送。如何像这样在 pagebeforechange 上重定向:
$(document).on("pagebeforechange", function (e, data) {
var overrideToPage;
// some for-loop to go through the urlHistory TOP>DOWN
for (var i = $.mobile.urlHistory.activeIndex - 1; i >= 0; i--) {
// this checks if # = your target id. You probably need to adapt this;
if ($.mobile.urlHistory.stack[i].url = $('#yourPageId').attr('id')) {
// save and break
overrideToPage = $.mobile.urlHistory.stack[i].url;
break;
}
// set new Page
data.toPage = overrideToPage;
}
});
This captures your back button changePage call and redirects to the page you want. You could also just set data.toPage = winelistdirectly of course.
这会捕获您的后退按钮 changePage 调用并重定向到您想要的页面。当然,您也可以直接设置data.toPage = winelist。
I'm only doing this with #internal pages, but it shoudn't be so hard to set this up with winelist.html etc.
我只是用#internal 页面来做这个,但是用 winelist.html 等设置它应该不难。
For more info, check the event page in the JQM docs
有关更多信息,请查看 JQM文档中的事件页面
回答by jtsnr
Why not have a back button in the header section of your page? Something like this:
为什么不在页面的标题部分有一个后退按钮?像这样的东西:
<div data-role="header">
<a data-direction="reverse" data-role="button" href="#winelist" data-icon="back">Back</a>
<h1>Wine Detail</h1>
</div><!-- /header -->
回答by Cosmacelf
I wrestled with this recently as well. After thinking about it, I realized I could rewrite my JQM application to use Pop Up "windows" for those pages that I didn't want in my history. This ended up being an easier and cleaner fix than mucking around with browser history.
我最近也在与这个搏斗。仔细考虑之后,我意识到我可以重写我的 JQM 应用程序,以便在我的历史记录中不想要的那些页面上使用弹出“窗口”。这最终比处理浏览器历史记录更容易、更干净。
Now users can intuitively use the browser back button, and I don't have to code application back buttons.
现在用户可以直观地使用浏览器后退按钮,而我不必编写应用程序后退按钮。
The only thing you have to ensure is that the popups don't themselves make it into the browser history, so make sure to set the "history" option to false like so:
您唯一需要确保的是弹出窗口本身不会进入浏览器历史记录,因此请确保将“历史记录”选项设置为 false,如下所示:
$('#some_popup').popup( { history: false } );
回答by stot
If you have the situation that you want the close button refer to an arbitrary (not the last) page, you could also change first to the target page and open the dialog afterwards. Therefore the close button at the dialog will open the target page.
如果您希望关闭按钮引用任意(不是最后一个)页面,您也可以先更改为目标页面,然后再打开对话框。因此对话框中的关闭按钮将打开目标页面。
// First: change to the target page
$.mobile.changePage('#target_page');
Afterwards open the dialog like this.
然后像这样打开对话框。
// Second: change to the dialog
window.setTimeout(
// for some reason you have to wrap it in a timeout
function(){
$.mobile.changePage('#dialog');
},
1
);
Now you can open the dialog and the close button will open #target_page.
现在您可以打开对话框,关闭按钮将打开#target_page。
Advantages:
好处:
- solution works for single dialogs rather than removing all close buttons from all dialogs
- seamless integration on a single point of code
- history manipulation is not needed
- 解决方案适用于单个对话框,而不是从所有对话框中删除所有关闭按钮
- 在单点代码上无缝集成
- 不需要历史操作
回答by webdevmatt
I have seen similar issues before when using jquery mobile and it is addressed in the documentation. When setting up your Javascript "at the beginning of your page" use pageinit instead of ready or maybe in your case pageshow. I think this will address your issue without having to workaround the history queue.
我之前在使用 jquery mobile 时遇到过类似的问题,并且在文档中得到了解决。在“页面开头”设置 Javascript 时,请使用 pageinit 而不是 ready 或者在您的情况下使用 pageshow。我认为这将解决您的问题,而无需解决历史队列。