Reputation:
var checklist = document.getElementById("my-ul");
var items = checklist.querySelectorAll("a");
console.log(checklist);
console.log(items);
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", returnLetter);
}
function returnLetter() {
alert(items.innerHTML);
}
<ul id="my-ul" class="pager">
<li><a href="#">A</a>
</li>
<li><a href="#">B</a>
</li>
<li><a href="#">C</a>
</li>
<li><a href="#">D</a>
</li>
<li><a href="#">E</a>
</li>
<li><a href="#">F</a>
</li>
<li><a href="#">G</a>
</li>
<li><a href="#">H</a>
</li>
<li><a href="#">I</a>
</li>
</ul>
My javascript seems to not return anything, the alert prints out 'undefined', but I can't figure out where my problem is. My goal is to return the letter corresponding to the button/link the user has clicked.
Upvotes: 2
Views: 118
Reputation: 241088
It's returning undefined
because .querySelectorAll()
returns a NodeList and items
is a NodeList, which means that it doesn't have a innerHTML
property. You need to access the property of an element in the NodeList.
You can pass the index of the clicked element:
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", returnLetter.bind(items[i], i));
}
function returnLetter(i) {
console.log(items[i].textContent);
}
However, a better option would be to use the this
keyword to get a reference to the element the event occurred on. I'd also suggest using the .textContent
property:
function returnLetter() {
console.log(this.textContent);
}
As a side note, you could also just attach a single event listener to the parent ul
element, then access event.target
to get a reference to the clicked a
element:
checklist.addEventListener("click", returnLetter);
function returnLetter(e) {
if (e.target.tagName === 'A') {
alert(e.target.textContent);
}
}
Upvotes: 2
Reputation: 17371
Right now, your returnLetter()
function is trying to print out the innerHTML
s of every item
. To fix this, only alert the innerHTML
of that item by passing that item to the function, like so:
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", alertValue);
}
function alertValue() {
alert(this.innerHTML);
});
The this
in the event handler function will point to the element that is being clicked on (calling the event handler), instead of pointing to the items
array.
See working example at JSFiddle.net.
Upvotes: 2
Reputation:
You need to use this
on the event listener. For instance, your code could be rewritten as
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", clickCallback);
}
function clickCallback() {
alert(this.innerHTML);
}
Upvotes: 2
Reputation: 36703
You should use this.innerHTML
as this
points to the clicked element.
var checklist = document.getElementById("my-ul");
var items = checklist.querySelectorAll("a");
console.log(checklist);
console.log(items);
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", returnLetter);
}
function returnLetter() {
alert(this.innerHTML);
}
<ul id="my-ul" class="pager">
<li><a href="#">A</a>
</li>
<li><a href="#">B</a>
</li>
<li><a href="#">C</a>
</li>
<li><a href="#">D</a>
</li>
<li><a href="#">E</a>
</li>
<li><a href="#">F</a>
</li>
<li><a href="#">G</a>
</li>
<li><a href="#">H</a>
</li>
<li><a href="#">I</a>
</li>
</ul>
Upvotes: 1