javascript - Jquery BIND 有效,但 ON 无效

标签 javascript jquery jquery-mobile

我已经编辑了原始代码示例,以包含我应该做到的“正确方法”

我正在开发一个 jquery 移动项目,我注意到,如果我使用 ON 绑定(bind)单击,它将在页面第一次加载时起作用,但如果我返回到该页面,那么每次返回时我都会得到另一个绑定(bind)。如果我使用 BIND,那么无论我离开页面并返回多少次,我都只会得到一个。

我可以使用 BIND,但我知道它将来会消失,所以我想知道为什么 ON 不起作用?

我正在使用 jquery 1.9.1 和 jquery mobile 1.3.1

此代码位于每个页面的头部:

 <link rel="stylesheet" href="resources/js/jquery.mobile-1.3.1.min.css" />
 <script src="resources/js/jquery-1.9.1.min.js"></script>
 <script type="text/javascript">
    console.log('head javascript - before JQM is loaded');


    // EDITED: Don't put JQM events inside .ready()
    //$(function() {


            // *** EDITED - THIS IS CORRECT WAY TO USE .on() IN THIS CASE ****
            $(document).on("pageinit", "#page_login", function() {
                console.log('#page_login page - pageinit event -- (only once for THIS page)');
                $('#loginformSubmit').on('click', login_form_click_handler);
            });


            // *** THIS ONE WORKS ****
            $(document).on("pageinit", "#page_login", function() {
                console.log('#page_login page - pageinit event -- (only once for THIS page)');
                $('#loginformSubmit').bind('click', login_form_click_handler);
            });



           // *** BUT, if I replace the section above with this
           //          then the login_form_click_handler() function
           //          will get executed N+1 times, where N = number
           //          of times I have viewed the page. 

           $(document).on("pageinit", "#page_login", function() {
                console.log('#page_login page - pageinit event -- (only once for THIS page)');               
                /* EDITED NOTE:  This doesn't work correctly because JQM maintains
                                 a single 'document'  so each time this event is 
                                 fired (initial browse and subsequent visits if 
                                 page is not in jqm cache) I was binding another
                                 click event to the document which already had one
                                 (or more) of the same.  */
                $(document).on('click', '#loginformSubmit', function(e){                 
                     login_form_click_handler(e);
                });
           });


    //});


    <script src="resources/js/jquery.mobile-1.3.1.min.js"></script>

这是 #page_login 页面的正文部分

<div data-role="page" id="page_login" data-theme="b" data-content-theme="b">


<div data-role="header">
    <h1>AV Login</h1>
    <a href="resources/dialogs/login_help.htm" data-icon="info" data-iconpos="right" data-theme="b" data-rel="dialog" class="ui-btn-right">Help</a>
</div>

<div data-role="content">

<form id='loginform' class="validate" action="resources/processors/login.php" method="post">

<div data-role="popup" id="invalid_login" data-transition="pop" class="ui-content" data-theme="e" data-overlay-theme="a" style="max-width:350px;">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
Invalid username or password
</div>

<div data-role="popup" id="login_processor_error" data-transition="pop" class="ui-content" data-theme="e" data-overlay-theme="a" style="max-width:350px;">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
<div id="login_processor_error_content"></div>
</div>

<ul data-role="listview" data-inset="true">


<li data-role="fieldcontain">
<label for="username">Username:</label>
<input type="text" name="username" id="username" data-mini="true"  class="required" />
</li>


<li data-role="fieldcontain">
<label for="password">Password:</label>
<input type="password" name="password" id="password" data-mini="true" class="required" />
</li>

</ul>

<a id="loginformSubmit" href="" data-role="button" data-mini="true">Login</a>
</form>


<script type="text/javascript">
function login_form_click_handler(e){
    console.log('login_form_click_handler');
    e.preventDefault(); 
            // EDIT NOTE:  'this' is the #loginformSubmit element
            //        can setup your own var to use, such as:  var $this = $('#loginform');

             // .. do form validation, submission, etc ..
}
</script>

</div>

</div>

最佳答案

在 jQuery mobile 中,文档 通常在页面转换时保持不变。我指出这一点的原因是,每当您向元素(本例中为文档)添加事件监听器时,它都会添加到已添加的任何其他事件监听器的集合中。这与您使用 .bind 还是 .on 无关。因此,每次调用 .on('click', '#loginformSubmit', ... 时,您都会向该文档点击事件添加更多监听器。

如果您将事件绑定(bind)更改为如下所示:

$('#loginformSubmit').on('click', login_form_click_handler);

您将看到与以相同方式使用 .bind 相同的结果。

当您按原样使用 .on 事件绑定(bind)语法时,它会将事件监听器添加到 $(document) 中,但只会在函数冒泡时触发您的函数直到范围选择器#loginformSubmit

jQuery .on documentation

关于javascript - Jquery BIND 有效,但 ON 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18318293/

相关文章:

javascript - 正则表达式替换简单的缩写

javascript - 为什么我的 React 组件没有在 setState() 上重新渲染?

javascript - 使用多个可选择的选项卡

javascript - 在模式中滚动 twiiter-bootstrap

jquery - 逻辑查询-jquery mobile-多页面模板

javascript - 手机浏览器网页解决方案

javascript - Eclipse 在复制/粘贴 JavaScript 文件时挂起

javascript - 通过换行从文本区域值创建列表

javascript - 如何根据所选 ListView 项目使按钮表现不同?

css - 如何控制 Jquery 移动控件组的大小?