找到你要的答案

Q:jQuery click not working for dynamicly created elements

Q:jQuery点击不是动态创建元素的工作

I looked at the other solutions on SO for this problem and none of them seem to help my case. To give you some background, yesterday I was trying to select all DIVs by a class and store their IDs. See this Now that I have the IDs I want to create some new elements and incorporate the IDs and be able to click on these new elements. I went to JSFiddle to show you a demo but the crazy part is over there, my code works, yet in my app (Chrome extension) it doesn't. What's even crazier is that I'm already implementing jQuery click events in other parts of it without a problem so I'm really confused why it's not working in this particular case. Here's the JSFiddle that works but in my app it doesn't do anything on click. Thanks for any help! I'm sorry for posting so many (silly) questions.

HTML:

<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>

JS:

var HAContainer = document.querySelectorAll('.HA');
var HALength = document.querySelectorAll('.HA').length;

    var id = [];
    var j = 0;

    $('.HA').each(function(){
        id[j++] = $(this).attr('id');
    });

for (var i=0; i<HALength; i++) {

    var HABtn, HABtnImg, HAImgContainer;

    HABtnImg = document.createElement("img");
    HABtnImg.src = ("http://www.freesmileys.org/smileys/smiley-laughing002.gif"); 
    HABtnImg.className = "ha-icon"; 

    HAImgContainer = document.createElement("div");
    HAImgContainer.setAttribute("id", 'HA-'+id[i] + '-container');
    HAImgContainer.appendChild(HABtnImg);

    HABtn = document.createElement("div");
    HABtn.className = 'ha-button';
    HABtn.setAttribute("id", 'HA-container');
    HABtn.appendChild(HAImgContainer);

    HAContainer[i].appendChild(HABtn);
    HAClick(id[i]);

}

function HAClick(id) {

    $('#HA-'+id+'-container').click(function() {
        alert("clicked on ID " + id);
    });
}

我看了其他的解决方案,所以这个问题,他们似乎没有帮助我的情况下。给你一些背景,昨天我去选择所有div的一类和存储他们的ID。现在我有了ID,我想创建一些新的元素,并结合IDS和能够点击这些新元素。我去JSFiddle给你演示,但疯狂的部分是在那里,我的代码工作,但在我的应用程序(浏览器扩展)不行。更不可思议的是,我已经实现了jQuery的单击事件在它的其他部分没有问题,所以我真的很困惑,为什么它不在这个案工作。这里是JSFiddle,但在我的应用程序不在点击什么。谢谢你的帮助!我很抱歉发布这么多(愚蠢的)问题。

HTML:

<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>

JS:

var HAContainer = document.querySelectorAll('.HA');
var HALength = document.querySelectorAll('.HA').length;

    var id = [];
    var j = 0;

    $('.HA').each(function(){
        id[j++] = $(this).attr('id');
    });

for (var i=0; i<HALength; i++) {

    var HABtn, HABtnImg, HAImgContainer;

    HABtnImg = document.createElement("img");
    HABtnImg.src = ("http://www.freesmileys.org/smileys/smiley-laughing002.gif"); 
    HABtnImg.className = "ha-icon"; 

    HAImgContainer = document.createElement("div");
    HAImgContainer.setAttribute("id", 'HA-'+id[i] + '-container');
    HAImgContainer.appendChild(HABtnImg);

    HABtn = document.createElement("div");
    HABtn.className = 'ha-button';
    HABtn.setAttribute("id", 'HA-container');
    HABtn.appendChild(HAImgContainer);

    HAContainer[i].appendChild(HABtn);
    HAClick(id[i]);

}

function HAClick(id) {

    $('#HA-'+id+'-container').click(function() {
        alert("clicked on ID " + id);
    });
}
answer1: 回答1:

You have to delegate your event in order to make it work with dinamically added elements:

$('body').on("click", '#HA-'+id+'-container', function() {
    alert("clicked on ID " + id);
});

I've noticed something and will edit with a better approach:

Change:

HABtn.setAttribute("id", 'HA-container');

To:

HABtn.setAttribute("id", 'HA-'+id[i] + '-inner-container');
HABtn.setAttribute("class", 'HA-container');

And instead of:

function HAClick(id) {
    $('#HA-'+id+'-container').click(function() {
        alert("clicked on ID " + id);
    });
}

simply attach once the event with delegation:

$('body').on("click", '.HA-container', function() {
    alert("clicked on ID " + $(this).attr('id'));
});

你要代表你的事件以使它与动态添加元素:

$('body').on("click", '#HA-'+id+'-container', function() {
    alert("clicked on ID " + id);
});

我注意到一些东西,并将用更好的方法编辑:

改变:

HABtn.setAttribute("id", 'HA-container');

以:

HABtn.setAttribute("id", 'HA-'+id[i] + '-inner-container');
HABtn.setAttribute("class", 'HA-container');

而不是:

function HAClick(id) {
    $('#HA-'+id+'-container').click(function() {
        alert("clicked on ID " + id);
    });
}

只需附上一次事件与代表团:

$('body').on("click", '.HA-container', function() {
    alert("clicked on ID " + $(this).attr('id'));
});
answer2: 回答2:

jsFiddle implicitly selects the javascript you use to be placed inside of an onload event handler.

As a result your code is wrapped with the onload event handler and basically looks likes this

window.onload = function(){
    //your code here
};

The reason it works in jsFiddle is because the script is executing once the DOM is loaded and thus can interact with the elements as they are in the DOM. It is possible that your chrome extension is not acting after the elements have been loaded.

It would be prudent to wrap your javascript in the document.ready shortcut

$(function(){
    //your code here
});

Given that, there are still some issues which exist in your code. It is not clear why you need to have that nested div structure, perhaps as a result of css styling, but one issue is the duplication of ids. They could probably just be class names (I am referencing "HA-container").

jQuery offers a very easy way to create elements in the constructor that you can take advantage of here. It will allow your code to be more streamlined and readable.

Further, you can store the id you use inside of the container element's jquery object reference for data using .data('id',value). This will all you to also assign the click event handler immediately inside of using another function to assign it.

jsFiddle Demo

$('.HA').each(function(){
    var btn = $('<div class="ha-button HA-container">');
    var cont = $('<div id="'+this.id+'-container">').data('id',this.id);
    cont.click(function(){ alert("clicked on ID " + $(this).data('id')); });
    var img = $('<img src="http://www.freesmileys.org/smileys/smiley-laughing002.gif" class="ha-icon" />');
    $(this).append(btn.append(cont.append(img)));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>

JSFiddle隐式选择您使用的是放置在onload事件的JavaScript。

因此你的代码是用onload事件处理程序和基本看起来喜欢这个

window.onload = function(){
    //your code here
};

它在JSFiddle的原因是因为脚本执行一次DOM加载从而与元素作为他们在DOM交互。这是可能的,你的Chrome扩展是不行动后的元素已加载。

这将是审慎的做法是把你的JavaScript在document.ready捷径

$(function(){
    //your code here
});

鉴于此,您的代码中仍然存在一些问题。目前还不清楚为什么你需要嵌套div结构,或许是由于CSS样式,但有一个问题是入侵检测系统的重复。他们可能只是类名(我引用“HA容器”)。

jQuery提供了一个非常简单的方法来创建构造函数中的元素,你可以利用这里。这将允许您的代码更精简和可读性。

此外,你可以把你使用的容器内元素的jQuery对象引用的数据使用ID数据('id',值)。这也将为您分配立即使用另一个函数分配的单击事件处理程序。

JSFiddle演示

$('.HA').each(function(){
    var btn = $('<div class="ha-button HA-container">');
    var cont = $('<div id="'+this.id+'-container">').data('id',this.id);
    cont.click(function(){ alert("clicked on ID " + $(this).data('id')); });
    var img = $('<img src="http://www.freesmileys.org/smileys/smiley-laughing002.gif" class="ha-icon" />');
    $(this).append(btn.append(cont.append(img)));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="HA" id="k2348382383838382133"></div>
<div class="HA" id="k2344444444444444444"></div>
<div class="HA" id="k234543544545454454"></div>
<div class="HA" id="k2346787878778787878"></div>
answer3: 回答3:

I'd re-write it a bit to take advantage of jQuery:

for (var i=0; i<HALength; i++) {

    var HABtnImg = $('<img/>')
            .attr('src', 'http://www.freesmileys.org/smileys/smiley-laughing002.gif')
            .addClass('ha-icon');

    var HAImgContainer = $('<div/>')
            .attr('id', 'HA-'+id[i] + '-container')
            .append(HABtnImg);

    var HABtn = $('<div/>')
            .addClass('ha-button')
            .append(HAImgContainer);
            //don't use duplicate ID's here

    $(HAContainer[i]).append(HABtn);
}

And later attach the event like so:

$(document).on('click', '.ha-button', function(e){
   //your click code here 
   var id = $(this).find('div').attr('id');
   alert("clicked on ID " + id);
});

我想重新写一下利用jQuery:

for (var i=0; i<HALength; i++) {

    var HABtnImg = $('<img/>')
            .attr('src', 'http://www.freesmileys.org/smileys/smiley-laughing002.gif')
            .addClass('ha-icon');

    var HAImgContainer = $('<div/>')
            .attr('id', 'HA-'+id[i] + '-container')
            .append(HABtnImg);

    var HABtn = $('<div/>')
            .addClass('ha-button')
            .append(HAImgContainer);
            //don't use duplicate ID's here

    $(HAContainer[i]).append(HABtn);
}

后来附加事件像这样:

$(document).on('click', '.ha-button', function(e){
   //your click code here 
   var id = $(this).find('div').attr('id');
   alert("clicked on ID " + id);
});
javascript  jquery