user5179813
user5179813

Reputation:

How can return the innerHTML inside my <a> tag?

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

Answers (4)

Josh Crozier
Josh Crozier

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:

Example Here

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:

Example Here

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:

Example Here

checklist.addEventListener("click", returnLetter);

function returnLetter(e) {
  if (e.target.tagName === 'A') {
    alert(e.target.textContent);
  }
}

Upvotes: 2

Jonathan Lam
Jonathan Lam

Reputation: 17371

Right now, your returnLetter() function is trying to print out the innerHTMLs 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

user147373
user147373

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

void
void

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

Related Questions