JS学习47:transitionend 事件的折腾

1、引子

如上,单击方块的运行结果应该是什么呢?在高级浏览器下测试的结果是:1、2,符合预期。

通常,dom元素上的事件名称,比如“onclick、onmousedown”是与事件监听的事件名称是一一对应的,只是省略了“on”。于是:

如上,ontransitionend 是监听 css3 中 transition 过渡结束的事件,相关链接可以阅读参考链接。实际运行结果是,#demo 元素内并未如期的出现 done 内容。

2、折腾

于是尝试用驼峰形式来书写,如 onTransitionEnd、onWebkitTransitionEnd 都没有达到预期的结果。为什么要做这个尝试?因为有这样的事件名称:DOMContentLoaded。并且,奇葩的是,这个事件名称虽然是监听 document 的,但是也无法使用 document.onDOMContentLoaded 来监听。但 "onDOMContentLoaded" in document 却返回 true,让人摸不着头脑。

因此,尝试使用 in 操作符来检测元素是否含有该事件监听方法存在。

 
 
  1. "onDOMContentLoaded" in document// => true
  2. "ontransitionend" in document.body// => false
  3. "onTransitionEnd" in document.body// => false
  4. "onWebkitTransitionEnd" in document.body// => false

上面结果的出现,倍感吃惊。当我们尝试在 window 对象上进行 in 检测时:

 
 
  1. "ontransitionend" in window// => true

真调皮的。当我拿着这段欣喜若狂的代码去火狐下检测时:

 
 
  1. "ontransitionend" in window// => false
  2. "ontransitionend" in document;; // => false
  3. "ontransitionend" in document.body;; // => false
  4. "onMozTransitionEnd" in window;; // => false
  5. "onMozTransitionEnd" in document;; // => false
  6. "onMozTransitionEnd" in document.body;; // => false

火狐更让我吃惊。但是火狐确实可以用 document.addEventListener 来监听到 transitionend 事件的,却无法检测出来。

于是,找来了 zepto 这个脚本库来参考,才出这么一个蹩脚的检测方案:

先检测 transition-property 这个 css 属性的私有前缀,然后添加到 transitionend 前面去(详细方法见下一节)。确实可以这样检测,但多多少少让人觉得有些失真,css 属性的私有前缀和 JS 事件的私有前缀,虽然有联系,但他们是没有交集的。比如浏览器率先支持了css3 的标准属性,但有私有前缀,但并不能说明,此时浏览器已经支持该 css3 的事件结束回调!?

不过怎样吧,这也算是绕了弯路,多少都已经到达目的地了。

3、私有前缀检测工具

3.1、检测 css3 私有前缀

 
 
  1. /**
  2.  * 获取有浏览器前缀的CSS3名称
  3.  * @param {String} standard 标准的CSS3属性
  4.  * @returns {String|null} 私有CSS3属性
  5.  *
  6.  * @example
  7.  * compatible.css3('border-start');
  8.  * // => "-webkit-border-start"
  9.  */
  10. css3function (standard) {
  11.     var cssKey = null;
  12.     var find = !1;
  13.     standard = _toSepString(standard.trim().replace(regCss3''));
  14.     dato.each(css3Prefixsfunction (indexprefix) {
  15.         cssKey = prefix ? prefix + '-' + standard : standard;
  16.         var testCssKey = fixCss[cssKey] ? fixCss[cssKey]: cssKey;
  17.         if (_toHumbString(testCssKeyin p.style) {
  18.             find = !0;
  19.             return !1;
  20.         }
  21.     });
  22.     return find ? cssKey : null;
  23. }

原理很简单,遍历一下私有前缀 ['', '-webkit', '-moz', '-ms'],使用 in 操作符在 style 对象里进行匹配,返回最先匹配到的,否则返回 null。

3.2、检测 html5 私有前缀

 
 
  1. /**
  2.  * 获取有浏览器前缀的方法名称
  3.  * @param {String} standard 标准属性、方法名称
  4.  * @param {Object} parent   标准方法父级
  5.  * @param {Boolean} [isEventType=false]   是否为事件类型
  6.  * @returns {String} 私有属性、方法名称
  7.  *
  8.  * @example
  9.  * compatible.html5('audioContext', window);
  10.  * // => "webkitAudioContext"
  11.  */
  12. html5function (standardparentisEventType) {
  13.     var html5Key = null;
  14.     var find = !1;
  15.     if(isEventType){
  16.         standard = standard.replace(regOn'');
  17.     }
  18.     dato.each(html5Prefixsfunction (indexprefix) {
  19.         html5Key = isEventType ?
  20.             (prefix + standard ):
  21.             (prefix ? prefix + _toUpperCaseFirstLetter(standard) : standard);
  22.         if ((isEventType ? 'on':'') + html5Key in parent) {
  23.             find = !0;
  24.             return !1;
  25.         }
  26.     });
  27.     return find ? html5Key : undefined;
  28. }

html5 检测要稍微多做一步,需要指定父级对象和是否为事件名称(事件名称都带有 on 前缀)。原理也很简单,也是遍历 ['', 'webkit', 'moz', 'ms', 'MS'] 操作。

最后,检测出 transitionend 的私有方法:

 
 
  1. var css = 'transition-property';
  2. var transitionendEventPrefix = compatible.css3(css).replace(css'').replace(/-/g'');
  3. var transitionendEventType = transitionendEventPrefix ? transitionendEventPrefix + 'TransitionEnd' : 'transitionend';

4、参考链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值