JQueryMobile听取点击

时间:2012-12-06 23:57:46

标签: jquery-mobile jquery

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

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

<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是一个链接:

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

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

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. 点击链接
  6. 使用以下控制台输出:

    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" 
    

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

    1. 导航至disclaimer.html(http)
    2. 转到home.html(ajax)
    3. 点击链接
    4. 转到disclaimer.html(ajax)
    5. 转到home.html(ajax)
    6. 点击链接
    7. 控制台输出:

      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个结果会被复制。

      对不起这个问题很抱歉。我希望有人可以向我解释究竟发生了什么,以及这是否是预期的行为?

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

1 个答案:

答案 0 :(得分:1)

简而言之:在jQueryMobile中,您应该在pageinit内监听(绑定)您的事件;这与jQuery的ready事件相当(更多)。这是jQueryMobile家伙推荐的内容。

页面加载并初始化后(通过AJAX或HTTP)会触发

pageinit,但如果页面已经在DOM中,pagebeforeshow可能会被触发多次,例如关闭后一个jQueryMobile对话框。无论你在pagebeforeshow上绑定什么,每次再次显示页面时都会再次重新绑定。这就是为什么你有两个点击pagebeforeshow

编辑:测试说明

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

在您的第一次测试中,您有:

  1. 导航到home.html(http):它绑定(通过委托文档)并触发pageinitpagebeforeshow(日志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,所以最后一个(重复)因为第4步。
  6. 在你的第二次测试中,你有:

    1. 导航至disclaimer.html(http):它绑定pageinitpagebeforeshow,但不显示日志,因为没有触发任何事件;两个事件都绑定到document(通过委托),因此如果特定页面尚未在DOM中,则无关紧要。这是此测试中唯一一次加载和执行“events.js”的时间。
    2. 转到home.html(ajax):它会触发pageinitpagebeforeshow,您可以看到日志0和1.当两个事件都被触发时,相应的点击事件正在绑定到链接(直接绑定!)
    3. 点击链接:此步骤按预期显示日志2和3。
    4. 转到disclaimer.html(ajax):日志中没有显示任何内容...但是:jQueryMobile决定应该从DOM中删除“home.html”!这是因为一旦您导航到另一个页面,JQM就会删除每个页面。请注意,“disclaimer.html”不会从DOM中删除,因为他是它的“拥有者”。
    5. 转到home.html(ajax):此步骤会触发pageinitpagebeforeshow(因为两个事件仍然绑定到文档对象),如您所见log 4和5.这将两个函数绑定到链接,就像在步骤2中一样,但是......(参见下一步)
    6. 点击链接:您在这里说“我希望第6和第7个结果被重复”;好吧,他们没有重复,因为整个页面(包含链接的div)及其从DOM中删除的所有内容,以及您将直接直接绑定到链接的第一次点击事件(在步骤2中)消失了!所以你只看到步骤5中绑定引起的日志。
    7. 如果我(最终)理解JQM事件是如何工作的,则加载的第一个页面(通过完整的HTTP请求)保存在DOM中,直到用户导航到外部页面或重新加载页面(通过F5或CTRL + R)。任何其他页面(通过AJAX加载)都会添加到“主”DOM中,然后在导航到另一个页面时从其中卸载/删除。所以:如果你在pageinit中进行所有绑定(直接绑定或最多委托给它的父div [data-role:page]),你就不必担心重复的事件绑定。

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