如何在包装在跨度中的图标上触发跨度单击事件?

How to trigger a span click event on an icon wrapped in a span?

提问人:tlockhart 提问时间:10/1/2023 更新时间:10/1/2023 访问量:43

问:

我有一个基本的 react ToggleBtn 组件,可以更改向上/向下图标并触发模态。该按钮由文本和环绕在跨度中的图标组成。问题是单击图标时 event.target 不同。单击跨度上的文本时,它会触发跨度单击事件,该事件会冒泡到按钮处理程序。但是,如果单击该图标,则会触发 svg 单击事件。这是一个问题,因为模态的位置与被单击的对象相关联。因此,如果单击图标,模态会定位不正确。 注意:我将文本和图标包装在一个范围内,以便它们并排显示。有没有办法让图标触发跨度点击事件而不是 svg 点击事件?请参阅下面的代码:

const ToggleBtn = ({ btnName, children, showContent, handleBtnClick }) => {

  const [displayProjectToggle, setDisplayProjectToggle] = useState(false);

  const handleShow = (event, btnName) => {
    event.preventDefault();
    event.stopPropagation();
    console.log("Content: Event:", event.target);
    console.log("Content: Event:", btnName)
    console.log("Content: Event:", event.target.parentElement);

    handleBtnClick(event, btnName);
    // console.log("BtnName:", btnnName);
    setDisplayProjectToggle(!displayProjectToggle);
  };

  useEffect(() => {
    // console.log("displayProjectToggle:", displayProjectToggle)
  }, [displayProjectToggle]);

  return (
    <div className={showContent ? "content-toggle-show" : "content-toggle-hide"}>
      <div className="content-toggle-chevron">
        <button
          className="nav-link dropdown-btn"
          d
          onClick={(e) => handleShow(e, btnName)}
        >
          <span
            className="flex-container1"
            data-dropdown="dropdown2" aria-expanded="false"
            name="discover"
          >
            {btnName + " "}
            <FontAwesomeIcon
              className="mg-l-4 content-dropdown-header"
              data-dropdown="dropdown2" aria-expanded="false" name="discover"
              icon={
                displayProjectToggle
                  ? "fa-solid fa-chevron-down"
                  : "fa-solid fa-chevron-up"
              }
            />
          </span>

        </button>

      </div>{" "}
      {/*Header*/}

      {/*Content*/}
      <div className={displayProjectToggle ? "content-toggle-show" : "content-toggle-hide"}>{children}</div>
      {/*Content*/}
    </div>
  );
};

export default ToggleBtn;
ReactJS 事件 onclick

评论


答:

-1赞 harsh Kanodiya 10/1/2023 #1

图标触发 SVG 单击事件时面临的问题是,SVG 元素(包括组件)具有自己的事件处理,这些处理可能与常规 HTML 元素不同。要使图标触发跨度的单击事件,可以使用 CSS 和标签元素的组合来包装文本和图标,并将其样式设置为看起来像按钮。

下面是实现此目的的 ToggleBtn 组件的更新版本:

import React, { useState, useEffect } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

const ToggleBtn = ({ btnName, children, showContent, handleBtnClick }) => {
const [displayProjectToggle, setDisplayProjectToggle] = useState(false);

const handleShow = (event, btnName) => {
 event.preventDefault();
 event.stopPropagation();
 handleBtnClick(event, btnName);
 setDisplayProjectToggle(!displayProjectToggle);
};

  useEffect(() => {
   // console.log("displayProjectToggle:", displayProjectToggle)
  }, [displayProjectToggle]);

 return (
   <div className={showContent ? 'content-toggle-show' : 'content-toggle- 
  hide'}>
  <div className="content-toggle-chevron">
    <label
      className="nav-link dropdown-btn"
      onClick={(e) => handleShow(e, btnName)}
    >
      <span className="flex-container1" data-dropdown="dropdown2" aria- 
    expanded="false" name="discover">
        {btnName + ' '}
        <FontAwesomeIcon
          className="mg-l-4 content-dropdown-header"
          data-dropdown="dropdown2"
          aria-expanded="false"
          name="discover"
          icon={
            displayProjectToggle
              ? 'fa-solid fa-chevron-down'
              : 'fa-solid fa-chevron-up'
          }
        />
      </span>
    </label>
  </div>

  {/* Content */}
  <div className={displayProjectToggle ? 'content-toggle-show' : 'content- 
  toggle-hide'}>{children}</div>
  {/* Content */}
   </div>
  );
  };

export default ToggleBtn;

在此更新的代码中,我已将文本和图标包装在标签元素而不是按钮中,并应用了必要的 CSS 样式以使其看起来像按钮。这应确保单击文本和图标会触发 handleShow 函数,而不是单独的 SVG 单击事件。

评论

1赞 tlockhart 10/1/2023
感谢您提供的信息,根据 SVG 元素有自己的点击事件的知识,我能够通过向 FontAwesomeIcon 元素添加类“icon-container”来解决此问题。icon-container 规则将图标的 pointer-events 设置为 none。指针事件:无;