0

an existent (pure) javascript function doesn't work with a new html element (created after that function):

document.querySelector('li').onmouseover = function() {
  document.querySelector("li").innerHTML ="Hai soffermato il mouse qui!";
}

document.querySelector('li').onmouseout = function() {
  document.querySelector("li").innerHTML ="Sofferma il mouse qui";
}

document.getElementById('bottone1').onclick = function() {
  var Lista = document.getElementById('lista');
  var NuovoElemento = document.createElement('li');
  NuovoElemento.innerText = 'Nuova voce'; // innerHTML
  Lista.insertBefore(NuovoElemento, Lista.lastChild);
}
<p><b>Elenco puntato:</b></p>
<ol id="lista">
  <li>Sofferma il mouse qui</li>
</ol>
<button id="bottone1">Aggiungi voce</button>

It's right so (but not good, imho), I know. But, sorry, I don't understand this thread, that solves the problem (widthout explains it) :-( Javascript function doesn't work when creating a new HTML element

Thanks (more solito).

Community
  • 1
  • 1
  • What is your question? – sidanmor Oct 29 '16 at 15:11
  • @sidanmor, If there was a code more self-explaining than that I linked, I would be happy :-) –  Oct 29 '16 at 15:15
  • I believe you are looking for event delegation. Check out these answers: http://stackoverflow.com/questions/24117369/vanilla-js-event-delegation-dealing-with-child-elements-of-the-target-element and/or http://stackoverflow.com/questions/23508221/vanilla-javascript-event-delegation – JonSG Oct 29 '16 at 15:15
  • Note: Your current code doesn't work as expected to start with. When hovering a list item, it won't change the text of that specific item, but the first list item instead. Also, the events are bound only to the first list item, not all items in the list. You don't see these problems as there is currently only one item in the list. – Guffa Oct 29 '16 at 15:21

2 Answers2

2

You can solve this by applying the concept of event delegation. This means you listen to mouse events on the parent element instead of on the li elements. To make this possible, you need to consult the event object that is passed to the callback function, and check that the original element on which the mouse event originated, was indeed an li element:

document.getElementById('lista').onmouseover = function(e) {
  if (e.target.tagName !== 'LI') return false;
  e.target.textContent ="Hai soffermato il mouse qui!";
}

document.getElementById('lista').onmouseout = function(e) {
  if (e.target.tagName !== 'LI') return false;
  e.target.textContent ="Sofferma il mouse qui";
}

document.getElementById('bottone1').onclick = function() {
  var Lista = document.getElementById('lista');
  var NuovoElemento = document.createElement('li');
  NuovoElemento.textContent = 'Nuova voce';
  Lista.insertBefore(NuovoElemento, Lista.lastChild);
}
<p><b>Elenco puntato:</b></p>
<ol id="lista">
  <li>Sofferma il mouse qui</li>
</ol>
<button id="bottone1">Aggiungi voce</button>

Note that I also introduced the use of the textContent property which is to be favored above innerHTML when assigning plain text, to avoid side-effects that some strings otherwise could have (with < and & in them).

trincot
  • 317,000
  • 35
  • 244
  • 286
0

Replace lastChild with lastElementChild it should work

check the following snippet

window.onload = function() {

  document.querySelector('li').onmouseover = function() {
    document.querySelector("li").innerHTML = "Hai soffermato il mouse qui!";
  }

  document.querySelector('li').onmouseout = function() {
    document.querySelector("li").innerHTML = "Sofferma il mouse qui";
  }

  document.getElementById('bottone1').onclick = function() {
    var Lista = document.getElementById('lista');
    var NuovoElemento = document.createElement('li');
    NuovoElemento.innerText = 'Nuova voce1'; // innerHTML
    Lista.insertBefore(NuovoElemento, Lista.lastElementChild);
  }
}
<p><b>Elenco puntato:</b>
</p>
<ol id="lista">
  <li>Sofferma il mouse qui</li>
</ol>
<button id="bottone1">Aggiungi voce</button>

Hope this helps

Geeky
  • 7,420
  • 2
  • 24
  • 50