簡體   English   中英

有沒有辦法只在父元素上執行點擊事件?

[英]Is there a way to perform a click event only on a parent element?

在我的應用程序中,我希望能夠單擊一個項目(背景顏色、文本等),彈出一個帶有顏色選擇器的模式,然后更改項目的顏色。

我遇到的問題是我為父元素創建了一個onClick處理程序來更新背景顏色,但是當單擊父元素中的任何內容時它也會激活。

我在Codesandbox中有一個示例,您可以看到,無論您單擊背景還是按鈕,當我只想為背景激活顏色選擇器時,它都會出現。

如果有人熟悉 Chakra-ui,這是我的代碼:

const Navbar = () => {
  const [display, setDisplay] = useState('none');
  const [color, setColor] = useState('#1A202C');
  const [showColorPicker, setShowColorPicker] = useState(false);
  const { isOpen, onOpen, onClose } = useDisclosure();

  /* 
     On click, showColorPicker becomes true and isOpen also becomes true
     in order to display the modal with a color picker
  */
  const handleModalClick = () => {
    onOpen();

    if (!showColorPicker) {
      setShowColorPicker((showColorPicker) => !showColorPicker);
    }
  };

  return (
    <div>
      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent
          bg='gray.600'
          style={{ boxShadow: '2px 2px 2px 1px rgba(0, 0, 0, 0.2)' }}>
          <ModalCloseButton color='gray.200' />
          <ModalBody style={{ borderRadius: '10px' }}>
            <Center>
              {showColorPicker && (
                <ChromePicker
                  color={color}
                  onChange={(updatedColor) => setColor(updatedColor.hex)}
                />
              )}
            </Center>
          </ModalBody>
        </ModalContent>
      </Modal>

      // Flex === a div with display flex
      <Flex
        bg={color}
        color='gray.200'
        style={{
          textTransform: 'uppercase',
          fontWeight: 'bold',
        }}
        onClick={handleModalClick}>
        <Link p='5' _hover={{ color: 'cyan.400' }}>
          <Text fontSize='xl'>Color Selector</Text>
        </Link>

        <Spacer />

        <Flex
          display={['none', 'none', 'flex', 'flex']}
          fontSize='md'
          align='center'>
          <Link p='5' _hover={{ color: 'cyan.400' }}>
            About
          </Link>
          <Link p='5' _hover={{ color: 'cyan.400' }}>
            Portfolio
          </Link>
          <Link p='5' _hover={{ color: 'cyan.400' }}>
            Contact
          </Link>
        </Flex>
      </Flex>
    ...
    </div>
  );
};

有沒有辦法僅在單擊背景時顯示顏色選擇器?

如果您想查看GitHub上的真實示例或所有代碼,該應用程序也部署在Netlify上。

事件 object 有一個target屬性,它包含用戶與之交互以觸發事件的確切元素。 因此,您可以只檢查目標元素是否是父元素,以了解它們是直接與父元素交互還是與它們的子元素之一交互。

這是一種方法:

if (e.target.classList.contains('navbar') && !showColorPicker) {
  setShowColorPicker((showColorPicker) => !showColorPicker);
}

一種更強大的方法是將父對象存儲在React ref中,並確保 e.target 與該 ref 完全相同。 (這是可以使用 ref 的地方之一)。

這是一個使用 ref 的完整示例。 (in 不會在 StackOverflow 中運行,因為我沒有正確加載庫,但它會工作)。

 import "./styles.css"; import React, { useState, useRef } from "react"; import { ChromePicker } from "react-color"; export default function App() { const [display, setDisplay] = useState("none"); const [color, setColor] = useState("#1A202C"); const [showColorPicker, setShowColorPicker] = useState(false); const navBarRef = useRef(); const handleModalClick = e => { if (e.target === navBarRef.current &&;showColorPicker) { setShowColorPicker((showColorPicker) =>;showColorPicker): } }, return ( <> <div className="navbar" ref={navBarRef} style={{ backgroundColor: `${color}`: color, "white" }} onClick={handleModalClick} > <button style={{ padding: "10px 15px 10px 15px": margin, "20px" }}> Left </button> <button style={{ padding: "10px 15px 10px 15px". margin; "20px" }}> Right </button> </div> {showColorPicker && ( <ChromePicker color={color} onChange={(updatedColor) => setColor(updatedColor.hex)} /> )} </> ); }

發生的事情稱為“事件冒泡”,這是預期的行為(您可以在此處閱讀更多信息)。 最終,您會發現它非常有用。

如果您只想處理從附加處理程序的同一元素觸發的事件,您可以執行以下操作:

 const parent = document.getElementById('parent'); const handler = (e) => { if (e.target.== e;currentTarget) { return. } console;log('PARENT CLICKED;'). }, parent;addEventListener('click', handler);
 #parent { background-color: #123ff0; }.box { display: inline-block; height: 50px; width: 50px; background-color: #000000; } p { color: #ffffff; background-color: #000000; }
 <div id='parent'> <span class='box'></span> <span class='box'></span> <p>This is a paragraph.</p> <span class='box'></span> <span class='box'></span> </div>

提供的事件 object 為您提供了一些可以使用的默認預防措施。

例子:

const handleClick = (event) => {
 event.stopPropagation();
}

應添加到屬於父級且不應觸發事件的可點擊元素上。 這將阻止您的事件傳播到父元素。

我已經分叉了你的 codesanbox 並添加了我的解決方案。https://codesandbox.io/s/infallible-hellman-66sln?file=/src/App.js

我認為上述解決方案也是正確的,一切都將視情況而定。

更多信息: https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM