简体   繁体   English

jQuery单击事件不会在“已加载”的HTML上触发

[英]jQuery click event does not fire on 'loaded' html

I'm trying to understand why loading HTML into a div block renders its class statement effectively non-existent to a click event. 我试图理解为什么将HTML加载到div块中会导致单击事件实际上不存在其class语句。

My HTML code looks like this: 我的HTML代码如下所示:

<div id="load-to"></div> 

<div id="load-from">
    <div class="load-from-css"> Hello!</div> 
</div>

<button>load it!</button>

My JS code looks like this: 我的JS代码如下所示:

$('button').click(function(){
    var html = $('#load-from').html();
    $('#load-to').html(html);
});

$('.load-from-css').click(function(){
    alert('clicked');
});

When I click the button the HTML from the lower div block is loaded into the upper div block, and then the HTML looks like this: 当我单击按钮时,将来自较低div块的HTML加载到较高div块中,然后HTML如下所示:

<div id="load-to">
    <div class="load-from-css"> Hello!</div>
</div> 

<div id="load-from">
    <div class="load-from-css"> Hello!</div>
</div>

My question is, why does the second click event (defined in my jQuery code) only work on the original lower "Hello!" 我的问题是,为什么第二个单击事件(在我的jQuery代码中定义)仅在原始的下部“ Hello!”上起作用? div block but not on the loaded upper one, when both have the same class definition? div块但不在加载的上层块上时,当两者具有相同的类定义时?

Other answers have already covered the core reason for your problem (that copying the HTML of an element and placing it elsewhere will create a brand new DOM element and does not copy any events that were bound to the original element... keeping in mind that when you add an event listener, it will only bind to any elements that exist at the time that you do so) 其他答案已经涵盖了您问题的核心原因(复制元素的HTML并将其放置在其他位置将创建一个全新的DOM元素,并且不会复制绑定到原始元素的任何事件……请记住,当您添加事件监听器时,它只会绑定到您当时存在的任何元素)

However, I wanted to add some other options for accomplishing what you want to do. 但是,我想添加其他一些选项来完成您想做的事情。

jQuery has a few different techniques that make this sort of thing easy: jQuery有几种不同的技术可以简化这种事情:

.clone() will essentially do the same thing as you are doing now*, it will copy the HTML content and create a new DOM element. .clone()本质上将与您现在执行的操作*相同,它将复制HTML内容并创建一个新的DOM元素。 However, if you pass true (ie: .clone(true) ), it will clone it with all data and events intact. 但是,如果您传递true (即.clone(true) ),它将在所有数据和事件完好无损的情况下对其进行克隆。

* note that to truly get the same result as using .html() , you need to do .children().clone() , otherwise you'll get both the inner and outer div .. this may or may not be necessary depending on the use case *请注意,要真正获得与使用.html()相同的结果,您需要执行.children().clone() ,否则您将同时获得内部和外部div ..这可能是必需的,也可能不是必需的。在用例上

ex: https://jsfiddle.net/Lx0973gc/1/ 例如: https//jsfiddle.net/Lx0973gc/1/

Additionally, if you were in this same situation but did not want to make a clone, and simply wanted to move an element from one place to another, there is another method called .detach() which will remove the element from the DOM, but keep all data and events, allowing you to re-insert it later, in the same state. 此外,如果你在这个同样的情况,但希望做一个克隆,而只是想一个元素从一个地方移动到另一个,还有另一种方法叫做.detach() ,这将从DOM删除元素,但保留所有数据和事件,以便您稍后以相同状态重新插入。

ex: https://jsfiddle.net/Lx0973gc/2/ (not the best example because you won't see it move anywhere, but it's doing it!) 例如: https//jsfiddle.net/Lx0973gc/2/ (不是最佳示例,因为您不会看到它移动到任何地方,但是它正在这样做!)

As another alternative, you can use delegated event binding, which actually binds the event to a different element (a parent) which you know won't change, but still allows you to target a child element within it: 作为另一种选择,您可以使用委托事件绑定,它实际上将事件绑定到您知道不会改变的其他元素(父元素),但仍然允许您将其中的子元素作为目标:

$('body').on({
    'click': function() {
    alert('clicked');
  }
}, '.load-from-css');

ex: https://jsfiddle.net/Lx0973gc/4/ 例如: https//jsfiddle.net/Lx0973gc/4/

The $('.load-from-css') finds all elements currently existing and .click(...) attaches a listener to all these elements. $('.load-from-css')查找当前存在的所有元素, .click(...)将侦听器附加到所有这些元素。 This is executed once. 执行一次。

Then you copy the raw html which does not transfer any listeners. 然后,您复制不传输任何侦听器的原始html。 The DOM has nodes onto which the listeners are attached but when you copy the plain HTML you essentially create new nodes based on the html. DOM具有侦听器附加到的节点,但是当您复制纯HTML时,实际上是基于html创建新节点。

Because you are copying just the HTML. 因为您只复制HTML。 The js file is loaded at the beginning, when there is just one instance of a div with the "load-from-css" class. 当只有一个带有“ load-from-css”类的div实例时,将在开始时加载js文件。 You should execute again the code adding the listener after you copy the html. 复制html后,您应该再次执行添加侦听器的代码。 Somethinglike: 就像是:

 $('button').click(function(){
    var html = $('#load-from').html();
    $('#load-to').html(html);

    $('.load-from-css').click(function(){
        alert('clicked');
    });

 });

#load-to inner HTML is initially empty. #load-to内部HTML最初为空。 so added click listener only for #load-from .load-from-css . 因此,仅为#load-from .load-from-css添加了点击监听器。 Dynamically bind element will not attach the click listener. 动态绑定元素将不会附加点击监听器。

jQuery new version have the feature to attach the event for dynamic elements also. jQuery新版本还具有为动态元素附加事件的功能。 Try this 尝试这个

$('button').click(function(){
        var html = $('#load-from').html();
        $('#load-to').html(html);
    });

    $(document).on('click', '.load-from-css', function(){
        alert('clicked');
    });

Also we can use like this 我们也可以这样使用

$( document ).delegate( "load-from-css", "click", function() {
  alert( "Clicked!" ); // jQuery 1.4.3+
});

Simply because the page did not refresh. 仅仅是因为页面没有刷新。 You loaded a content to another content without loading the page, and the browser wont recognized any event added to the loaded element. 您将一个内容加载到另一个内容而不加载页面,浏览器将无法识别添加到已加载元素中的任何事件。

What you should do is load your javascript tag with the load along with the content. 您应该做的是将javascript标记与内容一起加载。

Your code should be like this: 您的代码应如下所示:

   <div id="load-to">
    <div class="load-from-css"> Hello!</div>
</div> 

<div id="load-from">
    <div class="load-from-css"> Hello!</div>
   <script>$('button').click(function(){
        var html = $('#load-from').html();
        $('#load-to').html(html);
    });

    $('.load-from-css').click(function(){
        alert('clicked');
    });</script>
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM