I want to attach the "click" event to all button inside a div. Except this:
var div1 = document.getElementById("div1");
var elements = div1.getElementsByTagName('button');
for(var i = 0, len = elements.length; i < len; i++) {
elements[i].onclick = function () {
// stuff
}
}
Is there a better way to attach "onclick" function handler to all the buttons at once in pure js?
As mentioned in the comments, you can use event delegation. In that case, a single event handler is added to a common ancestor of the elements you want to handle. Inside the handler, the element where the event originated is inspected and if it is one of the ones that should be handled, the actual event handler logic is executed.
In your case it could be like:
var div1 = document.getElementById('div1');
div1.onclick = function(event) {
if (event.target.nodeName.toLowerCase() !== 'button') {
return;
}
// stuff
};
Note that there differences in the event system between browsers, especially older IE versions. You will have to deal with that if want to support those versions. You might also want to consider using addEventListener instead of onclick.
In order to reduce the code you can define a clickHandler function and attach this function to all buttons.
The result of div1.getElementsByTagName('button') is an HTMLCollection and not an array. In order to take advantage of Array.forEach syntax you can use call.
The example:
var clickHandler = function (e) {
console.log(this.textContent);
};
var div1 = document.getElementById("div1");
var elements = div1.getElementsByTagName('button');
Array.prototype.forEach.call(elements, function(ele) {
ele.onclick = clickHandler
});
<div id="div1">
<button type="button">Button 1</button>
<button type="button">Button 2</button>
<button type="button">Button 3</button>
<button type="button">Button 4</button>
</div>
If you can use the Arrow Functions, they are supported only in ES6, you can compact more your code:
var clickHandler = function (e) {
console.log(this.textContent);
};
var div1 = document.getElementById("div1");
var elements = div1.getElementsByTagName('button');
Array.prototype.forEach.call(elements, (ele) => {ele.onclick = clickHandler;});
<div id="div1">
<button type="button">Button 1</button>
<button type="button">Button 2</button>
<button type="button">Button 3</button>
<button type="button">Button 4</button>
</div>
Related
I have built a pretty complex slider and now have to build it so it can be removed and re-added to the page based on a selection. I have a simple click event listener for the pagination to call all my animations and timers that looks like this
let $slideItems = $slideShow.querySelector('.slideshow-items'),
$slideshowNav = $slideShow.querySelector('.slideshow-nav'),
$slideshowNavButton = $slideshowNav.getElementsByTagName('button');
forEach($slideshowNavButton, (index, el) => {
el.addEventListener('click', function() {
let isActive = this.classList.contains('active');
if (!isActive) {
clearTimeout(timer);
slideshowClick($slideShow, this);
slideshowAnimations($slideShow, index);
slideTimer();
}
});
});
I use the forEach function as a for loop to go through all the elements I need, like having multiple $slideShow's on the page, and return them as an indexed array. The issue I am having is that I need to add a functionality in which the $slideshowNav and all the $slideshowNavButtons get removed and rebuilt from a function outside of the $slideshow function and can't figure out how to rebind the click event without repeating all of the code. Is there a way to bind this event to the $slideshow object, similar to the way jQuery's .on function works or rebind the click event to the new $slideshowNavButton's after they are created? I am not able to use jQuery so I can't use the .on function.
its hard to give you correct answer since you motion too many classes without visual placement but hope this helps:
var btnWraper = document.querySelectorAll('.btnWraper > button');
btnWraper.forEach(function(e){
e.onclick = buttonClicking;;
})
let remake = document.getElementById('reMakeMe');
remake.addEventListener('click', function(){
var btnWraper = document.querySelectorAll('.btnWraper > button');
//if deleted
if(!btnWraper.length)
{
createButtons('Btn1');
createButtons('Btn2');
createButtons('Btn3');
createButtons('Btn4');
}
},false)
let rest = document.getElementById('resetMe');
rest.addEventListener('click', function(){
var btnWraper = document.querySelectorAll('.btnWraper > button');
btnWraper.forEach(function(e){
e.remove();
})
},false) ;
function buttonClicking (){
alert(this.innerHTML);
}
function createButtons(value){
var btn = document.createElement("button");
btn.innerHTML = value;
btn.onclick = buttonClicking;
var parentElement = document.getElementsByClassName("btnWraper")[0];
parentElement.appendChild(btn);
}
<div class="btnWraper">
<button>Btn1</button>
<button>Btn2</button>
<button>Btn3</button>
<button>Btn4</button>
</div>
<div>
<button id="resetMe">Reset All</button>
<button id="reMakeMe">ReMake All</button>
</div>
var btn = document.querySelectorAll('.button');
function test() {
alert('hello')
}
btn.addEventListener("click", test);
After clicking on the "button" - test function should be called, bit it's not.
'.button' will search for all elements with class named 'button'. If you are searching for button elements you should write: document.querySelectorAll('button')
Additionally querySelectorAll gives nodeList.
For this code:
<button id="myBtn">Try it</button>
<button id="myBtn2">Try it</button>
<script>
var btn = document.querySelectorAll('button');
console.log(btn);
</script>
return will be NodeList[button#myBtn, button#myBtn2], as you can see it is an array.
document.querySelectorAll would return the list of elements. You need
to apply the click event on individual elements.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
var btn = document.querySelectorAll('.button');
console.log(btn[0]);
function test() {
alert('hello')
}
btn[0].addEventListener("click", test);
<div class = 'button'>Button</div>
I have several buttons in my WinJS page.
<button id="btn1">
Button 1
</button>
<button id="btn2"">
button 2
</button>...
and javascript to add click event to clicked button:
(function () {
WinJS.UI.processAll().done(function () {
var showButton = document.querySelector("xxx");
showButton.addEventListener("click", function () {
});
});
})();
How do i determine what button is clicked and set value of "xxx" to id of that button (btn1, btn2 etc...)
If I understood you correctly, you want to identify the button (sender) when you have multiple buttons that are attached to a single event handler.
MSDN:
In JavaScript, Windows Runtime event arguments are represented as a
single event object. In the following example of an event handler
method, the ev parameter is an object that contains both the sender
(the target property) and the other event arguments. The event
arguments are the ones that are documented for each event.
So you need to define an argument for the event handler and use its target property.
Let's say you have the following HTML:
<div id="label1"/>
<div>
<button id="button1">Button1</button><br />
<button id="button2">Button2</button><br />
<button id="button3">Button3</button><br />
</div>
and attached a single event handler to all of the buttons:
var button1 = document.getElementById("button1");
button1.addEventListener("click", buttonClickHandler);
var button2 = document.getElementById("button2");
button2.addEventListener("click", buttonClickHandler);
var button3 = document.getElementById("button3");
button3.addEventListener("click", buttonClickHandler);
you can access to sender in this way:
function buttonClickHandler(eventInfo) {
var clickedButton = eventInfo.target;
var label1 = document.getElementById("label1");
label1.innerHTML = clickedButton.id.toString();
}
Here's a WinJS solution to get the buttons :
var buttons = WinJS.Utilities.query('button');
Then you can bind the event to the buttons click :
buttons.forEach(function (btn) {
btn.addEventListener("click", function () {
console.log('button ' + this.id + ' has been clicked.');
})
});
I am new to WinJS, so there is probably a prettier solution to replace the forEach.
Something like this should work. querySelector only returns the first match, so you need to use querySelectorAll (see docs).
var buttons = document.querySelectorAll("button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", function () {
var id = this.id;
// do stuff with "id"
});
}
You might also consider looking into jQuery as that can make things like this a little bit cleaner.
The text "Now I'm here..." is supposed to disappear when the button is clicked, not the button itself.
<div id="alpha">Now I'm here...</div>
<button type="button" onclick="remove()">Remove</button>
<script>
function remove()
{
var element = document.getElementById("alpha");
element.parentNode.removeChild(element);
}
/*function add()
{
var ele = document.createElement("p");
var text = document.createTextNode("This is new text");
ele.appendChild(text);
var location = document.getElementById("alpha");
location.appendChild(ele);
}*/
</script>
There is another function called remove that is interfering with your function.
Rename your function and it works fine:
http://jsfiddle.net/fL3gZ/
<div id="alpha">Now I'm here...</div>
<button type="button" onclick="Myremove()">Remove</button>
<script>
function Myremove()
{
var element = document.getElementById("alpha");
element.parentNode.removeChild(element);
}
</script>
What's happening is remove() is being called on the button itself! HTMLElement.prototype.remove is an existing function (in some browsers)! Oh god!
var button = document.getElementsByTagName("button")[0];
// surprise! this is what's actually happening
button.remove();
Check out this alternative approach. See: fiddle
Change HTML to
<div id="alpha">Now I'm here...</div>
<button type="button">Remove</button>
Then use this JavaScript
function remove(id) {
var elem = document.getElementById(id);
if (elem) elem.parentNode.removeChild(elem);
}
var button = document.getElementsByTagName("button")[0];
button.addEventListener("click", function(event) {
remove("alpha");
event.preventDefault();
});
A couple things about this:
I'm favoring a more unobtrusive approach
The remove function is single purpose, and reusable
It will work in more browsers
You won't run into WTFs like you just experienced
remove() is already an excisting javascript method, so you are actually calling that method on your button instead of calling the function.
Just rename the function and it will be fine.
Fiddle: http://jsfiddle.net/WkUqT/7/
function removeText()
{
var element = document.getElementById("alpha");
element.parentNode.removeChild(element);
}
You are probably using chrome as your browser to test that code. Elements in chrome have a self-removal, .remove() method which removes the element itself from its container.
This is the main reason why the code above removes the button, because of this the appended event in your onclick() declaration was not invoked because the element invoking the event does not exist anymore. Try changing the name of your function to removeElement().
First, I would have created this example in JSFiddle but they are in read-only mode.
I would like to get the specific element that was clicked based on a class.
var button = document.getElementsByClassName("mybutton");
button.onclick = function() {
//how do I reference the specific button that was clicked?
};
<button class="myclass">Button 1</button>
<button class="myclass">Button 2</button>
No jQuery answers please; that is not an option here.
it's not document.getElementByClassName, it's document.getElementsByClassName.
See the difference yet?
It's easy to overlook:
document.getElementByClassName
document.getElementsByClassName
^
The former doesn't exist unless you define it, the latter only works in modern browsers. getElementsByClassName will return a node list, which you need to iterate over to attach event listeners to each node.
var i,
l,
buttons,
button;
function clickHandler(e) {
console.log(this);//the button that was clicked on
}
buttons = document.getElementsByClassName('mybutton');
for (i = 0, l = buttons.length; i < l; i++) {
button = buttons[i];
button.onclick = clickHandler;
}
The first argument in your event handler will be a reference to the event
var button = document.getElementByClassName("mybutton");
button.onclick = function(e) {
//e.Target is a reference to your button
};