0

const profile = document.querySelector('#profile');

profile.addEventListener('mouseover', function() { 
   console.log('parent')
   const onHover = document.createElement('div');
   const hoverContent = document.createTextNode('my profile');
   onHover.setAttribute('id', 'miniProfile');
   onHover.append(hoverContent);
   onHover.style.height = '100px';
   onHover.style.width = '100px';
   onHover.style.backgroundColor = 'blue';
   onHover.style.position = 'absolute';
   onHover.style.top = '30px';
   this.append(onHover)
   setTimeout(()=> {
       onHover.style.top = '15px';
       onHover.style.transition = '1s'
       onHover.style.transitionTimingFunction = 'ease'
   }, 10)

    onHover.addEventListener('mouseover', function(e) { 
       // e.stopPropagation()
    })

})

profile.addEventListener('mouseout', function(e) { 
    
    if(e.relatedTarget.id.toLowerCase() !=        this.children[0].id.toLowerCase()) {
        console.log(this.children) 
        if(this.children.length != 0) { 
            for(let i = 0; i < this.children.length; i++) { 
                this.children[i].remove();
            }
        }
    }
})
#profile { 
    position: relative;
    display: inline-block;
    margin-left:100px;
    margin-top:50px;
    padding: 10px;
    background-color: red;
}
<div id="profile">My Profile</div>

When you hover over the red parent box, and then without hovering over the blue child box, you just hover out of the parent blue box, the log shows this:

HTMLCollection [div#miniProfile, miniProfile: div#miniProfile]

but when you open it, the length property shows 0. Here's a snapshot:

HTML Collection Length Property

Why?

Also, if you hover over the child blue box, you will generate a lot of new child elements, then when you hover out, you get an HTML collection with a lot of elements inside, but the length is almost always close to half the actual elements.

Here's a snapshot:

HTML collection

..again, why?

happy_story
  • 1
  • 1
  • 7
  • 17
  • The collection had 27 elements *when you logged it*, but *later* when you expanded it in the console, it only had 13 elements. This is a surprising behavior of consoles that trips people up from time to time, see the answers [here](http://stackoverflow.com/questions/38660832/element-children-has-elements-but-returns-empty-htmlcollection). – T.J. Crowder Aug 14 '21 at 14:11
  • I'm going to guess that you were looking at this because your loop through `this.children` didn't work the way you wanted it to. The reason for *that* is that `this.children` is an `HTMLCollection` which is "live." That means when you remove a child, the `length` goes down. So your loop starts out comparing `i` (`0`) with `length` (`27`), then removes an element (`length` is now `26`) and increments `i` to `1`. So on the next pass, you remove the element at index `1` but the element at index `0` (which used to be at index `1`) is never removed. – T.J. Crowder Aug 14 '21 at 14:15
  • See the answers [here](https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript) for how to remove all of the children from an element. But for other situations, if you're dealing with a live collection, loop backward rather than forward to avoid having them move around on you. – T.J. Crowder Aug 14 '21 at 14:16
  • @T.J.Crowder Thanks. Can I ask you one more thing? Why when I hover over a child element, the event on the parent is invoked even though the child does not have the same event listener? And same for hovering out of the child. Leaving the child is considered as leaving the parent, despite the child not having a `mouseout` event listener. Why is the parent `listening` when the child does not have an event listener? This is the example I am talking about: https://jsfiddle.net/5t73chmd/ I thought bubbling up only works when both have the same event listener? – happy_story Aug 14 '21 at 16:54
  • Both the `mouseover` and `mouseout` events *bubble*. So the events bubble to the parent and the parent's handler sees them. (In contrast, the `mouseenter` and `mouseleave` events don't bubble.) [Here's](https://jsfiddle.net/tjcrowder/fd281s6j/) a version of your fiddle logging `e.target.id` (the `id` of target element of the event) and `e.currentTarget.id` (the `id` of the element the current handler was attached to, which is always `parent` in your example). That should help make things more clear. [Here's](https://jsfiddle.net/tjcrowder/fd281s6j/1/) a version with the non-bubbling events. – T.J. Crowder Aug 14 '21 at 17:48
  • @T.J.Crowder But I don't get WHY are they bubbling since the child does not have an event listener? I thought it's only when the child element has an event listener to, say, `click`, and then the parent also has `click` event listener, then if you click the child, the event bubbles up and triggers the parent `click` event. But in my case, the child does not have any even, so why does entering and leaving the child triggers those same events of the parent? – happy_story Aug 14 '21 at 18:18
  • The bubbling happens regardless of whether there's an event listener on the child or not. When an event occurs, the browser sends it to the element and then if it's a bubbling event it also goes to that element's ancestors. This happens regardless of whether there are any event handlers at all (although if there are *none*, presumably the browser can optimize the process away). Event listeners are just that: *listeners*. The process happens whether they're there or not (in theory). – T.J. Crowder Aug 15 '21 at 08:29
  • 1
    Right. It's a good explanation. Thank you. – happy_story Aug 15 '21 at 11:05

0 Answers0