This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 6 years ago.
This problem is so weird and the title might not seem to fully explain the meaning, so this is what i mean, i have list of div nested in each other and i can get the click event and other event of the outer Div but can't get the click event and other event of the inner div and it's content. below is my code
var scrollWidth = 124;
var currentPhoto;
var defaultDisplayPhoto = 5;
var maxScrollCount=0;
var maxScroll =(scrollWidth*currentPhoto)-(scrollWidth*defaultDisplayPhoto);
var maxScroll;
var timeCounter;
var duration = 1000; //time to wait to fire the event;
var photoAllowed = 12;
var canAddMore;
var eventCounter= [];
$("input.upload").on('change',function(event){
$(".mycarousel-container").show();
if(eventCounter){
i=eventCounter.length;
}else{
i=0;
}
imgsrc = URL.createObjectURL(event.target.files[0]);
//for(var i=0; i <eventCounter.length; i++)
var div = $("<div class='mycarousel' style='left:"+left+"px' id='picture"+i+"'></div>");
var transparentDiv = $("<div class='transparent'></div>");
var deleteIcon = $("<span class=\"deletebutton\"><i class=\"glyphicon glyphicon-trash\"></i></span>");
var imgPreview = "<img class='myimg' src="+imgsrc+">"
transparentDiv = transparentDiv.html(deleteIcon);
div = div.html(transparentDiv);
div = div.append(imgPreview);
$(".carouser-inner").append(div);
left = left+120;
eventCounter.push(imgsrc);
if(eventCounter.length>5){
$("#carousel_control_left").show();
$("#carousel_control_left").addClass('myActive');
scrollThumb('Go_R');
}else{
$("#carousel_control_left,#carousel_control_right").hide();
}
if(eventCounter.length == 12){
alert('end')
$("input.upload").attr('disabled',true);
}else{
$("input.upload").attr('disabled',false);
}
});
$('.mycarousel').click(function(){
alert('this is inner div with border color blue');
});
$('.myimg').click(function(){
alert('this is inner image');
});
DEMO ON FIDDLE
please see the demo on fiddle and add some images and divs will show up, now try to get the click event of the div with border color BLUE or the image in it
use $(document).on cause when you assign your click event , div element is not in DOM yet
$(document).on( 'click', '.mycarousel', function () {
alert("here");
});
You can't register a static listener, because you add the items dynamically. You can use on with document instead:
$(document).on("click", '.mycarousel', function(){
alert('this is inner div with border color blue');
});
$(document).on('click', '.myimg', function() {
alert('this is inner image');
});
Try this.
$(document).on('click', '.mycarousel' , function() {
//code here ....
});
Related
How can I call a click event listener on a dynamically created element rendered in the DOM?
I have some scripts that dynamically create elements in the DOM, one of them being a button/a. I would like that button/a to do something once the user clicks it. Right now nothing happens but if I add a setTimeout on the things to happen upon a click, then it kind of works - only let's me do the something on the first element's click (button/a). However I can't rely on a setTimeout to make this chunk of code work.
Here is more or less what I have without the setTimeout method:
// This triggers the whole process
var mainBtn = document.querySelector('.mainBtn');
mainBtn.addEventListener('click', function(e){
e.preventDefault();
mainFunc();
});
// This creates and renders dynamic content in DOM
function mainFunc(){
var out = document.querySelector('.outputWrapper');
var mainArr = ['something ', 'another ', 'else ', 'last one.'];
var div = document.createElement("div");
var btn = document.createElement("a");
var btnText = document.createTextNode("Click Me");
btn.appendChild(btnText);
btn.className = "clickMeBtn";
for(a of probArr){
div.append(a);
div.append(btn);
}
out.append(div);
}
// This is what should happen on button/a click
var clickedBtn = document.querySelector('.clickMeBtn');
if( clickedBtn != null ){
clickedBtn.addEventListener('click', function(e){
e.preventDefault();
console.log('click');
});
}
Here's with the setTimeout method:
// This triggers the whole process
var mainBtn = document.querySelector('.mainBtn');
mainBtn.addEventListener('click', function(e){
e.preventDefault();
mainFunc();
});
// This creates and renders dynamic content in DOM
function mainFunc(){
var out = document.querySelector('.outputWrapper');
var mainArr = ['something ', 'another ', 'else ', 'last one.'];
var div = document.createElement("div");
var btn = document.createElement("a");
var btnText = document.createTextNode("Click Me");
btn.appendChild(btnText);
btn.className = "clickMeBtn";
for(a of probArr){
div.append(a);
div.append(btn);
}
out.append(div);
}
// This is what should happen on button/a click
setTimeout(function(){
var clickedBtn = document.querySelector('.clickMeBtn');
if( clickedBtn != null ){
clickedBtn.addEventListener('click', function(e){
e.preventDefault();
console.log('click');
});
}
}, 10000);
Again this kind of works...it let's me click only on the first instance of the clickedBtn variable.
Any suggestions on how to make this idea work?
Thanks a lot!!
document.querySelector('.clickMeBtn'); returns the first found element, or null.
Attach click event handler when you create the anchor element:
var btn = document.createElement("a");
btn.addEventListener('click', function(e){
e.preventDefault();
console.log('click');
});
I am not 100% sure of what is your question. But the problem I can see is that you cannot bind listeners to elements that are not yet created in the DOM.
So I can see 3 options here:
1- You build a wrapper on top of document.createElement() and a wrapper on top of addEventListener to bind the events to the elements after they are created. For example you build a map of event listeners to begin with, with the 'element selector' as Key and function to call as Value. Then you do a lookup of the listener once the element has been created and you bind it to it with addEventListener.
2- You use JQuery on() method like this:
// define the click handler for all buttons
$( document ).on( "click", "button", function() {
alert( "Button Clicked!" )
});
/* ... some time later ... */
// dynamically add another button to the page
$( "html" ).append( "<button>Click Alert!</button>" );
Source: this JQuery script is from [here][1]
(EDIT) 3- you just bind it after creation, as suggested. Although I thought you wanted to do more advanced stuff, like dynamically add elements asynchronously from the listeners.
Below is the code that dynamically creates an element and attach an onclick event.
var div = document.createElement('div');
div.onclick = function(e){
console.debug(e);
}
var parent = document.getElementsByClassName('myid_templates_editor_center_menu');
parent[0].appendChild(div);
How about attaching a right click event?
The answer to your question consists of two parts:
1) How to attach the right-click event?
Answer: use the contextmenu event.
2) How to attach an event to dynamically created elements?
Answer: the idea is to attach the event to the parent element that will contain your newly created element. The event will propagate along the DOM until it reaches your parent element.
Working Example:
//get parent elements
var elements = getElementsByClassName('myid_templates_editor_center_menu');
//attach to the first found parent element
elements[0].addEventlistener('contextmenu', function(e) {
console.log("right clicked!");
})
Add
div.oncontextmenu = function(e){
e.preventDefault();
console.debug(e);
}
instead onclick
You can use contextmenu event
window.onload = function() {
var div = document.createElement("div");
div.innerHTML = "right click";
div.oncontextmenu = function(e) {
console.debug(e.type, e);
}
document.body.appendChild(div);
}
Working Example
node.addEventListener('contextmenu', function(ev) {
ev.preventDefault();
alert('success! - Right Click');
return false;
}, false);
Codepen :
http://codepen.io/mastersmind/pen/WogoVB
var div = document.createElement('div');
div.oncontextmenu = function(e){
console.debug(e);
}
var parent = document.getElementsByClassName('myid_templates_editor_center_menu');
parent[0].appendChild(div);
I want to create a new element and assign this element the same event for onclick, which it has created it.
DEMO
$(function(){
var counter = 0;
$('.sub').click(function(event){
event.stopPropagation();
counter++;
$div = $(this); // makes more sense in the original code
$div.append('<div class="sub" title="subsub">subsub' + counter + '</div>');
//$div.find('.sub').click // <-- ?????
});
});
In my demo I want to create a new subsub for every sub, which was clicked. Than I want to add the same click event to the new subsub element.
Could anyone help me with this?
I've found nothing for this problem. Maybe I don't have the correct keywords for google or SO :/
Just use event Delegation
$(document).on('click', '.sub', function(event){
Your click events seem to be working correctly at this point,because you are using append which actually nests the new div inside the div that is clicked. Try using after and the functionality breaks.
$(function(){
var counter = 0;
$(document).on('click', '.sub', function(event){
event.stopPropagation();
counter++;
$div = $(this); // makes more sense in the original code
$div.after('<div class="sub" title="subsub">subsub' + counter + '</div>');
});
});
Check Fiddle
Why not create proper elements instead :
$(function(){
var counter = 0;
$('.sub').on('click', doStuff);
function doStuff(event) {
event.stopPropagation();
counter++;
var $div = $(this),
$sub = $('<div />', {'class':'sub',
title : 'subsub',
text : 'subsub' + counter,
on : {
click : doStuff
}
}
);
$div.append($sub);
}
});
This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 10 years ago.
I am trying to create a list of divs. When the new layer button is clicked, there is a new div created with a unique ID. When I try to call on these dynamically added divs, there is no response. I am confused because the preexisting divs work.
<input type="submit" id="newLayer" value="New Layer">
<div id="layersContainer" class="layerscontainer">
<div class="layer" id="layer1">fadfa</div>
<div class="layer" id="layer2">2</div>
</div>
var newLayerCounter = 2;
var layerID = "";
var layersArray = new Array();
var clickedElement = "";
function selectLayer(){
$(clickedElement).css({"background-color":"yellow"});
}
$('#layersContainer div').on("click", function(){
clickedElement = $(this).attr("id");
alert(clickedElement);
selectLayer();
});
$('#newLayer').on("click", function(){
newLayerCounter = newLayerCounter + 1;
layerID = "#layer"+ newLayerCounter;
$('<div/>', {
id: "layer"+ newLayerCounter,
class: "layer"
}).appendTo('#layersContainer');
$(layerID).text('hey');
})
Here is a link to a working JSfiddle
http://jsfiddle.net/Q3dSp/24/
Change your
$('#layersContainer div').on("click", function(){
to
$(document).on("click", '#layersContainer div', function () {
clickedElement = $(this).attr("id");
alert(clickedElement);
selectLayer();
});
It is known as delegated event.
Try with $('#layersContainer').on("click", "div", function(){ (...) });
http://jsfiddle.net/3hqfn/1/
change :
$('#layersContainer div').on("click", function(){
with this:
$('#layersContainer').on("click", "div", function(){
Try with this one:
$('#layersContainer').on("click", 'div', function(){
clickedElement = $(this).attr("id");
alert(clickedElement);
selectLayer();
});
In this situation you need a event delegation to existing closest parent when dom was ready.
I'm trying to add a div to a row of content with the click of a button. My code works for the first row but not for any other row. Please help. This is the function for the button:
$(".addMMbtn").each(function() {
$(this).bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
}
);
});
You can see a fiddle of the problem here: http://jsfiddle.net/z7uuJ/
$(".addMMbtn") will only find the elements present on the page and your code will only attach click event handler on them. Since you are adding the elements dynamically you should either use delegate or on (if you are using jQuery 1.7+) for click event to work on them too. Try this
Using delegate
$('#default').delegate('.addMMbtn', 'click', function() {
$('<div class = "mmCell prep"></div>')
.appendTo($(this).closest(".txtContentRow").find(".txtContent"));
});
Using on
$('#default').on('click', '.addMMbtn', function() {
$('<div class = "mmCell prep"></div>')
.appendTo($(this).closest(".txtContentRow").find(".txtContent"));
});
Demo
Instead of assigning click event directly on the button you need to use on():
$(document).on("click", ".addMMbtn",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
}
);
In this case event handler will be subscribed to all newly added elements.
Code: http://jsfiddle.net/z7uuJ/5/
You don't need to loop through the elements to bind the handler:
$(".addMMbtn").live('click', function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
});