使用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>
JavaScript的:
<script>
$(document).on( "mobileinit", function() {
$(document).on('click', '#one1', function(e){
console.log('firing');
});
$('#one1').on("click", function() {
console.log('not firing');
});
});
</script>
当我在JSFiddle中运行它时,两个事件在未包含在“mobileinit”事件中时触发: http://jsfiddle.net/9NRwa/
我在这里缺少什么?
答案 0 :(得分:23)
首先, mobileinit 事件不应用于事件绑定。虽然它可以像 mobileinit 那样用于此目的。它是为jQuery Mobile参数自动初始化创建的,因此不应该用于事件绑定。
正确的方法是使用正确的页面事件,例如 pageinit 。有关页面事件的更多信息,请查看我的其他答案,其中包含各种jQuery Mobile页面事件及其与常用jQuery文档就绪范例的区别: jQuery Mobile: document ready vs page events 。
不要让我回答这个问题。像click这样的事件可以用几种不同的方式绑定。 让我们看一下你用过的例子:
$(document).on('click', '#one1', function(e){
console.log('firing');
});
第一个示例是首先使用的新功能,现在已弃用的方法 live 。 基本上它是一种事件委托机制,它允许您将事件处理程序绑定到给定节点类型的所有现有实例,而且还绑定到给定节点类型的任何未来实例(“类型”我指的是一组DOM节点匹配的给定的jQuery选择器)。我想在这里说的是,在事件绑定期间,元素不需要存在于DOM中,基本上这个方法的工作原理是将事件处理程序绑定到文档本身,然后对通过DOM冒泡的所有事件做出反应。因此,在事件绑定期间,元素#one1是否存在无关紧要。您可以稍后动态创建它,它仍然有效。
$('#one1').on("click", function() {
console.log('not firing');
});
这是旧的事件绑定方式。它要求在事件可以绑定之前在DOM中存在事件。在您的情况下,您尝试将此单击事件绑定到该时间点在DOM中不存在的元素。在绑定过程之后加载它并不重要。
jsFiddle示例:http://jsfiddle.net/Gajotres/QmNsa/
看看这个例子。在那里,您将在jQuery Mobile中看到5种不同的点击事件绑定方式:
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>
答案 1 :(得分:0)
作为docs stated:
因为立即触发了mobileinit事件,所以您需要 在加载jQuery Mobile之前绑定您的事件处理程序
目前,您的mobileinit
事件在加载jQuery Mobile后正在运行,因为jsFiddle
将在完成加载您从侧边栏中选择的任何库后执行您的javascript代码。为了使其有效,您的结构应如下所示:
<script src="jQuery library include first"></script>
<script>
$(document).on("mobileinit", function() {
// Your code here
});
</script>
<script src="jQuery Mobile include last"></script>