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
Related
Here is the link to my codepen to see all my code: http://codepen.io/stevengangano/full/LGvRdq/
My question has to do with my deleteButton function. I have trouble grasping this concept.
I created a function for the delete button called deleteButton(item). I just want to know what does "item" and "parentNode" represent in the variable remove? Which one is the <ul> and which one is the <li>?
An explanation would be appreciated. Thanks!
deleteButton(item) is attached to the removeButton. this represents the current node which is button itself.
item.parentNode will be nothing but parent of the button which is li element. remove variable holds this li element.
Again remove.parentNode will return parent node of the li element which is ul element.
paretNode.removeChild removes a child node from the DOM
So in this case, UL_ELEMENT.removeChild(LI_ELEMENT);
function deleteButton(item) {
var remove = item.parentNode;
remove.parentNode.removeChild(remove);
}
in your code (posted offsite) is long for
function deleteButton(item) {
item.parentNode.parentNode.removeChild(item.parentNode);
}
which removes the parent node of the clicked item from its grandparent node's list of children. The parent node of the delete button is listItem in code, which means an LI item will be deleted.
Elsewhere in code posted offsite (bad practiceâ„¢) the delete function is defined as
removeButton.setAttribute('onclick', 'deleteButton(this);');
which is seriously really very, interesting. It suggests that setting an onclick attribute with text, after HTML parsing has been completed, causes the text to be parsed as source for a javascript function which becomes the attribute value. Okay, so a setter can do this - but onEvent setters doing this is news to me. And testing indicates it being true.
So an answer is that setting the onclick attribute of a node with text compiles the text to a function object, attaches the function object as the onclick attribute value, which when called by clicking supplies the node being clicked on as the this object for the onclick handler. If the function called removes the parent node of the clicked object, in this case an LI element gets removed.
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");
});
I have a list of buttons that is created by the DOM which references an array. When a button in the list is clicked, I want to retrieve the String that is displayed on the Button.
I have tried the following code to reference the string value, but get undefined:
this.String; inside the function when the button is clicked to retreive the string.
How can I properly retrieve the string.
The click handling function is:
$('.timeButtons').click(function() {
confirmation.push(this.textContent);
})
This is how the list of buttons is created:
var populateList=function(array){
var list = document.createElement('ul');
list.className="delete";
for(var i = 0; i < array.length;- i++) {
var item = document.createElement('li');
var itemButton=document.createElement('button');
itemButton.style.cssText='background:#f85a5a; border:none; width:200px; height:50px; margin-bottom:50px; align:center; border-radius:25px; color:#ffffff;'
itemButton.appendChild(document.createTextNode(array[i]));
item.appendChild(itemButton);
list.appendChild(item);
}
return list;
}
Assuming that this is a reference to the button element in question, you can use this.textContent to get the button's text. (Or .innerHTML.)
Demo: http://jsfiddle.net/w0ntsrLx/
Or since in your edited question you seem to be using jQuery, use the .text() method. In a comment you say that the containing div has the "timeButtons" class, so bind a delegated handler to that div as follows:
$(".timeButtons").on("click", "button", function(e) {
confirmation.push($(this).text());
});
Demo: http://jsfiddle.net/w0ntsrLx/1/
That way the function will only be called if the click is on a button element within the .timeButtons div, and this will be the clicked button. The click handler that you show in your question with $(".timeButtons").click(...) is bound to the div and doesn't in any way test for the buttons, so within the handler this will be the div, not the clicked button.
Check this out
Assuming you want pure javascript code,
Whenever an event is triggered, an object is passed back in callback (generally being named as 'event'). this object has many properties including source element, position of click and many more.
get the element using event.srcElement
You can use element.innerHTML or element.innerText to find out the content of the Button.
There is a difference between using innerText and innerHTML, but in your case, both can be used.
Also, you can use jquery too to easily append child, create elements and binding events.
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.
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'));
});