为什么节点 contains 方法没有捕获对 svg 元素的点击?

2023-12-28

我有一个基本的模态,其 html 结构中有一个 svg 图标。我想检测模式之外的点击,以便我可以将其关闭。执行此操作的代码类似于以下内容:

document.addEventListener('mousedown', (e) => {
  if(modal.contains(e.target)) return;
  closeModal();
});

但是,当我单击 svg(位于模态内部)时,单击事件被认为位于模态外部,我不明白为什么。为了让它按照我想要的方式工作,我必须对 svg 元素执行pointer-events: none。

简化的 html 结构如下所示:

  <div class="modal">
    <div class="css-t7awl3">
      <form>
        <div class="css-1incodr">
          <label class="css-g2pzhe" for="previousPassword">
            Mot de passe actuel<span class="css-5fl39m">*</span>
          </label>
        <div class="css-1xm32e0">
          <input
            class="css-17lan49"
            type="text"
            placeholder="**********"
            name="previousPassword"
          />
            <div id="test-input-toggle-password-visibility" class="css-1vw18kh">
              <svg
                height="16"
                viewBox="0 0 32 32"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
              />
            </div>
          </div>
        </div>
        <button class="css-1pnrrva" disabled="">
          Valider
        </button>
      </form>
    </div>
  </div>

编辑:如果我在此处粘贴实际的反应代码,也许会有所帮助,因为我不确定它是否是 svg 元素而不是我的代码的问题。

    export const PasswordInput = React.forwardRef<HTMLInputElement, PasswordInputProps>(({
  placeholder,
  name,
  id,
  disabled,
  className,
}: PasswordInputProps, ref) => {
  const [showPassword, setShowPassword] = useState(false);

  const DisplayedPicto = showPassword ? ClosedEyePicto : EyePicto;

  return (
    <Container className={className}>
      <CustomInput
        className={className}
        type={showPassword ? 'text' : 'password'}
        placeholder={placeholder}
        name={name}
        disabled={disabled}
        ref={ref}
        id={id}
      />
      <StyledSuffix
        onMouseLeave={() => setShowPassword(false)}
        onMouseDown={() => setShowPassword(true)}
        onMouseUp={() => setShowPassword(false)}
        id='test-input-toggle-password-visibility'
      >
        <DisplayedPicto height={16} />  //svg element
      </StyledSuffix>
    </Container>
  );
});

我只是明白发生了什么,这与 svgs 无关。 发生的情况是,当我单击 svg 时,首先会触发“mousedown”事件。请记住,“单击”事件由两个相继发生的事件组成:第一个是“鼠标按下”,然后是“鼠标松开”。

因此,通过 svg 上的“mousedown”事件,将触发 svg 周围组件 StyledSuffix 上的 onMouseDown 事件处理程序。这导致 dom 上的 svg 实际上从 EyePicto 更改为 ClosedEyPicto (const DisplayedPicto = showPassword ? ClosedEyePicto : EyePicto;)。因此,模态不再“包含”原始的 svg,因为它已经改变了!

解决方案是使用事件“click”而不是“mousedown”来监听单击。因为原来的 svg (EyePicto) 只会注册 'mousedown' 事件,而不会注册 'mouseup' 事件,因为它从 2 之间的 dom 中消失了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么节点 contains 方法没有捕获对 svg 元素的点击? 的相关文章

随机推荐

  • 如何消除 MigLayout 中两个单元格之间的垂直间隙?

    非常简单的问题 如何消除包含两个单元格的两个单元格之间的垂直间隙JCheckBox 我已经用红色边框标记了图片中的间隙 这是代码 import javax swing JButton import javax swing JCheckBox
  • WPF 应用程序是否需要使用 XAML?

    我想学习 C 似乎每个人都从使用 WinForms 转向使用 WPF 由于使用了用于构建表单的 XAML 文件 WPF 应用程序对我来说似乎要复杂得多 在我真正参与之前 我只是想问一下 XAML 文件是构建 WPF 应用程序的唯一方法吗 有
  • 如何在recyclerview项目之间设置相等的边距

    看这张图片 https i stack imgur com UtZFS jpg 我从 xml 布局中实现了当前边距 但四个边的边距并不相同 如何获得等额保证金 我当前的 xml 布局
  • 将shoutcast 流转换为Python 中的可播放样本?

    我有一个 Shotcat 广播电台 现在想为其构建一个播放器 我知道如何从服务器 获取 流 非常感谢 bobince 但我不确定如何将该流转换为可播放的样本 它是如何完成的 Shoutcast 流通常 但不总是 MP3 要获得可播放的样本
  • 数据表响应优先级

    我正在使用这个令人惊叹的插件 但在列上使用响应式优先级时发现了一个问题 Code var fillTable function data var list name Name 123456789 email email protected
  • Apache Commons Lang3 Hashcode、Equals 和 ToString(包括枚举)

    我们在模型中为服务响应和请求对象定义了很少的数据类型 最近我们发现需要实施ToString HashCode 和等于在所有此类类型上利用这些过度比较和断言 从几个来源确认 例如在Java中重写equals和hashCode时应该考虑哪些问题
  • Android 中的可扩展列表视图

    我有一个可扩展的 ListView 但我面临两个问题 Q1 如果标题不包含任何子项 我想将其隐藏 从列表中删除 为此 我有内部 getGroupView 方法 if getChildrenCount groupPosition 0 conv
  • 如何在没有任何注释的 Spring 项目中使用 Jackson Json 解析?

    情况 我有一个名为 Errors 的枚举类 它位于一个公共项目中 错误枚举包含一个 int 代码和一个 String 文本 Errors 枚举用于两个不同的项目 一个项目是基于 Spring 的项目 另一个项目是非 Spring J2EE
  • 是否可以在 C++03 中定义等效的“移动和交换习惯用法”

    我有义务C 03我有一个不可复制的对象 例如持有资源 我需要使用移动和交换语义能够做类似的事情并避免复制 MyClass returnMyClass void MyClass temp fill temp members with actu
  • 虚拟地球或谷歌地图

    简单的问题 答案可能不是 我将为客户开发一个 Web 应用程序 ASP NET MVC 他们询问我是否使用 Google 地图或 Virtual Earth 来提供地图解决方案的意见 你会选择哪一个 为什么 或者还有其他可以推荐的吗 还有什
  • 如何从数据帧创建 key:column_name 和 value:python 列中的唯一值的字典

    我正在尝试创建一个键 值对的字典 其中键是数据帧的列名 值将是包含该列中所有唯一值的列表 最终我希望能够从基于条件的字典 到目前为止 这是我能够做的 for col in col list 1 list list append footwe
  • Pytrends 趋势结果与手动下载的数据不相似

    I use pytrends自动下载数据到csv来自谷歌趋势 我使用的代码如下 在本例中 我正在下载 2008 年至今的每月 Google 趋势数据 from pytrends request import TrendReq from ur
  • html 5 canvas 硬件在 android chrome beta 上加速吗?

    我在 Android 浏览器与 chrome beta 上进行了一些 html 5 canvas 测试 结果有利于 Android 默认浏览器 尽管 chrome gpu 显示 canvas 具有硬件加速功能 测试示例 带有 8 个小图像的
  • istream读取失败后

    我有一小段代码来读取用户数据 如下所示 include
  • 在 Java 中,如何录制扬声器的声音输出? [复制]

    这个问题在这里已经有答案了 我有一个 Java 应用程序 它从多个来源接收声音 用户的能力之一是将应用程序中发生的情况记录到 AVI 文件中 我想将声音包含在该视频捕获中 如何录制用户会听到的声音 例如所有声音输入混合在一起的结果 我可以弄
  • 如何确定系统上的 Boost 版本?

    有没有一种快速方法可以确定系统上 Boost C 库的版本 增强信息宏 http www boost org doc libs 1 44 0 libs config doc html boost config boost macro ref
  • Windows ISO 8601 时间戳

    我需要将 Windows PowerShell 中的日期转换为 ISO 8601 格式 在 Linux Unix 中没有问题 TZ 0 date d
  • 从 Android 应用程序向 Azure AD 进行 Firebase 身份验证

    我正在尝试将 Microsoft 登录方法添加到我的 Firebase 项目中 希望允许用户使用其 Azure AD 凭据登录我的 Android 应用程序 我已经完成了使用 电子邮件 密码 提供商的所有设置 该提供商运行良好 我不打算访问
  • 扑动|如何将数据添加到 firestore 中的现有文档

    我正在使用 firestore 来存储我的 flutter 应用程序的数据 并且我创建了一个在用户登录后自动在 firestore 中创建文档的功能 现在我希望用户在填写此表单时 数据将添加到用户电子邮件所在的同一文档中 RaisedBut
  • 为什么节点 contains 方法没有捕获对 svg 元素的点击?

    我有一个基本的模态 其 html 结构中有一个 svg 图标 我想检测模式之外的点击 以便我可以将其关闭 执行此操作的代码类似于以下内容 document addEventListener mousedown e gt if modal c