This question already has answers here:
Using .on() and e.stopPropagation() on dynamic elements
(5 answers)
Closed 7 years ago.
http://jsfiddle.net/w8ak1yyy/7/
The project is to create colors based off the child. I am focusing on fixing the LEFT div (GREEN box). However when I try to create more divs off of the left most box (GREY), it keeps calling the parent div (GREEN). It does not create a div off the child clicked.
Now I am trying to stop propagation to limit the event call only on the child, but the specific selectors never select the child.
LINE 38:
$(".left-child").click(function(event){
propStopped( event );
event.stopPropagation();
propStopped( event );
alert("Found child");
});
this code should target the child element but doesn't, and I also tried the following selectors below and they also didn't find the child.
$(".left-child")
$(".left > .left-child")
$("div.left" > .left-child")
The end result for now should be making more divs to the left by clicking the left most div.
Line 63 begins appending the left div.
I placed a counter that displays on the div being clicked on, which updates the parent div(GREEN) rather than the child.
You can't attach an event to an element that doesn't exist yet. You should use event delegation:
$(".left").on("click", ".left-child", function(event){
propStopped( event );
event.stopPropagation();
propStopped( event );
alert("Found child");
});
Related
I am new to HTML and JS.
Need to create dynamic expand-collapse list.
var parentId = document.getElementById("ABCD")
parentId.setAttribute("data-toggle","collapse")
parentId.setAttribute("data-target","#collapse1")
var tag = document.createElement("ul");
tag.setAttribute("id","collapse1")
tag.appendChild(document.createTextNode("PQR"))
parentId.appendChild(tag)
Trying for list as-
ABCD
PQR
So in this case, when i am clicking on ABCD, PQR gets expanded/collapsed.
But the problem is on clicking on PQR, it gets collapsed again.
So does the properties of parent gets applied to child node also?
it's not that it gets properties of it's parent, this has to do with how events handled, specifically event bubbling. When you click a child element, a click event if fired for all parent elements of what you clicked on
to cancel the event from bubbling when you click the appended elements you need to event.stopPropagation() inside of a click handler for the new elements
after you append them do the following
// tag.appendchild code goes here, then do the following
document.querySelector("#collapse1").onclick=function(event){
event.stopPropagation();
}
also, i should mention all this would be 10 times easier with jQuery
I'm generating and appending several spans to divs on page load.
HTML structure like:
<div id="holder">
<div id="grid"></div>
</div>
Then loop through and append spans to the nested div:
$span = $('<span />').attr('class', 'colorSquare');
$("#grid").append($span);
Then, I want to click a button and reset (delete the originally appended spans, because I don't want to reappend spans) what's inside the div's with:
$("#holder > div").html("");
On initial page load / initial generation of spans inside the div, the click event handler is registered to the div's spans on document.ready , and the following works:
$("#grid span").click(function () { console.log("working"); });
However, after resetting with $("#holder > div").html("");, the click handler doesn't work. I'm assuming this is because the handler is only assigned on initial document ready, but I wasn't expecting all handlers to be removed once you reset the div's content. How do I prevent assigned handlers from being removed?
This is because you are assigning the click handler onto the span element that you have added to #grid. When you clear #grid, you also remove the span and therefore you lose the click handler. You will either have to re-assign the handler again as soon as another span is created, or use an alternate handler that is tied to an element that does not get removed (such as #grid):
$('#grid').on('click', 'span', function() { console.log("working"); });
This alternative uses jQuery's on method, and binds the handler to the #grid element. However, the second parameter labels that you only care about clicking on span elements which are children of #grid.
Is it possible to select a div's all child divs with a specified class using jQuery?
For example:
If I click on a div it should toggle the clicked .name div's all children with .content class(div1,div2,div3).
The html:
<div class="name">
Name of div 1
<div class="content">
Content of div 1
</div>
<div class="name">
Name of div 2
<div class="content">
Content of div 2
</div>
<div class="name">
Name of div 3
<div class="content">
Content of div 3
</div>
</div>
</div>
</div>
The script:
$(function()
{
$('.name').click(function()
{
$(this).children('.content').slideToggle();
});
});
I've tried this script, but it's select the divs on the first level only.
First let me explain an issue as result what you're trying to do
If you decide to click on DIV 2 the CONTENT 2 and 3 should open,
but if than you click DIV 1 a total mess will happen:
DIV 1 will open but all the other will close.
EXAMPLE WITH ISSUE (PRESENT IN OTHER ANSWERS)
To prevent that
you should store the is clicked or not state directly into the clicked DIV
WORKING EXAMPLE
$('.name').click(function(ev){
ev.stopPropagation();
var io = this.io ^= 1; // Toggle 1/0 state
$('.content', this)[io?"slideDown":"slideUp"](function(){
$(this).closest('.name')[0].io = io; // Store state also to all other
});
});
ev.stopPropagation(); prevents the click to navigate up the DOM triggering the same function on not targeted elements (with same className)
var io = this.io ^= 1; toggles using the XOR ^ bitwise operator a 1/0 value (later used as boolean) directly into the element Object custom io (or name it as you like) property (or name it as you like).
Than what we do is: by using the Conditional Operator (?:) we use the toggled this.io value 1 or 0 as boolean, and if value is 1 (true) do a slideDown else, logically a slideUp for every $('.content', this) (.content, children of this)
if we did not used an additional function callback for the slide, you might get the issue of the need to double-click some DIV elements, cause the io value of that particular element was not up to date for it's state, so to change that we just need to set for every slided element the same io state to the .name (the toggler) (.closest()) parent.
Your code works, but the click is propagation. A click inside an inner name is also a click inside the outer name. Add this :
$('.name').click(function(e)//pass the event
{
e.stopPropagation(); // prevent the event from bubbling.
$(this).children('.content').slideToggle();
});
Also, you are using .children, which targets direct children only. If you want all childrens (descendants), use .find().
You need to stop propagating the event so that it doesn't bubble up the tree -
$('.name').click(function(e) {
e.stopPropagation();
$(this).find('.content').slideToggle();
});
http://jsfiddle.net/jayblanchard/sSRJ4/
I am creating Table of Content dynamically.
Hierarchy levels:
Parent Div
Children Div
Grand Children Div
For this I am creating div 's dynamically.
Then I am assigning margin to those divs.
Parent Div :- No margin
Children Div :- margin-left :15px;
Grand Children Div :- margin-left :35px;
So I am able to create table of content dynamically.
Problem :
I created more than one parent divs and there sub divs as per hierarchy.
But If I am applying click event on first parent div then that event also getting apply on other parent div why because I am adding click event on class.
In this click I am facing problem in slideToggle().
As I am using class so because of this it is getting applied on other also.
Example:
$('main_div').haml(['%div.g', {id:'g_' + i', name: i}, Parent Div]);//class = 'g'
$('main_div').haml(['%div.g1', {id:'g_' + i, name: i, style:'**margin-left: 15px**;'}, Children Div]);//class = 'g1'
$('main_div').haml(['%div.g2', {id:'g_' + i, name: i, style:'**margin-left: 35px**;'}, Grand Children Div]);//class = 'g2'
In this div 'i' value is coming from database on with the help of AJAX GET.
So what changes should I do for slideToggle() : In this I just want to toggle only clicked parent div's childrens only?
Any hints / suggestions please?
Reference code:
$('#main_div').on('click','.g', function(){
$('#main_div').find('.g1,.g2').slideToggle();
});
If I understand right, slideToggle() is click event for all parents div? Than in function you can use 'this' variable.
$(this).find(...some selector for child divs...').slide..
Show, please, code for click event?
Try this:
$('#main_div').on('click','.g', function(){
$(this).find('.g1,.g2').slideToggle();
});
When jQuery calls your click handler it sets this to the clicked item, i.e., to the .g element, so only apply .find() to that item's descendants by using $(this).find(...
Following Reference Link solved my problem.
On click slidetoggle div but hide others first - jQuery
Thanks to other people also.
I am aware that e.target contains the info of the element just below the cursor, but what if I want to know the class name of the div which has a table>tr>td>button in it and I'm clicking that button inside that td. I know this events bubbles up and there should be a way to find out if the div exists in that bubbling levels. Any help.
Scenario: button is inside a modal window. How do I find the modal windows class name on click of the button inside it.
Use .closest() to traverse up the DOM to the nearest match:
var parentDiv = $(yourButton).closest('div');
Or in the button's click:
$(yourButton).click(function() {
var nearestParentDiv = $(this).closest('div');
// And read its class
console.log(nearestParentDiv.attr('class'));
});
The selector .closest() accepts can of course be more specific than this, so if if the modal window <div> has some known class but you need to inspect its other classes, you should use the more specific selector.
Yes as you say the event will bubble up to your div, so just make the div handle the event with .on() , like this:
$('#yourdiv').on('click',':button',function(e) {
alert( $(e.delegateTarget).attr('class') );//alerts the classes of #yourdiv
alert( $(this).attr('id'));//alerts the id of the clicked button (if have one)
});
UPDATE:
Fixed obtaining the reference to the original div where the event was attached. With event.delegateTarget from the Event object . Thanks Cristophe and Kevin B. for spotting the error.
See working demo
You can use .parent() to get the parent div attributes like id: http://jsbin.com/ololad/1/edit
$('button').click(function(){
console.log($(this).parent().attr('id'));
});