w3c / chinese-ig

Web中文兴趣组
https://www.w3.org/2018/chinese-web-ig/
Other
536 stars 192 forks source link

关于查询宿主环境是否支持某个特定的事件能力的提案讨论 #241

Open answershuto opened 3 years ago

answershuto commented 3 years ago

Hi All,

这个 issue 抛出一个关于事件的提案,我希望能够在 Web 中文兴趣组内先进行一些讨论,收集意见和建议,最终目标是能够贡献此标准。

需要注意的是这个文档目前还只是一个"提议",还不算是比较完整的提案。

提案期望解决 Web 标准下具有根据“特征判断”来获取当前宿主环境本身是否提供某个事件能力,以此来得知是否可以在当前宿主环境下使用某个具体的事件能力。

举个例子:

dblclick 事件为例,在移动端上,safari、firefox 等浏览器支持,但是 chrome、android WebView 不支持,这时如果我们没有“特征判断”则需要像下述那样编码。

if (/Chrome/.test(window.navigator.userAgent)) {
  // 通过其他手段实现,比如判断 2 次点击
} else {
  element.addEventListener('dblclick', (e)=>{
    //...
  });
}

显然,通过“环境判断”我们可以去实现相关功能,但是当历史版本以及浏览器种类繁多带来了非常多的判断条件。

Web 标准中,所有的 element 都是继承自 eventTarget,开发者无论监听何种事件都应该正常监听。但是开发者本意是监听一个来自宿主环境的 dispatch 时,宿主环境本身没有相关功能,就会导致功能缺失,而开发者无法很好地在上层进行判断。

我们期望通过“特征判断”来判断是否当前宿主环境提供某个特定事件,以解决上述问题。

我暂时想了三种方案,希望抛出来大家讨论一下:

  1. 通过提供一个宿主环境的方法 navigator.queryEventTypeSupport(type) 以供开发者查询宿主环境是否支持该功能。
const isSupportDblclick = navigator.queryEventTypeSupport('dblclick');
  1. 通过提供一个宿主环境的方法 Event 上提供一个静态方法 queryEventTypeSupport(type) 以供开发者查询宿主环境是否支持该功能。
const isSupportDblclick = Event.queryEventTypeSupport('dblclick');
  1. 在 eventTarget 上提供到某个具体的 element 的事件查询能力。
const element = document.createElement('div');
const isSupportDblclick = element.queryEventTypeSupport('dblclick');

我希望讨论的内容

wssgcg1213 commented 3 years ago

isEventSupports() 会更好一点吧

zhijs commented 3 years ago

赞👍~

  1. 确实有必要,日常开发中经常会遇到这种探测判断的场景,比如屏幕横竖屏切换事件,如果有相关的检测方法的话,会更方便以及代码的可读性更高。
  2. 可能在 Event 静态方法上扩展会跟合适一些,毕竟 Event 对象基本在所有的环境中都存在。
  3. 上述的 API 方式都不错,我这里也提供一种供参考的方式const isSupports = Event. supports('dbclick');
wssgcg1213 commented 3 years ago
xfq commented 3 years ago

看起来挺有用的,在标准层面感觉和HTML/DOM关系比较大,可以考虑在这个issue里先讨论一下这个提案的使用场景和建议语法,初步成型后提到DOM标准?

这是一个DOM的新特性提案的例子,可供参考(不过这个提案比我们讨论的这个要复杂得多):https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md

answershuto commented 3 years ago

其实在无论是在 Event 上扩展 还是 navigator 上扩展,都是一个全局的查询能力,只是一个能力归属放在哪个 global 对象下更合适的问题。而对于某些 element 的特定事件,上述 @wssgcg1213 比如 的 InputEvent 能力,属于某个 element 的特定能力,所以如果提供 element 级别的查询,使开发者可以感知某个具体的 element 支持哪些事件。

answershuto commented 3 years ago

考虑到特定元素的一些特有事件,以及 window 上的 onload 事件等,更倾向放在 EventTarget 上提供一个基础能力。继承 EventTarget 的 class 如果有自己的特有事件,可以覆盖该方法提供特有的一些事件判断。

answershuto commented 3 years ago

@xfq 已补充相关提案文档 https://github.com/answershuto/isEventSupports

xfq commented 3 years ago

谢谢 @answershuto 。简单看了一下你的提案,有两点建议:

  1. 我觉得需要写一下为什么不能使用 if (window.MouseEvent) 或者 if ("onxxxxx" in window) 这样的用法,因为这可能是常见问题
  2. 例子里写的 isEventSupports(Event event); 和下面的 .isEventSupports('click'); 不匹配,可能需要改为 isEventSupports(DOMString eventType);
answershuto commented 3 years ago

感谢 @xfq 的宝贵建议,相关内容我已经修改以及增加在文档中了。

https://github.com/answershuto/isEventSupports#other-considerations

xfq commented 3 years ago

感谢 @answershuto

如果其他同学没有新的comment,我觉得可以在DOM提一个issue了:https://github.com/whatwg/dom/issues

Issue里可以简单介绍一下这个提案,再加一个到 https://github.com/answershuto/isEventSupports 的链接。

xfq commented 3 years ago

另外,提案有一个小typo:最后的input will return ture应该是input will return true

answershuto commented 3 years ago

感谢 @xfq ,相关内容已修改。 DOM issue 见 https://github.com/whatwg/dom/issues/968