React: relatedTarget in blur event in Firefox returns null always

Created on 7 Aug 2014  路  41Comments  路  Source: facebook/react

Basically that, the relatedTarget is returning null all the time, when in Chrome it is returning the correct value if clicking on an actual element (will return null if clicking outside the document, which is ok).

This is something that Firefox is doing natively, so there should be some "patch" in that case to make it cross browser as a syntethic event.

Here is an example: http://jsfiddle.net/leoasis/kb3gN/4476/ Click the first input and then the second, and you'll see in the console: a) the relatedTarget if in Chrome, or b) null if in Firefox.

DOM

Most helpful comment

i don't use react but i came across this issue while searching for what to do about the missing relatedTarget in IE11. i'm not familiar with how react works with events but using raw DOM events i managed to get a reasonable relatedTarget using the following

function blurHandler(e) {
    var relatedTarget = e.relatedTarget ||
            e.explicitOriginalTarget ||
            document.activeElement; // IE11

    if (!relatedTarget || !e.currentTarget.contains(relatedTarget) && !element.contains(relatedTarget)) {
        // blur is moving to an element outside of the tree under currentTarget
    }
}

maybe that will help someone.

All 41 comments

cc @syranide our resident event export these days

Haha, I believe I've seen some code in there that's meant to fix this, I'll have a look tomorrow and see what's going on. @leoasis I'm curious what you need this for.

Basically I'm trying to show some contextual elements whenever I'm focused in a component. So I have an onBlur handler at the root of my component and use the relatedTarget (which in a blur event is the element where i'm going TO) and check wether that element is inside the root one or not to figure out if I'm actually leaving the component or not.

I worked it around right now by checking the same but with clicks, attaching the handler in the document object and doing the same check. It works, but only for clicks (pressing tab won't work for example).

@leoasis That sounds like something you could/should solve with onMouseEnter and onMouseLeave. There's generally no reason to use the reported nodes in an event for React. That being said it should still be fixed.

Actually I want to show/hide things when focused, not when I'm hovering. Think about a contextual dropdown menu for example.

@leoasis So onFocus and onBlur then? Or whichever event fits your use-case. It's your choice obviously, but I'm quite certain that your solution has a React-only solution.

That's actually what I used, the thing is that onBlur is bubbled to the root element in the component whenever anything inside is blurred. So I still want to check if the relatedTarget (the next element being focused) is still inside the component.

@leoasis event.stopPropagation() I think?

@syranide I think that won't work in this case, since I don't want to handle the blur events in the children, I am handling the event in the top element inside the component, so I want to have the events propagated to that one.

Yep, your choice, but AFAIK, the React-way would be to handle it in the children and propagate a callback through props instead. Anyway, I'm going to have a look at fixing this either way.

Thanks for taking a look at it!

Anyway, I think I'm still not clear in what I need to do, and I don't think the React way is to traverse the entire children adding blur and focus handles to just see if i'm blurring out of the component or not. To be clear, this is a simplified version of what I'm trying to do, in a fiddle:

http://jsfiddle.net/leoasis/VkebS/569/

Notice that I want to be able to select the