I am practicing DOM Scripting (no real-life problem but rather practice and theory, I know how to achieve this with jQuery of course) So, I am trying to improve and understand the following:
I have some links with classes and I am attaching event on them:
<a href="" class="popup">click</a>
<a href="" class="popup">click2</a>
<a href="" class="popup">click3</a>
<a href="" class="no">click4</a>
Javascript:
window.onload = prepareLinks;
function prepareLinks() {
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
if (links[i].getAttribute("class") == "popup") {
links[i].onclick = function () {
popUp(this.getAttribute("href"));
return false;
}
}
}
}
function popUp(winURL) {
window.open(winURL, "popup", "width=320,height=480");
}
That works fine. I got it from a book basically. Now I want to improve it by making use of getElementsByClassName. I went on to write:
window.onload = prepareLinks;
function prepareLinks() {
var links = document.getElementsByTagName("a");
var popups = links.getElementsByClassName("popup");
for (var i = 0; i < popups.length; i++) {
popups[i].onclick = function () {
popUp(this.getAttribute("href"));
return false;
}
}
}
function popUp(winURL) {
window.open(winURL, "popup", "width=320,height=480");
}
But I got error: Uncaught TypeError: Object # has no method 'getElementsByClassName'
Apparently links is a NodeList so I can't use the getElementsByClassName on it. Which I don't really understand... Can you help on how I could do this, and whether or not the first version of the script is good? (performance wise). Thanks.
I am practicing DOM Scripting (no real-life problem but rather practice and theory, I know how to achieve this with jQuery of course) So, I am trying to improve and understand the following:
I have some links with classes and I am attaching event on them:
<a href="http://www.google." class="popup">click</a>
<a href="http://www.test." class="popup">click2</a>
<a href="http://www.abc." class="popup">click3</a>
<a href="http://www.google." class="no">click4</a>
Javascript:
window.onload = prepareLinks;
function prepareLinks() {
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
if (links[i].getAttribute("class") == "popup") {
links[i].onclick = function () {
popUp(this.getAttribute("href"));
return false;
}
}
}
}
function popUp(winURL) {
window.open(winURL, "popup", "width=320,height=480");
}
That works fine. I got it from a book basically. Now I want to improve it by making use of getElementsByClassName. I went on to write:
window.onload = prepareLinks;
function prepareLinks() {
var links = document.getElementsByTagName("a");
var popups = links.getElementsByClassName("popup");
for (var i = 0; i < popups.length; i++) {
popups[i].onclick = function () {
popUp(this.getAttribute("href"));
return false;
}
}
}
function popUp(winURL) {
window.open(winURL, "popup", "width=320,height=480");
}
But I got error: Uncaught TypeError: Object # has no method 'getElementsByClassName'
Apparently links is a NodeList so I can't use the getElementsByClassName on it. Which I don't really understand... Can you help on how I could do this, and whether or not the first version of the script is good? (performance wise). Thanks.
Share Improve this question asked Oct 16, 2011 at 19:46 George KatsanosGeorge Katsanos 14.2k17 gold badges69 silver badges109 bronze badges 2-
links[i].getAttribute("class") == "popup"
won't work if the anchor has two or more classes. – Šime Vidas Commented Oct 16, 2011 at 20:32 -
If those
.popup
anchors have a mon ancestor, consider event delegation. Assigning an event handler for each anchor is something that you want to avoid. – Šime Vidas Commented Oct 16, 2011 at 20:34
2 Answers
Reset to default 6You can't use getElement* functions to filter each other like that, because they don't operate on lists, and they don't return the original node in their results anyway. If you need to filter on more than one condition simultaneously, use querySelectorAll
instead, e.g. document.querySelectorAll("a.popup")
.
The first version is fine, but you might see an improvement if you got the elements by class name first, then filtered them by tag name, if in fact you do even need them filtered by tag name. If the class popup
will only be used on links, getElementsByTagName
is unnecessary and your script will speed up if you remove it, of course.