You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

_hyperscript中为details元素绑定on click事件时触发范围扩散至子节点的问题求助

hyperscript中为details元素绑定on click事件时触发范围扩散至子节点的问题求助

我最近在做一个带状态记忆的菜单,需要记录用户展开/折叠菜单项的状态,包括子菜单的状态。但碰到个头疼的问题——我给<details>元素绑定的on click事件,居然会被它所有的子元素触发!点子菜单里的链接也会触发父级的点击逻辑,这完全不是我想要的效果。

我翻遍了hyperscript的文档也没找到相关说明,谷歌搜了半天也没解决办法,只好来求助大家了。

初始有问题的代码

<aside class="w-64 p-5 flex flex-col h-screen">
  <ul class="menu bg-base-200 w-full flex-1 flex flex-col rounded-box">
    <li>
      <a>Home</a>
    </li>
    <li>
      <details id="menu-x-top" _="
        on click
        halt the event's bubbling
        handleMenuChanged(me) then
        init
        menuLoad(me)
      ">
        <summary>Stop - X</summary>
        <ul>
          <li>
            <a id="signals-should-not-log">Signals - Should not trigger X click</a>
          </li>
          <li>
            <details id="menu-y-child" _="
              on click
              halt the event's bubbling
              handleMenuChanged(me) then
              init
              menuLoad(me)
            ">
              <summary>Warnings - Y (X blocked)</summary>
              <ul>
                <li><a>Active - Should not trigger Y click</a></li>
                <li><a>Inactive - Should not trigger Y click</a></li>
              </ul>
            </details>
          </li>
        </ul>
      </details>
    </li>
    <li>
      <a>Addresses</a>
    </li>
  </ul>
</aside>

<script type="text/hyperscript">
def handleMenuChanged(this)
  if this.open is false then
    sessionStorage.setItem(this.id, 'true')
  else
    log this.id then
    sessionStorage.setItem(this.id, 'false')
  end
end

def menuLoad(this)
  if sessionStorage.getItem(this.id) is null then
    sessionStorage.setItem(this.id, 'false')
  else
    if sessionStorage.getItem(this.id) is 'true' then
      set this.open to 'open'
    end
  end
end
</script>

临时解决方案(已调整逻辑到summary元素)

后来根据@mariodev的建议,我把点击逻辑移到了<summary>元素上,这样就不会被子节点误触发了,调整后的代码如下:

<details id="menu-x-top">
  <summary _="
    on click
    handleMenuChanged(me.parentElement)
    init
    menuLoad(me.parentElement)
  ">
    Stop
  </summary>
</details>

<script type="text/hyperscript">
def handleMenuChanged(this)
  if this.open is false then
    sessionStorage.setItem(this.id, 'true')
  else
    sessionStorage.setItem(this.id, 'false')
  end
end

def menuLoad(this)
  if sessionStorage.getItem(this.id) is null then
    sessionStorage.setItem(this.id, 'false')
  else
    if sessionStorage.getItem(this.id) is 'true' then
      set this.open to 'open'
    end
  end
end
</script>

备注:内容来源于stack exchange,提问作者DannyThunder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 06:15:29