jQuery 单击事件未在 jQueryMobile 中触发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16375975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery click event not firing in jQueryMobile
提问by Marc
Using jQuery jquery-1.9.1.js and jQueryMobile 1.3.1 (Chrome 26/Windows 7) I cannot see why one of these 'click' events bound to #one1 fires and the other doesn't:
使用 jQuery jquery-1.9.1.js 和 jQueryMobile 1.3.1 (Chrome 26/Windows 7) 我不明白为什么绑定到 #one1 的这些“点击”事件之一触发而另一个不触发:
HTML:
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:
JavaScript:
<script>
$(document).on( "mobileinit", function() {
$(document).on('click', '#one1', function(e){
console.log('firing');
});
$('#one1').on("click", function() {
console.log('not firing');
});
});
</script>
When I run it in JSFiddle both events fire when not wrapped in the "mobileinit" event: http://jsfiddle.net/9NRwa/
当我在 JSFiddle 中运行它时,两个事件都在未包含在“mobileinit”事件中时触发:http: //jsfiddle.net/9NRwa/
What am I missing here?
我在这里缺少什么?
回答by Gajotres
Intro
介绍
First thing first, mobileinitevent should not be used for event binding. While it CAN be used like that mobileinitwas not created for that purpose. It was created for jQuery Mobile parameter auto-initialization, so it should not be used for event binding.
首先,mobileinit事件不应该用于事件绑定。虽然它可以像mobileinit不是为此目的而创建的那样使用。它是为 jQuery Mobile 参数自动初始化而创建的,因此不应用于事件绑定。
Correct way is to use proper page events like pageinit. For more information about page events take a look at my other answer that covers various jQuery Mobile page events and their difference towards usual jQuery document ready paradigm: jQuery Mobile: document ready vs page events.
正确的方法是使用适当的页面事件,如pageinit。有关页面事件的更多信息,请查看我的其他答案,其中涵盖了各种 jQuery Mobile 页面事件及其与通常的 jQuery 文档就绪范例的区别:jQuery Mobile:文档就绪与页面事件。
Not let me answer this question. Events like click can be bound in a few different ways. Lets look at examples you have used:
不让我回答这个问题。可以通过几种不同的方式绑定像 click 这样的事件。让我们看一下您使用过的示例:
Various ways of event binding with jQuery
jQuery 事件绑定的各种方式
First example
第一个例子
$(document).on('click', '#one1', function(e){
console.log('firing');
});
This first example is something new that came to use first with now deprecated method live. Basically it's an event delegation mechanism that allows you to bind event handlers not just to all existing instances of a given node type, but also to any future instances of a given node type (by "type" I mean a set of DOM nodes matched by a given jQuery selector). What I want to say here is, during the event binding that element don't need to exist in a DOM, basically this method works by binding event handlers to the document itself and then reacting to all the events that bubble up through the DOM. So it doesn't matter if element #one1 exist or not during the event binding. You can create it dynamically later and it will still work.
第一个示例是新的东西,首先使用现在已弃用的方法live。基本上,它是一种事件委托机制,允许您将事件处理程序不仅绑定到给定节点类型的所有现有实例,还绑定到给定节点类型的任何未来实例(“类型”我指的是一组 DOM 节点匹配给定的 jQuery 选择器)。我在这里想说的是,在事件绑定期间,元素不需要存在于 DOM 中,基本上这个方法的工作原理是将事件处理程序绑定到文档本身,然后对通过 DOM 冒泡的所有事件做出反应。所以在事件绑定期间元素#one1 是否存在并不重要。您可以稍后动态创建它,它仍然可以工作。
Second example
第二个例子
$('#one1').on("click", function() {
console.log('not firing');
});
This is on old way of event binding. It requires that event exists in the DOM before event can be bind. In your case you were trying to bind this click event to the element that didn't exist in a DOM at that point in time. It doesn't matter it was loaded after the binding process.
这是事件绑定的旧方式。它要求事件在 DOM 中存在才能绑定事件。在您的情况下,您试图将此单击事件绑定到当时不存在于 DOM 中的元素。在绑定过程之后加载它并不重要。
Working example
工作示例
jsFiddle example: http://jsfiddle.net/Gajotres/QmNsa/
jsFiddle 示例:http: //jsfiddle.net/Gajotres/QmNsa/
Take a look at this example. There you will see 5 different ways of click event binding in jQuery Mobile:
看看这个例子。在那里您将看到 jQuery Mobile 中点击事件绑定的 5 种不同方式:
- 2 click event are bound in HEAD, before page is initialized into the DOM
- 2 click events are bound in HEAD in pagebeforeshow event, basically this is also a delegation of binding because event are bound when page is about to be shown and already inside a DOM
- 1 click event is bound in a BODY after all page content. Because all content is loaded inside a DOM at this point this click event will work.
- 2 点击事件绑定在 HEAD 中,在页面初始化到 DOM 之前
- 2个点击事件在pagebeforeshow事件中绑定在HEAD中,基本上这也是绑定委托,因为当页面即将显示并且已经在DOM中时绑定事件
- 1个点击事件在所有页面内容之后绑定在一个BODY中。因为此时所有内容都加载到 DOM 中,所以单击事件将起作用。
HTML :
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>
Conclusion
结论
- Do not use mobileinit event for event binding, it will trigger before page is loaded into the DOM and only events bind with delegation will work.
- Bind your events in a correct jQuery Mobile page events.
Usefull links regarding this topic:
有关此主题的有用链接:
jQuery Live() Method And Event Bubbling
While livemethod is deprecated onmethod should be used instead. In some benchmarks on method is 2x faster.
- Various jQuery Mobile page events
- What does “event bubbling” mean?
回答by Eli
As the docs stated:
正如文档所述:
Because the mobileinit event is triggered immediately, you'll need to bind your event handler before jQuery Mobile is loaded
因为 mobileinit 事件是立即触发的,所以您需要在加载 jQuery Mobile 之前绑定您的事件处理程序
Currently, your mobileinit
event are running after jQuery Mobile is loaded since jsFiddle
will execute your javascript code after finish loaded any libraries you've chosen from the sidebar. To make it works, your structure should look like this:
目前,您的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>