Reputation: 27
I want to use a getElemendbyId function several times, just by passing the name of the ID as a variable.
I guess there is a more elegant way to do it than:
<div id="1" onclick="myFunction2()"></div>
<div id="2" onclick="myFunction3()"></div>
<div id="3" onclick="myFunction4()"></div>
<div id="4" onclick="myFunction5()"></div>
<script>
function myFunction2() { document.getElementById("2").innerHTML = "test2"; }
function myFunction3() { document.getElementById("3").innerHTML = "test3"; }
function myFunction4() { document.getElementById("4").innerHTML = "test4"; }
</script>
Thanks!
Upvotes: 1
Views: 88
Reputation: 43920
Event delegation is a pattern that optimizes event handling by registering an ancestor element of a group of descendant elements. By controlling what is ignored and what is triggered by an event, you can have a single element (ancestor in demo is <ul>
/ event.currentTarget
) listen for an event (click event in demo) for all of its descendant elements (all of the <li>
in demo event.target
).
Details are commented in demo
// Reference an ancestor element
var list = document.querySelector('ul');
// Register click event on ancestor element
list.onclick = clicker;
// Callback function pass the Event Object
function clicker(event) {
// Reference the clicked element (<li>...)
var clicked = event.target;
// Reference the element registered to the event (<ul>)
var ancestor = event.currentTarget;
// if the clicked element is NOT the registered element
if (clicked !== ancestor) {
// if the clicked element is an <li>...
if (clicked.matches('li')) {
// ...toggle the .on class
clicked.classList.toggle('on');
}
}
}
li {
cursor: pointer;
}
.on {
color: gold;
background: black;
}
<ul>
<li>ITEM 1</li>
<li>ITEM 2</li>
<li>ITEM 3</li>
<li>ITEM 4</li>
</ul>
Upvotes: 0
Reputation: 1666
Here is a solution without using Ids
function myFunction(el, content) {
el.innerHTML = content;
}
<div onclick="myFunction(this, 'test2')">Click Me</div>
<div onclick="myFunction(this, 'test3')">Click Me</div>
<div onclick="myFunction(this, 'test4')">Click Me</div>
<div onclick="myFunction(this, 'test5')">Click Me</div>
Upvotes: 0
Reputation: 5941
A more elegant solution than inline on<...>
event handlers is to call addEventListener
on the parent element (read about event delegation here). Once the listener is registered you can use the event
argument to determine what target the user has clicked and what action to be taken, if any.
For example, in the scenario below we evaluate the event
to determine if one of our <div>
elements were clicked - if so, call myFunction
with the appropriate data passed in:
document.addEventListener('click', handleClick)
function handleClick(event) {
if (event.target.tagName === 'DIV') {
myFunction(event.target);
}
}
function myFunction(el) {
el.innerHTML = `test${el.id}`;
}
<div id="1">Click Me</div>
<div id="2">Click Me</div>
<div id="3">Click Me</div>
<div id="4">Click Me</div>
Upvotes: 1
Reputation: 4116
You can use the getElementById
and addEventListener
functions. It looks like this
[1, 2, 3, 4].forEach(id => {
document.getElementById(id).addEventListener('click', () => {
const el = document.getElementById(id + 1);
if (el) el.innerHTML = `test${id+1}`;
});
});
<div id='1'>a</div>
<div id='2'>b</div>
<div id='3'>c</div>
<div id='4'>d</div>
Upvotes: 0
Reputation: 65796
There are a couple of ways to go about this, but in all scenarios you really should not use inline event handling attributes (onclick
). There are many reasons not to use this 20+ year old technique that just will not die the death it deserved to almost 10 years ago. Additionally, don't use .innerHTML
to get/set values that don't contain any HTML as it is wasteful, in terms of performance and it opens up security holes in your application. Instead, use .textContent
to get/set non-HTML values.
For each element to have its own handler:
// Get all the elements that need the same handler into an Array
let divs = Array.prototype.slice.call(document.querySelectorAll("div"));
// Iterate the array
divs.forEach(function(div){
// Set up the handler
div.addEventListener("click", function(){
div.textContent = "test" + div.id;
});
});
<div id="1">click me</div>
<div id="2">click me</div>
<div id="3">click me</div>
<div id="4">click me</div>
To set up just one handler and use event delegation:
// Set up an event handler on the container element
document.querySelector(".parent").addEventListener("click", function(event){
// Act upon the target of the event (the element that triggered the
// event in the first place).
event.target.textContent = "test" + event.target.id;
});
<div class="parent">
<div id="1">click me</div>
<div id="2">click me</div>
<div id="3">click me</div>
<div id="4">click me</div>
</div>
Upvotes: 1
Reputation: 1311
<div id="1" onclick="myFunction(2, 'test2')"></div>
<div id="2" onclick="myFunction(3, 'test3')"></div>
<div id="3" onclick="myFunction(4, 'test4')"></div>
<div id="4" onclick="myFunction(5, 'test5')"></div>
<script>
function myFunction(id, content) {
document.getElementById(id).innerHTML = content;
}
</script>
Upvotes: 3