Attaching a click event to multiple elements at once? [duplicate] - javascript

This question already has answers here:
Javascript click event listener on multiple elements and get target ID
(7 answers)
Closed 7 years ago.
Here is my code in jQuery:
$('.paragraph, .section, .heading').on('input', function (e) {
localStorage.setItem($(this).attr('id'), $(this).text());
});
Is there any JavaScript equivalent where I could attach all events at once?

You could use querySelectorAll with your multiple element selectors, then add the event listeners to each one
var elements = document.querySelectorAll(".a, .b");
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener("click", function() {
console.log("clicked");
});
}

Suppose you want to add click event to multiple elements, then set their class name as for example demo
demos= document.getElementsByClassName('demo');
for (var i = 0; i < demos.length; i++) {
demos[i].addEventListener('click',redirect,false);
}
function redirect(){
alert(this.id);
}
WORKING FIDDLE

Credit goes to:
Javascript click event listener on multiple elements and get target ID
articles = document.getElementsByTagName('button');
for (var i = 0; i < articles.length; i++) {
articles[i].addEventListener('click',redirect,false);
}
function redirect(){
alert(this);
}
<button></button>
<button></button>

Read Jquery Multiple Selector
$( "div, span, p.myClass" ).css( "border", "3px solid red" );
div, span, p {
width: 126px;
height: 60px;
float: left;
padding: 3px;
margin: 2px;
background-color: #eee;
font-size: 14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div>div</div>
<p class="myClass">p class="myClass"</p>
<p class="notMyClass">p class="notMyClass"</p>
<span>span</span>

Related

how can i make onclick to all the elments? [duplicate]

This question already has answers here:
Attach event handlers for click event on all elements in the DOM
(5 answers)
Closed 3 years ago.
i try to make onclick event to all the decomnt that give me back the elment id that i click on .
thank you
i tried to you the parent id
document.getElementById("parent").onclick = function(){btnIsClicked(this.id)};
this work but give me the parent id not the clicked one..
document.getElementById(*).onclick = function(){btnIsClicked(this.id)};
function btnIsClicked(id){
console.log(id);
}
please i need some thing like * to make it for all but in same time give me the id of the clicked elment (not the just the parent one)
You can add the event listener to the document and access the element that was clicked as event.target
document.addEventListener('click', (event) => {
console.log(event.target.id);
})
.box {
width: 50px;
height: 50px;
background-color: lightblue;
margin: 10px;
display: inline-block;
}
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
<div id="box3" class="box"></div>
You can attach an event listener to the document body.
document.getElementsByTagName('body')[0].onclick = function(e) {console.log(e.target.id)};
You can use querySelectorAll and addEventListener for achive this.
const elements = document.querySelectorAll('*');
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
element.addEventListener('click', e => {
e.stopPropagation();
btnIsClicked(e.target.id);
});
}
function btnIsClicked(id) {
console.log(id);
}
div {
display: inline-block;
width: 100px;
height: 100px;
}
#element-one {
background: blue;
}
#element-two {
background: red;
}
<div id="element-one"></div>
<div id="element-two"></div>
A possible approach using querySelectorAll and stopPropagation() to get the exact element clicked.
[...document.querySelectorAll("*")].forEach(em => {
em.addEventListener("click", (e) => {
e.stopPropagation();
console.log(e.target)
})
});
<h1>title</h1>
<div>text inside div
<span>text inside span</span>
</div>

Cant call function after creating element. jQuery

So my target is to run a function when click on "li" but number of li depends from user choice...
Function work when i create exactly amount of li elements...
$("li").click(function(){
var e = $(this).attr("id");
alert(e);});
li{
border: 1px solid black;
cursor: pointer;
display: inline-block;
padding:5px 10px 5px 10px;
}
ul{
display: inline-block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="questlist">
<li id='quest1'>1</li>
<li id='quest2'>2</li>
<li id='quest3'>3</li>
<li id='quest4'>4</li>
<li id='quest5'>5</li>
<li id='quest6'>6</li>
<li id='quest7'>7</li>
<li id='quest8'>8</li>
<li id='quest9'>9</li>
<li id='quest10'>10</li>
</ul>
But when i would like to create list from user choice i cant run function already try:
function countList(ListX){
for(k=0;k<ListX; k++){
ke = k+1;
node = document.createElement("LI");
node.setAttribute("id", "quest"+ke);
textnode = document.createTextNode(ke);
node.appendChild(textnode);
document.getElementById("questlist").appendChild(node);
}}
and
function countList(ListX){
for(k=0;k<ListX; k++){
ke = k+1;
document.getElementById("questlist").innerHTML += "<li id='quest"+ke+"'>"+ke+"</li>";
}}
var ListX = 10;
function countList(ListX){
for(k=0;k<ListX; k++){
ke = k+1;
node = document.createElement("LI");
node.setAttribute("id", "quest"+ke);
textnode = document.createTextNode(ke);
node.appendChild(textnode);
document.getElementById("questlist").appendChild(node);
}}
countList(ListX);
$("li").click(function(){
var e = $(this).attr("id");
alert(e);});
li{
border: 1px solid black;
cursor: pointer;
display: inline-block;
padding:5px 10px 5px 10px;
}
ul{
display: inline-block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="questlist"></ul>
Both of function create me "li" elements with expected id, or at least after i open a console and analyze each "li" element i can see expected id.
Need
Use the on method instead of click handler on li element, like this
$('body').on('click', 'li', function() {
var e = $(this).attr("id");
alert(e);
});
Rest of your code is fine, just use above code instead of $("li").click..
Working Demo here
The official documentation says:
Event handlers are bound only to the currently selected elements; they
must exist at the time your code makes the call to .on()
What you need is to make sure the actual element exist at the time you attaching the event. So if your li tags doesn't exist at the time of attaching event, the .click() method will fail. You next choice is to bind the event on one of the parents (in your case it would be the UL tag, like so:
$("#questlist").on("click", "li", function() {
var e = $(this).attr("id");
alert(e);
})
Also from now on use .on() method, it attaches event handlers to a selected set of elements and it works perfectly for elements present on the page.

javascript don't .toggleClass() if clicked again?

I've put this in the simplest terms for this question.
if element is clicked, 'active' class is added to element, 'active' class is removed from other elements.
However, if the element is 'active' and it's clicked for a second time the 'active' class should not be "re-applied" (or called for a second time).
$(".class").click(function(){
$('.class').not(this).removeClass('active');
$(this).addClass('active');
}
For example when button 1 is clicked and has the 'active' class -> doFunction;
if ( $(".active").is("#1") ) {
doFunction();
}
when it's clicked again, a second time, the function is fired again even though the element is already 'active'. If the element is active and is clicked a second time I don't want to call the functions again. How can I achieve this?
Codepen Example: https://codepen.io/anon/pen/yvZXOB?editors=1111
Thanks!
Since you didn't specify exactly how you want to limit the functions from being called, let's look at two possibilities.
First possibility: each button you can click to activate and call some function at most one time. After that, toggling buttons will toggle the classes but not calling the other function again.
In this scenario, you can use jQuery's .one().
$(".class").one('click', function(){
$('.class').not(this).removeClass('active');
$(this).addClass('active');
if ( $(".active").is("#1") ) {
doFunction();
}
if ( $(".active").is("#2") ) {
doFunction();
}
function doFunction() {
console.log("function fired!");
}
});
.class {
padding: 10px;
border-radius: 5px;
background: #392;
width: 100px;
color: white;
text-align: center;
margin: 25px;
display: inline-block;
cursor: pointer;
}
.active {
background: #932;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="class" id="1">
button
</div>
<div class="class" id="2">
another
</div>
Second possibility: when you click between buttons, the active state is toggled, but clicking a button that's already active won't keep running the other function. However, toggling away from a button and back to it will allow that button's function to run again.
In this case, you can set some kind of flag via a variable and then check the flag to see if you're allowed to run the other function again. Function runs, flag goes up. Different button gets clicked, flag goes back down.
var preventFunction;
$(".class").on('click', function(){
if($(this).hasClass('active')) {
preventFunction = true;
} else {
preventFunction = false;
}
$('.class').not(this).removeClass('active');
$(this).addClass('active');
if ( $(".active").is("#1") ) {
if(preventFunction !== true) {
doFunctionOne();
}
}
if ( $(".active").is("#2") ) {
if(preventFunction !== true) {
doFunctionTwo();
}
}
});
function doFunctionOne() {
console.log("function one fired!");
preventFunctiong = true;
}
function doFunctionTwo() {
console.log("function two fired!");
preventFunction = true;
}
.class {
padding: 10px;
border-radius: 5px;
background: #392;
width: 100px;
color: white;
text-align: center;
margin: 25px;
display: inline-block;
cursor: pointer;
}
.active {
background: #932;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="class" id="1">
button
</div>
<div class="class" id="2">
another
</div>
Since you are dynamically adding/removing classes, the correct apporach is to use event delegation like this:
$(document).on('click', ".class:not(.active)", function(){
$('.class').removeClass('active');
$(this).addClass('active');
console.log("click triggered!");
})
https://codepen.io/connexo/pen/PQVKNY?editors=1111
This trick will work(just use one global variable and hold the last active item's id),
var last_act_id = 0;
$(".class").click(function(){
if($(this).attr('id') != last_act_id) {
last_act_id = $(this).attr('id');
$('.class').removeClass('active');
$(this).addClass('active');
doFunction();
}
function doFunction() {
console.log("function fired!");
}
});
Demo: https://codepen.io/anon/pen/Nyovjr?editors=0001
Just check to see if that event target has the class already. Since you're using jQuery you could do something like
if($('.selector').hasClass('active')) {
$('.selector').removeClass('active')
} else {
$('.selector').addClass('active')
}
Try this
$("#1").click(function(){
$('#2').removeClass('active');
if (!$("#1").hasClass('active')) {
$("#1").addClass('active');
doFunction();
}else{
console.log("already clicked");
}
});
$("#2").click(function(){
$('#1').removeClass('active');
if (!$("#2").hasClass('active')) {
$("#2").addClass('active');
doFunction();
}else{
console.log("already clicked");
}
});
function doFunction() {
console.log("function fired!");
}
I hope it helps

give an onclick function to be executed to every element with a certain class

How would i go about making something like this - i have multiple elements with a certain class and i would like this to happen:
element1 - onclick fires someFunction(13);
element2 - onclick fires someFunction(27);
element3 - onclick fires someFunction(81);
i am loading these elements in dynamically so i can't put it manually into my js file. I also can't give them an onclick as i load them with php.
I am looking for a purely js answer so please no jQuery.
function setMyHandler(){
var elements = document.getElementsByClassName('someClass');
for(var i = 0; i < elements.length; i++){
elements[i].onclick = function(){};
}
}
But I would be better advised to use you event delegate. Set Handler on root element. And checking event.target. http://javascript.info/tutorial/event-delegation
Approach #1
In your PHP code, create your elements with onclick tags, with intended input into the function.
<div class="someclass" onclick="someFunction(1)"></div>
Approach #2
When the page loads, iterate through all elements with your given classname and attach listeners to them. For this approach to work, the divs must have the numbers which will be entered in SomeFunction included in arbitrary tags.
<div data="13" > =) </div>
window.onload = function() {
for (var i =0; i < document.getElementsByClassName("classname").; i++){
var Div = document.getElementsByClassName("classname")[i];
Div.addEventListener("click", function(){
someFunction(Div.data);
});
}
}
You can delegate events by attaching event listener to parent element. To get the target element you can use event.target
Here's the sample code how you can achieve it:
var parentElement = document.querySelector("#parent");
parentElement.addEventListener("click", function () {
var currentTarget = event.target;
if (currentTarget.tagName === "LI") { // If you want LI to be clickable
currentTarget.style.backgroundColor = "#eee";
currentTarget.style.color = "#606060";
}
});
Here's the jsfiddle for the same: https://jsfiddle.net/dx8Lye29/
The simplest way of doing this is giving the elements a data-attribute with the parameter for the function you want to run:
<div class="someclass" data-parameter="12">
<div class="someclass" data-parameter="13">
<div class="someclass" data-parameter="14">
and then run this:
function setMyHandler(){
var elements = document.getElementsByClassName('someclass');
for(var i = 0; i < elements.length; i++){
elements[i].onclick = function(){ myFunction(this.data.parameter); };
}
}
Here is a link for data attributes: data attributes
And here is a snipplet to see the simple version of it in action:
function setMyHandler(){
var elements = document.getElementsByClassName('someclass');
for(var i = 0; i < elements.length; i++){
elements[i].onclick = function(){window.alert(this.dataset.somevalue);};
}
}
setMyHandler();
body {
display: flex;
justify-content: center;
}
div.someclass {
margin: 2%;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
background: #80bfff;
box-shadow: 0px 2px 6px 0px rgba(0,0,0,0.7);
transition: background 0.3s ease;
}
div.someclass:hover {
background: #3399ff;
}
<div class="someclass" data-somevalue="13"> </div>
<div class="someclass" data-somevalue="14"> </div>
<div class="someclass" data-somevalue="15"> </div>

Change CSS value by javascript for whole document

I want on ajax call change the values loaded from CSS file, it means not only for one element like:
document.getElementById("something").style.backgroundColor="<?php echo "red"; ?>";
but similar script which is change the css value generally, not only for element by ID, idealy like background color for CSS CLASS divforchangecolor:
CSS:
.divforchangecolor{
display: block;
margin: 20px 0px 0px 0px;
padding: 0px;
background-color: blue;
}
HTML:
<div class="divforchangecolor"><ul><li>something i want to style</li><ul></div>
<div class="divforchangecolor">not important</div>
<div class="divforchangecolor"><ul><li>something i want to style</li><ul></div>
<div class="divforchangecolor">not improtant</div>
Ideal solution for me:
onclick="--change CSS value divforchangecolor.backgroundColor=red--"
but i need to change CSS to reach .divforchangecolor ul li and .divforchangecolor ul li:hover
If you can't just apply the classname to these elements. You could add a new selector to your page. The following vanilla JS would be able to do that (jsFiddle).
function applyDynamicStyle(css) {
var styleTag = document.createElement('style');
var dynamicStyleCss = document.createTextNode(css);
styleTag.appendChild(dynamicStyleCss);
var header = document.getElementsByTagName('head')[0];
header.appendChild(styleTag);
};
applyDynamicStyle('.divforchangecolor { color: pink; }');
Just adapt the thought behind this and make it bullet proof.
var elements=document.getElementsByClassName("divforchangecolor");
for(var i=0;i<elements.length;i++){
elements[i].style.backgroundColor="red";
}
var e = document.getElementsByClassName('divforchangecolor');
for (var i = 0; i < e.length; i++) e[i].style.backgroundColor = 'red';
Use getElementByClassName() and iterate over the array returned to achieve this
You can select elements by class with document.getElementsByClassName or by css selector (includes class) with document.querySelectorAll().
Here are two approaches, for example: Live demo here (click).
Markup:
<div class="divforchangecolor"></div>
<div class="divforchangecolor"></div>
<div class="divforchangecolor"></div>
<div class="divforchangecolor"></div>
<div class="some-container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
JavaScript:
var toChange = document.getElementsByClassName('divforchangecolor');
for (var i=0; i<toChange.length; ++i) {
toChange[i].style.backgroundColor = 'green';
}
var toChange2 = document.querySelectorAll('.some-container > div');
for (var i=0; i<toChange.length; ++i) {
toChange2[i].style.backgroundColor = 'red';
}
I recommend the second solution if it is possible in your case, as the markup is much cleaner. You don't need to specifically wrap the elements in a parent - elements already have a parent (the body, for example).
Another option is to have the background color you want to change to in a css class, then you can change the class on your elements (and therefore the style changes), rather than changing the css directly. That is also good practice, as it lets you keep your styles all in css files, while js is just manipulating which one is used.
On the whole document your approach can be a bit different:
ajax call
call a function when done
conditionally set a class on the body like <body class='mycondition'></body>
CSS will take care of the rest .mycondition .someclass: color: red;
This approach will be more performant than using JavaScript to change CSS on a bunch of elements.
You can leverage CSS selectors for that:
.forchangecolor {
display: block;
margin: 20px 0px 0px 0px;
padding: 0px;
background-color: blue;
}
.red-divs .forchangecolor {
background-color: red;
}
Then, with javascript, add the red-divs class to a parent element (could be the <body>, for example), when one of the divs is clicked:
document.addEventListener("click", function(event) {
var target = event.target;
var isDiv = target.className.indexOf("forchangecolor") >= 0;
if(isDiv) {
document.body.classList.add("red-divs");
}
});
Working example: http://jsbin.com/oMIjASI/1/edit

Categories