user8472012
user8472012

Reputation:

Blur event triggered by click on child element

I got a parent element containing an input:

<div @blur="onLeaveSelect($event)">
    <div v-if="searchActivated" >
        <input type="text" placeholder="Search..." @mousedown.stop>
    </div>
    ...
</div>

When now clicking on the input child element the blur event of the parent div is fired. How'd I prevent that behavior? Using click.stop to prohibit bubbling works for other elements, but not that input.

        const onLeaveSelect = (evt) => {
            if (!evt.currentTarget.contains(evt.relatedTarget)) {
                open.value = false;
                showDescription.value = false;
                searchActivated.value = false;
            }
        }

Like this I stopped the dropdown from closing by a click on the input event. But the problem now is that focusing the input counts as not focusing the parent div anymore, what prevents the blur from getting detected completely.

Upvotes: 3

Views: 8857

Answers (4)

Sumod Sivadas
Sumod Sivadas

Reputation: 379

This is called event bubbling, to stop the event propagations, use e.stopPropagation() method on the child onClick()

Upvotes: -1

m01010011
m01010011

Reputation: 1082

I wanted the same behavior. But the focusout event is not present in React.

The way I solved it is using the onBlur event with a check to see if any child element is the relatedTarget:

  • If it's null, a child element hasn't been clicked on (so, we will want to hide the drop-down)
  • If it's not null, a child element has been clicked on (this will prevent the drop-down from being hidden)

Code snippet showing the parent div:

<div
    tabIndex='-1'
    onBlur={e => e.relatedTarget === null && setState(false)}
>
...
</div>

Upvotes: 9

user8472012
user8472012

Reputation:

The solution for all of my problems was the focusout event. It also detects focus inside an input child element. focusout

Upvotes: 4

Diego D
Diego D

Reputation: 8163

That happens because of events bubbling so that they get propagated to the parents.

There's an interesting question here on SO that I happened to hit very often in the past: How to stop propagating event from parent div to child div

There are several ways to stop such propagation but probably the easiest to achieve in this case is to use the css attribute on your child element:

pointer-events: none;

But since you clearly need that input to fire events, maybe you could try this other option in the event handler you added to parent element:

  if(event.target !== event.currentTarget) return;

But if yet you can't achieve what you are aiming to, you may try this line inside the handler for the event you wish it didn't propagate to the parent element:

 event.stopPropagation();

And as a side note I realized that div are not used to have the blur event because they don't capture focus as long as they don't have any tabindex="0" or contentEditable attributes. Maybe that's set by that directive when it will render the real html.

Upvotes: 1

Related Questions