Reputation:
I have a svg map and I am putting that into object and I am trying to create all path with id clickable.
For that I am doing this to get svg object :
let a = document.getElementById("biharsvg")
And I am putting that into svg doc like this:
var svgDoc = a.contentDocument;
And now I am getting all the values of certain class using this:
let de = svgDoc.getElementsByClassName("fil0");
I can also get the attribute id value using this:
var i;
for (i = 0; i < de.length; i++) {
var j = de[i].getAttribute("id");
console.log(j);
}
I want to add a click event on each attribute id and get the value when I am doing this:
var i;
for (i = 0; i < de.length; i++) {
var j = de[i].getAttribute("id");
console.log(j);
svgDoc.getElementById(j).onclick = function() {
modal.style.display = "block";
console.log(this.getAttribute("id"));
}
}
This is working fine and I am getting all the values but in jquery I can use this:
$(de).click(function(){
alert(this.getAttribute("id"));
});
Is there any way I can use something like this in javascript without loop. My question is what is the best possible way to make this work in javascript.
Upvotes: 0
Views: 1032
Reputation: 56740
I find for..of
to be the most convenient and readable syntax:
for (const element of svgDoc.getElementsByClassName("fil0")) {
console.log(element.id);
}
Upvotes: 0
Reputation:
I just want to show an alternative way, pointed out by CBroe, where a click on the document is checked for its event target:
let de = Array.from(mylist.getElementsByClassName("fil0"));
document.addEventListener('click', function(e) {
const el = e.target;
if (de.indexOf(el) < 0) return false;
alert(el.innerHTML);
});
<ul id="mylist">
<li>one</li>
<li class="fil0">two*</li>
<li class="fil0">three*</li>
</ul>
<p>* has click event assigned indirectly</p>
This has the additional benefit that it only uses a single handler function, and if the indexOf()
condition is changed to something like classList.contains()
, it will even work for elements that don't exist yet.
Upvotes: 0
Reputation: 87191
The javascript version for jQuery's
$(de).click(function(){
alert(this.getAttribute("id"));
});
would be something like
Array.from(de).forEach( function(el){
el.addEventListener('click', function() {
alert(this.getAttribute("id"));
// or "this.id" should work too
});
});
To be noted, when doing $(de).click(function(){...}
with jQuery, it also loops, internally.
And as commented, with arrow functions you could shorten the code even more
Array.from(de).forEach(el => el.addEventListener('click', function () {...}))
var de = document.querySelectorAll('span');
Array.from(de).forEach(el => el.addEventListener('click', function () {
alert(this.id);
}))
span {
display: inline-block;
padding: 20px;
margin: 0 5px;
border: 1px dotted black;
}
span::after {
content: attr(id)
}
<span id="nr1">click </span>
<span id="nr2">click </span>
<span id="nr3">click </span>
Updated based on a comment.
The main difference between your existing loop and the above is, the above is more efficient, with a cleaner/shorter code.
In your original loop
var i;
for (i = 0; i < de.length; i++) {
var j = de[i].getAttribute("id");
svgDoc.getElementById(j).onclick = function() {
modal.style.display = "block";
console.log(this.getAttribute("id"));
}
}
you iterate through the element array de
, get its id
and then make a new call using getElementById
to get the element you already have.
With the kept syntax/logic, your existing code could been simplified to something like this
for (var i = 0; i < de.length; i++) {
de.onclick = function() {
modal.style.display = "block";
console.log(this.getAttribute("id"));
}
}
Upvotes: 1