SamFlynn SamFlynn - 1 month ago 9
HTML Question

A Function doesn't work with setTimeout

So the page loads, however a part of the page is fetched from the server, which loads up later, so I set up a setTimeout function, however after doing this the error comes up

Uncaught reference error: check is not defined


I also moved check function outside the
setTimeout
still no luck

When this is pasted without the timeout function in the developer console everything, the check function works fine.

setTimeout(function() {


var getclass = document.getElementsByClassName('title');
var containerlength = getclass.length;

for (var i = 0; i < containerlength; i++) {
var container = getclass[i];
var jobid = getclass[i].children[0].innerHTML.trim().substring(0, 5);
var fragment = document.createElement('div');
var chk = "";
if (localStorage.getItem(jobid) == 1) {
chk = "checked";
getclass[i].style.textDecoration = 'line-through';
}
fragment.innerHTML = '<input onclick="check(this)" class="jobs" value="' + jobid + '" name="' + jobid + '" type="checkbox"' + chk + '></input>';
container.appendChild(fragment);

}

function check(ele) {
// alert(ele.name);
var name = ele.name;
var papa = ele.parentNode.parentNode;
if (localStorage.getItem(name) == 1) {
localStorage.setItem(name, 0);
papa.style.textDecoration = 'none';
} else {
localStorage.setItem(name, 1);
papa.style.textDecoration = 'line-through';
}
}


}, 5000);

Answer

Because you're trying to refer to a global check function, but not the local check.

With the current way you build the input element inside the loop you can't set its click event to check (or to use check) directly.

If you build the input element with document.createElement(), you can use the return's HTML element reference in order to directly set its click event to use check:

var input = document.createElement('input');
// Function#bind just wraps a function
// with instance and arguments pre-defined to a call
input.addEventListener('click', check.bind(null, input), false);
// or the event can be set through the 'HTMLElement#onclick' setter

fragment.appendChild(input);

Here's an example of implementation in your code:

function check(ele) {
  var name = ele.name;
  var papa = ele.parentNode.parentNode;

  if (localStorage.getItem(name) === 1) {
    localStorage.setItem(name, 0);
    papa.style.textDecoration = 'none';

  } else {
    localStorage.setItem(name, 1);
    papa.style.textDecoration = 'line-through';
  }
}

setTimeout(function() {
  var getclass = document.getElementsByClassName('title');
  var containerlength = getclass.length;

  for (var i = 0; i < containerlength; i++) {
    var container = getclass[i];
    var jobid = getclass[i].children[0].innerHTML.trim().substring(0, 5);
    var fragment = document.createElement('div');
    var chk = "";

    if (localStorage.getItem(jobid) === 1) {
      chk = "checked";
      getclass[i].style.textDecoration = 'line-through';
    }

    var input = document.createElement('input');

    input.addEventListener('click', check.bind(null, input), false);
    input.class = "jobs";
    input.value =
    input.name = jobid;
    input.type = "checkbox";

    fragment.appendChild(input);
    container.appendChild(fragment);

  }
}, 5000);