全是好东西!HTML command属性和JS toggle事件

这篇文章发布于 2026年06月22日,星期一,21:39,归类于 CSS相关。 阅读 56 次, 今日 50 次 没有评论

 

一、先说command属性

HTML command属性只能设置在按钮元素上,可以触发元素内置的方法,而这个方法是可以自定义设置的。

比方说下面这个点击按钮显示弹框的实现:

<button commandfor="my-dialog" command="show-modal">
  点击显示弹框
</button>

<dialog id="my-dialog" closedby="any">
  我显示啦!
</dialog>

<dialog>弹框元素内置了showModal方法,此时,点击按钮,弹框就会显示。

实时渲染效果如下:

我显示啦!

commandfor还适合触发popover浮层的显示,虽然popover属性有原生的popovertaregt属性。

实现原理

commandfor属性执行目标元素,通过ID属性值关联。

command属性会调用目标元素上的DOM方法,如果DOM方法是驼峰格式,则使用短横线表示。

是否支持自定义方法

测试代码如下:

<button commandfor="hanyun" command="radius">
  点击图片圆角
</button>
  
<img id="hanyun" src="hanyun.jpg" alt="张含韵">
  
<script>
HTMLImageElement.prototype.radius = function () {
  this.style.borderRadius = '50%';
} 
</script>

结果点击按钮是无效的,实时渲染如下,点击是没有任何反应的。

张含韵

正确使用自定义方法的路径

command执行其实是支持自定义行为的,只是使用方法并不是上面所说的这样,而是使用 command 事件。

代码示意:

<button commandfor="image" command="--radius">
  点击图片圆角
</button>
  
<img id="image" src="hanyun.jpg">
  
<script>
image.addEventListener("command", (event) => {
  if (event.command === "--radius") {
    event.target.style.borderRadius = '50%';
  }
});
</script>

此时,点击按钮,就可以看到图片元素圆角化了。

实时渲染效果如下(RSS订阅器中无效果,可访问原文体验):

兼容性

出乎我的意料,commandfor属性主流浏览器居然都已经支持了。

commond属性兼容性

二、再来说说toggle事件

ToggleEvent事件类型也是一个新特性,出现的时机比上面的command属性要早,如下截图所示:

Toggle事件的兼容性

此事件对象包括 beforetoggletoggle 两种事件类型。

其中:

  • beforetoggle事件会在Popover弹出框或<dialog>元素显示或隐藏之前触发;
  • toggle 事件则会在Popover弹出框、<dialog>元素或者<details>元素显示或隐藏后触发,多了个<details>元素。

newState和oldState值

我们可以通过newStateoldState事件对象的属性判断当前元素的展开还是收起状态。

比方说如下所示的实时渲染测试案例(RSS阅读器中无效果,可以访问原文体验):

HTML并不简单

技术发展还是很快的,在《HTML并不简单》这本书里介绍 details 元素的时候,还没有 toggle 事件呢。

测试代码如下:

<details id="details" open>
    <summary>HTML并不简单</summary>
    <content>技术发展还是很快的,在《HTML并不简单》这本书里介绍 details 元素的时候,还没有 toggle 事件呢。</content>
</details>
<script>
  details.addEventListener("toggle", function (event) {
    if (event.newState === "open") {
      this.style.background = 'aliceblue';
    } else {
      this.style.background = '';
    }
  });
</script>

最近刚支持的event.source

event.source可以返回触发ToggleEvent事件执行的目标元素。

例如,一个<dialog>元素关闭既可以使用内置的关闭行为(例如ESC,点击黑色蒙层,Form关闭、command关闭),还可以手动调用close()方法,此时我们可以借助event.source判断状态变化的来源是什么。

例如:

<p>关闭来源是:<output id="output"></output></p>
<p><button commandfor="dialog" command="show-modal">显示弹框</button></p>
<dialog id="dialog" closedby="any">
  <form method="dialog">
    <button>form关闭按钮</button>
  </form>
  <p>
    <button commandfor="dialog" command="close">command关闭按钮</button>
  </p>
</dialog>
<script>
  dialog.addEventListener("toggle", function (event) {
    if (event.newState === "closed") {
      output.textContent = event.source?.textContent || '来源未知';
    }
  });
</script>

实时运行效果如下(Chrome 140+,Safari 16.5+):

关闭来源是:

根据我的测试,只有通过command指令触发的弹框关闭按钮,才会被event.source识别出来,其他任何内置的弹框关闭行为,event.source都是null,包括JS执行的dialog.close()命令也是如此。

看来,这种场景下,还需要通过其他方式区分。

  • 常规弹框关闭,如果无法识别event.source,则可以认为是close()行为触发;
  • 如果是method="dialog"表单触发的弹框关闭,是会触发弹框的submit事件的;
    dialog.addEventListener("submit", function (event) {
      console.log('submit');
    });
  • 如果是ESC快捷键关闭,可以通过cancel事件识别。

最后,附上event.source的兼容性。

toggle事件source属性兼容性

三、结束时候说的话

妈呀,我买的恒生科技跌的爹妈都不认识了。

公司股票也新低了,没话说。

我还买了理想,两次翻倍都没卖,结果现在腰斩。

还不如去抄AI股。

算了,千斤难买早知道,人是无法赚到认知以外的钱的。

我家婉儿表示赞同!

南宫婉

(本篇完)

分享到:


发表评论(目前没有评论)