Reputation: 548
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);
});
}
Upvotes: 3
Views: 78
Reputation: 82337
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.
$('.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>
Upvotes: 1
Reputation: 14927
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);
});
Upvotes: 0
Reputation: 21789
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'));
});
Upvotes: 3