admin管理员组

文章数量:1310143

i want to identify the click outside a div element and close the dropdown menu based on it. However, clicking the svg element inside the div element (containing input element and svg) would identify it as click outside div element. Not sure how to solve it. I have tried using css trick as below,

button > * {
    pointer-events: none;
}

But it didnt work as well.

What i am trying to do ?

I have a form input element. within that i have a input with dropdown with up and down svgs. so when i click the svg down it identifies it as document click.

class Parent extends React.PureComponent {
    state = {
        opened: false,
    };

    ponentDidMount(){
        document.addEventListener('click', this.handle_document_click);
    }

    arrow_up_click = (e) => {
        e.stopPropagation();
        e.PreventDefault();
    }
    arrow_down_click = (e) => {
        e.stopPropagation();
        e.PreventDefault();
    }

    handle_document_click = () => {
        if (this.input_ref.current && 
            this.input_ref.current.contains(e.target)) {
                return;
        }
        this.setState({opened: false});
    };

    render = () => {
        return (
            <form onsubmit={handle_submit}>
                <div ref={this.input_ref}>
                    <input/>
                    <button>
                        {state.opened && <SvgUp height="22" width="22"/ 
                        onClick={arrow_up_click}>}
                        {!state.opened && <SvgDown height="22" 
                        width="22" onClick={arrow_down_click}/>}
                    </button>
               </div>
            </form>
        )
    }
}

Could someone help me fix this. I want the click on svg to not to be identified as document click. Thanks.

i want to identify the click outside a div element and close the dropdown menu based on it. However, clicking the svg element inside the div element (containing input element and svg) would identify it as click outside div element. Not sure how to solve it. I have tried using css trick as below,

button > * {
    pointer-events: none;
}

But it didnt work as well.

What i am trying to do ?

I have a form input element. within that i have a input with dropdown with up and down svgs. so when i click the svg down it identifies it as document click.

class Parent extends React.PureComponent {
    state = {
        opened: false,
    };

    ponentDidMount(){
        document.addEventListener('click', this.handle_document_click);
    }

    arrow_up_click = (e) => {
        e.stopPropagation();
        e.PreventDefault();
    }
    arrow_down_click = (e) => {
        e.stopPropagation();
        e.PreventDefault();
    }

    handle_document_click = () => {
        if (this.input_ref.current && 
            this.input_ref.current.contains(e.target)) {
                return;
        }
        this.setState({opened: false});
    };

    render = () => {
        return (
            <form onsubmit={handle_submit}>
                <div ref={this.input_ref}>
                    <input/>
                    <button>
                        {state.opened && <SvgUp height="22" width="22"/ 
                        onClick={arrow_up_click}>}
                        {!state.opened && <SvgDown height="22" 
                        width="22" onClick={arrow_down_click}/>}
                    </button>
               </div>
            </form>
        )
    }
}

Could someone help me fix this. I want the click on svg to not to be identified as document click. Thanks.

Share Improve this question edited Aug 26, 2019 at 21:26 stackoverflow_user asked Aug 26, 2019 at 20:34 stackoverflow_userstackoverflow_user 3014 silver badges17 bronze badges 4
  • The css you show should do the trick, did you inspect the output to see if it's even applied? You can also apply the attribute pointer-events="none" directly to the svg itself and get the same effect. – Chris W. Commented Aug 26, 2019 at 21:03
  • thanks. added that property to the svg directly and clicking the svg is submitting the form. i have modified the question with the respective code snippet. after adding pointer-events= none it is submitting form on clicking arrow up or down buttons. before it stopped propagating. – stackoverflow_user Commented Aug 26, 2019 at 21:22
  • got it. i had to add pointer-events = none to the parent element too that is the button element in this case and it worked. – stackoverflow_user Commented Aug 26, 2019 at 21:33
  • Ya I have to see what the actual rendered output is to be right the first time when it es to the frameworks stuff since I'm not familiar with whatever that is you're using but glad you found your remedy! – Chris W. Commented Aug 26, 2019 at 21:50
Add a ment  | 

3 Answers 3

Reset to default 5

You change the SVG icon depending on the state on the ponent. When the event of the SVG you swapped out reaches the event handler it is no longer "contained" in the div.

Found the answer in this very similar question: Why a click on svg element is not captured by node contains method?

That means that you do not have to disable pointer-events for all SVG:s but just have to wrap the ponents that are swapped out with a div containing a css class with pointer-events: none;.

I had a similar issue and I solved it with something close to your css trick:

Basically but applying pointer-events: none directly to the svg in question.

svg {
  pointer-events: none;
}

But I still don't understand why a click on the svg is considered to be outside of the node with the contains method.

I had a same problem.

After reading this answer I changed the listener to mousedown instead of click to trigger my equivalent of your hondle_document_click function. This solved the problem for me.

In your example this would be:

document.addEventListener('mousedown', this.handle_document_click)

instead of:

document.addEventListener('click', this.handle_document_click)

本文标签: Why is svg not identified inside a node using contain method using javascriptStack Overflow