Mouseover event over multiple elements flickers

I’m stuck creating code that’s lean and want to use only JavaScript for now.

http://jsfiddle.net/TheOne_TheMany/30zdkrys

The problem I’m having is the mouseover state, when it goes over the <li> it works, but flickers when going over the <div> delete area. I know why it does that(After lots of research). So I tried mouseleave, but I need to have multiple ID on the <li> to make it work.

Is there a cleaner way of coding without creating so many ID or multiple event listeners. Specially if Im going to add more <li> or delete them.

Thanks in advance for the help.

Its not that complicated right now! You’re only using 3 listeners for each of those buttons which is pretty good. You’re not going to get a whole lot better as far as reducing those :wink:

It sounds like you kind of know whats going on. And using mouseenter/mouseleave is kind of what you want, but it doesn’t work with delegation (adding one event to a parent) - which basically the whole point of their existence. So if you want to keep using one listener for them all, you’ll want to stick to mouseover/mouseout, but you’ll need to do a better job of recovering when a mouseout happens. This means in ever mouseover, you need to see if the target is in the <li> not just being the <li>, and if so, restore the class then too. This way when you move the mouse over to the delete button, and mouseout is called for the <li>, the mouseover for the <div> will see that its in the <li> and run the over for li code.

You can use closest() to find the parent shopping list <li> if it exists.

    const listItem = item.target.closest('#myShoppingList li');
     if(listItem){
        listItem.classList...
1 Like

Thanks for that, I’m starting to understand better on traversing through the DOM to select elements… taking awhile lol.

The closest() is a new one for me, and its kind of making sense. The only issue I’m seeing is that it’s calling the class function for the <li> onto the <div> when the mouse is moving over the <div> (which is the delete section)

const listItem = item.target.closest(‘#myShoppingList li’);

if(listItem) {
item.target.classList.add(‘onLi’);
item.target.lastChild.classList.add(‘containerDelete’);
}

It also calls the other function to it, which makes sense when it says item.target.lastChild.classList is undefined because there is no lastChild in the <div>

You don’t want to use item.target inside the if, you want to use listItem. item.target may be the list item or it may be some element in the list element and you want to work of the list element (listItem) itself.

2 Likes

Has anyone told you that your AMAZING

After reading more about Traversing the DOM

And going back to reading what you said, it all clicked on what I was doing wrong. Since you created const listItem = item.target.closest('#myShoppingList li'); in the ‘mouseOver function’, I didnt need to us ‘item.target’ again in the if
I just had to call listItem to add or remove the class

Here is the updated code:
jsfiddle.net/TheOne_TheMany/r1gz4aep/10

Thank you so much @senocular

2 Likes