JQueryMobile听取点击 [英] JQueryMobile listen click

查看:59
本文介绍了JQueryMobile听取点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解jQueryMobile导航中的页面事件,但我发现了一些非常奇怪的行为,因为一些事件处理程序被多次调用:

I am trying to understand the page events in jQueryMobile navigation, but I found some very weird behaviour, as some event handlers get called several times:

我有两个页面:home.html和disclaimer.html。两者都包含相同的标题:

I have two pages: home.html and disclaimer.html. Both contain the same header:

<head>
    <script src="js/jquery-1.8.2.min.js"></script>
    <script src="js/events.js"></script>
    <script src="js/jquery.mobile-1.2.0.min.js"></script>
</head>

在页面上home.html是一个链接:

On the page home.html is a link:

<section data-role="page" id="home">
    <a href="#" id="test">Test</a>
</section>

在文件events.js中是以下代码:

And in the file events.js is the following code:

var i = 0;

$(document).on('pageinit', 'section#home', function(event) {
    console.log(i++, 'pageinit');
    $('a#test').on('click', function() {
        console.log(i++, 'click pageinit');
    });
});

$(document).on('pagebeforeshow', 'section#home', function(event) {
    console.log(i++, 'pagebeforeshow');
    $('a#test').on('click', function() {
        console.log(i++, 'click pagebeforeshow');
    });
});

然后我执行以下步骤:


  1. 导航到home.html(http)

  2. 点击链接

  3. 转到disclaimer.html(ajax)

  4. 转到home.html(ajax)

  5. 点击链接

  1. Navigate to home.html (http)
  2. Click the link
  3. Go to disclaimer.html (ajax)
  4. Go to home.html (ajax)
  5. Click the link

使用以下控制台输出:

0 "pageinit"             // step 1
1 "pagebeforeshow"
2 "click pageinit"       // step 2
3 "click pagebeforeshow"
4 "pagebeforeshow"       // step 4
5 "click pageinit"       // step 5
6 "click pagebeforeshow"
7 "click pagebeforeshow" 

有道理,对吧? 但现在是奇怪的部分。当我更改访问页面的顺序时:行为更改。

Makes sense, right? But now the weird part. When I change the order in which I visit the pages: the behaviour changes.


  1. 导航至disclaimer.html(http)

  2. 转到home.html(ajax)

  3. 点击链接

  4. 转到disclaimer.html(ajax)

  5. 转到home.html(ajax)

  6. 点击链接

  1. Navigate to disclaimer.html (http)
  2. Go to home.html (ajax)
  3. Click the link
  4. Go to disclaimer.html (ajax)
  5. Go to home.html (ajax)
  6. Click the link

控制台输出:

0 "pageinit"             // step 2
1 "pagebeforeshow"
2 "click pageinit"       // step 3
3 "click pagebeforeshow"
4 "pageinit"             // step 5
5 "pagebeforeshow"
6 "click pageinit"       // step 6
7 "click pagebeforeshow" 

这很奇怪,因为我期待第6次第7个结果是重复的。

Which is weird, because I would expect the 6th and 7th result to have been duplicated.

很抱歉很长的问题。我希望有人可以向我解释到底发生了什么,以及这是否是预期的行为?

Sorry for the very long question. I hope someone can explain to me exactly what is happening and if this is expected behaviour?

tldr; 你在哪里听(点击) jQueryMobile中的事件?

tldr; Where do you listen for (click) events in jQueryMobile?

推荐答案

简而言之:在jQueryMobile中你应该在 pageinit中监听(绑定)你的事件;这与jQuery的 ready 事件相当(更多)。这就是 jQueryMobile 的推荐人。

In short: in jQueryMobile you should listen (bind) your events inside pageinit; this is equivalent (more of less) to jQuery's ready event. And it is what the jQueryMobile's guys recommend.

pageinit 在页面加载并初始化(通过AJAX或HTTP)后触发,但<$ c如果页面已经在DOM中,可以多次触发$ c> pagebeforeshow ,例如在关闭jQueryMobile对话框之后。无论你在 pagebeforeshow 上绑定什么,每次再次显示页面时都会再次重新绑定。这就是为什么你有两个点击pagebeforeshow

pageinit is triggered once the page has been loaded and initialized (via AJAX or HTTP), but pagebeforeshow may be triggered more than once if the page is already in the DOM, for example after closing a jQueryMobile dialog. Whatever you bind on pagebeforeshow is going to be rebind again every time the page is showed again. That is why you have two click pagebeforeshow.

我复制了你的2个html页面和js文件,并重复了两个测试中的所有步骤。

I replicated your 2 html pages and js file and repeated all the steps in both tests.

在你的第一次测试中你有:

In your first test you have:


  1. 导航到家.html(http):它绑定(通过委托文档)并触发 pageinit pagebeforeshow (记录0和1)因为您的页面已初始化并将显示。这也将两个函数绑定到链接(重要的是:在这种情况下不是委托,而是直接绑定!)。这是此测试中唯一一次加载和执行events.js的时间。

  2. 点击链接:这将执行两个点击pageinit 按预期点击pagebeforeshow (日志2和3),因为步骤1。

  3. 转到disclaimer.html(ajax ):这不会显示任何日志。

  4. 转到home.html(ajax):由于home.html仍在DOM中,因此触发 pagebeforeshow ,正如您在log(4)中看到的那样。这也会在链接中执行绑定。注意:我怀疑在此步骤中disclaimer.html已从DOM中删除(在第二次测试中更多内容)。

  5. 点击链接:显示树日志,前2个因为步骤1,所以最后2个(重复)因为第4步。

  1. Navigate to home.html (http): It binds (by delegating on document) and triggers pageinit and pagebeforeshow (logs 0 and 1) because your page was initialized and was going to be shown. this also binds the oter two functions to the link (important: in this case is not delegation, but a direct bind!). This is the only time in this test in which "events.js" is going to be loaded and executed.
  2. Click the link: this executes both click pageinit and click pagebeforeshow as expected (logs 2 and 3) because step 1.
  3. Go to disclaimer.html (ajax): this doesn't show any log.
  4. Go to home.html (ajax): since "home.html" is still in the DOM this triggers pagebeforeshow, as you can see in log (4). This executes too the binding in the link. NOTE: I suspect that at this step "disclaimer.html" was remove from DOM (more on this in second test).
  5. Click the link: shows tree logs, the first 2 because step 1, and the last (duplicated) because step 4.

在第二次测试中,您有:

In your second test you have:


  1. 导航至disclaimer.html(http):它绑定 pageinit pagebeforeshow ,但不显示日志因为没有一个事件被触发;这两个事件都绑定到文档(通过委托),因此如果特定页面尚未在DOM中,则无关紧要。这是此测试中唯一一次加载和执行events.js的时间。

  2. 转到home.html(ajax):它触发 pageinit pagebeforeshow ,您可以看到日志0和1.当两个事件都被触发时,相应的点击事件正在绑定到链接(直接绑定!)

  3. 单击链接:此步骤按预期显示日志2和3。

  4. 转到disclaimer.html(ajax):日志中没有显示任何内容...但是:jQueryMobile决定应该删除home.html DOM!这是因为一旦您导航到另一个页面,JQM就会删除每个页面。请注意,disclaimer.html不会从DOM中删除,因为他是它的拥有者。

  5. 转到home.html(ajax) :此步骤触发 pageinit pagebeforeshow (因为两个事件仍然绑定到文档对象)您可以在日志4和5中看到。这将两个功能绑定到链接,就像在步骤2中一样,但是......(请参阅下一步)

  6. 单击链接:您在这里说我希望第6和第7个结果重复;好吧,他们没有重复,因为整个页面(包含链接的div)及其从DOM中删除的所有内容,以及您将直接直接绑定到链接的第一次点击事件(在步骤2中)消失了!所以你只看到步骤5中绑定引起的日志。

  1. Navigate to disclaimer.html (http): It binds pageinit and pagebeforeshow, but doesn't show a log since none of the event is being triggered; both events are being bind to document (by delegation), so it doesn't matters if the specific page isn't yet in the DOM. This is the only time in this test in which "events.js" is going to be loaded and executed.
  2. Go to home.html (ajax): It triggers pageinit and pagebeforeshow and you can see logs 0 and 1. When both events are triggered, the corresponding click events are being bind to the link (a direct bind!)
  3. Click the link: This step shows logs 2 and 3, as expected.
  4. Go to disclaimer.html (ajax): Nothing is shown in the log... but: jQueryMobile decided that "home.html" should be removed from DOM! that is because JQM removes every page once you navigate to another one. Note that "disclaimer.html" is not going to be removed from the DOM ever, since he is the "owner" of it.
  5. Go to home.html (ajax): this step triggers pageinit and pagebeforeshow (since both events are still bind to the document object) as you can see in logs 4 and 5. This binds the two functions to the link, just as in step 2, but... (see next step)
  6. Click the link: Here is where you said "I would expect the 6th and 7th result to have been duplicated"; well they weren't duplicated because the whole page (the div containing the link) and all its content where removed from the DOM, and the first click events you bind directly to the link (in step 2) are gone! so you see only the logs caused by the bind in step 5.

如果我(最后)了解JQM事件的工作原理,那么第一个页面加载(通过完整的HTTP请求)保存在DOM中,直到用户导航到外部页面或重新加载页面(通过F5或CTRL + R)。任何其他页面(通过AJAX加载)都会添加到主DOM中,然后在导航到另一个页面时从其中卸载/删除。所以:如果你在 pageinit 中做了所有的约束(直接绑定或者最多委托给它的父div [data-role:page])你就不用担心了重复的事件绑定。

If I (finally) understood how JQM events work, the first page loaded (via full HTTP request) is kept in the DOM until the user navigate to an external page or reload the page (via F5 or CTRL+R). Any other page (loaded via AJAX) is added to the "main" DOM and then unloaded/deleted from it when you navigate to another one. So: if you do all your binds in pageinit (direct binds or at most delegating to its parent div[data-role:page]) you won't need to worry about duplicated event binds.

PD:如果你注意到我的写作方式有些奇怪,可能是因为我不习惯用被动语态用英语说/写,有时我混淆介词:P

PD: If you note something weird in how I write, is probably because I'm not used to speak/write in English in passive voice, and sometimes I mix up prepositions :P

这篇关于JQueryMobile听取点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆