我已经编辑了我的原始代码示例,以包含我应该做的“正确方法”
我正在开发一个jquery移动项目,我注意到如果我使用ON绑定一个单击它将在页面第一次加载时工作,但如果我返回页面,那么每次返回时我都会得到另一个绑定。如果我使用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>
答案 0 :(得分:1)
你对.bind和.on的使用是非常不同的。您使用.on的方式是使用事件委派,并且事件委派可以被停止传播的事件中断。
$('#loginformSubmit').bind('click', login_form_click_handler);
相当于
$('#loginformSubmit').on('click', login_form_click_handler);
尽管如此,真正的问题是你因为你正在调用这个函数而失去this
。假设没有停止传播,以下内容可能也会起作用。
$(document).on('click', '#loginformSubmit', login_form_click_handler);
然而,它可能会导致双重绑定,因为它绑定到文档,因此除非你解除绑定,否则永远不会消失。
答案 1 :(得分:1)
在jQuery mobile中,document
通常在页面转换时保持不变。我指出这一点的原因是,无论何时向元素添加事件监听器(在本例中为文档),它都添加到已添加的任何其他事件监听器的集合。这与您使用.bind
还是.on
无关。因此,每次调用.on('click', '#loginformSubmit', ...
时,您都会向该文档单击事件添加更多侦听器。
如果您将事件绑定更改为如下所示:
$('#loginformSubmit').on('click', login_form_click_handler);
您将看到与以相同方式使用.bind
相同的结果。
当您使用.on
事件绑定语法时,它会将事件侦听器添加到$(document)
,但只会在它冒泡到范围选择器#loginformSubmit
时触发您的函数