jQuery点击事件没有在jQueryMobile中触发

Mar*_*arc 8 jquery jquery-mobile jquery-mobile-button

使用jQuery jquery-1.9.1.js和jQueryMobile 1.3.1(Chrome 26/Windows 7)我无法理解为什么这些"click"事件中的一个绑定到#one1会触发而另一个不会:

HTML:

<div data-role="page" id="one" data-theme="a">
    <div data-role="header" data-position="inline">
        <h1>One</h1>
    </div>
    <div data-role="content" data-theme="a">
        <a href="#" id="one1">[one]</a>
        <a href="#two">two</a>
        <a href="#three">three</a>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

<script>
$(document).on( "mobileinit", function() {
    $(document).on('click', '#one1', function(e){
        console.log('firing');
    });
    $('#one1').on("click", function() {
        console.log('not firing');
    });
}); 
</script>
Run Code Online (Sandbox Code Playgroud)

当我在JSFiddle中运行它时,当没有包含在"mobileinit"事件中时,两个事件都会触发:http: //jsfiddle.net/9NRwa/

我在这里错过了什么?

Gaj*_*res 23

介绍

首先,mobileinit事件不应该用于事件绑定.虽然它可以像那样使用mobileinit不是为此目的而创建的.它是为jQuery Mobile参数自动初始化创建的,因此不应该用于事件绑定.

正确的方法是使用正确的页面事件,如pageinit.有关页面事件的更多信息,请查看我的其他答案,其中涵盖了各种jQuery Mobile页面事件及其与常用jQuery文档就绪范例的区别:jQuery Mobile:文档就绪与页面事件.

不要让我回答这个问题.像click这样的事件可以用几种不同的方式绑定.让我们看看你用过的例子:

使用jQuery进行事件绑定的各种方法

第一个例子

$(document).on('click', '#one1', function(e){
    console.log('firing');
});
Run Code Online (Sandbox Code Playgroud)

第一个例子是新的东西,来与现在已经过时方法首先使用现场.基本上它是一种事件委托机制,它允许您将事件处理程序绑定到给定节点类型的所有现有实例,而且还绑定到给定节点类型的任何未来实例("类型"我指的是一组DOM节点匹配的给定的jQuery选择器).我想在这里说的是,在事件绑定期间,元素不需要存在于DOM中,基本上这个方法的工作原理是将事件处理程序绑定到文档本身,然后对通过DOM冒泡的所有事件做出反应.因此,在事件绑定期间,元素#one1是否存在无关紧要.您可以稍后动态创建它,它仍然可以工作.

第二个例子

$('#one1').on("click", function() {
    console.log('not firing');
});
Run Code Online (Sandbox Code Playgroud)

这是旧的事件绑定方式.它要求在事件可以绑定之前在DOM中存在事件.在您的情况下,您尝试将此单击事件绑定到该时间点在DOM中不存在的元素.在绑定过程之后加载它并不重要.

工作实例

jsFiddle示例:http://jsfiddle.net/Gajotres/QmNsa/

看看这个例子.你会在jQuery Mobile中看到5种不同的点击事件绑定方式:

  • 在将页面初始化为DOM之前,在HEAD中绑定2个单击事件
  • 在pagebeforeshow事件中,HEAD中绑定了2个单击事件,基本上这也是绑定委托,因为当要显示页面并且已经在DOM中时事件被绑定
  • 在所有页面内容之后,1个点击事件被绑定在BODY中.因为此时所有内容都加载到DOM中,所以此单击事件将起作用.

HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>jQM Complex Demo</title>
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
        <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>    
        <script>
                $(document).on('click', '#one1', function(e){
                    // This example will work because it was bind with event delegation process
                    console.log('Firing 1');
                });
                $('#one1').on("click", function() {
                    // This example will not work because event do not exist in this moment
                    console.log('Not firing');
                });
                $(document).on( "pagebeforeshow", function() {
                    // This example will work because it was bind with event delegation process            
                    $(document).on('click', '#one1', function(e){
                        console.log('Firing 2');
                    });
                    // This example will work because element exist in a DOM during the pagebeforeshow event
                    $('#one1').on("click", function() {
                        console.log('Firing 3');
                    });
                });             
        </script>
    </head>
    <body>
        <div data-role="page" id="index">
            <div data-theme="b" data-role="header">
                <h1>Index page</h1>
            </div>

            <div data-role="content">
                <a href="#" id="one1" data-role="button">[one]</a>
            </div>
        </div>    
        <script>
            $('#one1').on("click", function() {
                // This example will  work because we are binding it when element is already loaded into the DOM
                console.log('Firing 4');
            });            
        </script>
    </body>
</html>   
Run Code Online (Sandbox Code Playgroud)

结论

  • 不要将mobileinit事件用于事件绑定,它将在页面加载到DOM之前触发,并且只有与委托绑定的事件才有效.
  • 将您的事件绑定到正确的jQuery Mobile页面事件中.

有关此主题的有用链接:

  1. jQuery Live()方法和事件冒泡

    虽然法已经过时方法,而应使用.在某些基准测试方法上,速度提高了2倍.

  2. jQuery Mobile:文档就绪与页面事件

  3. 各种jQuery Mobile页面事件
  4. "事件冒泡"是什么意思?