Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,而其中的 transition.js 就是为了判断当前使用的浏览器是否支持 CSS 过渡。下面先来简单了解下 CSS 过渡。

CSS 过渡

CSS 过渡是指在 CSS 属性发生改变时在一段时间内平滑地过渡,使用 CSS 伪类可以很方便地使用:

  1. a {
  2. color: #333;
  3. transition: color 1s linear;
  4. }
  5. a:hover {
  6. color: #36f;
  7. }

这里给链接设置了一个 1秒的颜色过渡效果,当鼠标经过链接激活链接 :hover 状态的时候文字的颜色会从黑色平滑地变化为蓝色,鼠标移开时又平滑地变回来。

仅仅依靠伪类来使用过渡显得太单调了,使用 JavaScript 来动态添加删除 class 才能尽情地玩弄过渡:

  1. /* 这是一个圆 */
  2. .circle {
  3. background-color: red;
  4. border-radius: 50%;
  5. height: 100px;
  6. margin-left: 220px;
  7. transition: transform 1s linear;
  8. width: 100px;
  9. }
  10. /* 添加 left 类水平向左偏移 200 像素 */
  11. .circle.left {
  12. transform: translateX(-200px);
  13. }
  14. /* 添加 right 类水平向右偏移 200 像素 */
  15. .circle.right {
  16. transform: translateX(200px);
  17. }

JavaScript 的工作就是简单的删除和添加 class:

  1. function toLeft() {
  2. $('.circle').removeClass('right').addClass('left');
  3. }
  4. function toRight() {
  5. $('.circle').removeClass('left').addClass('right');
  6. }

你让它往左,它不敢往右!demo上面的例子展示了当元素状态改变或者添加了某个 class 的时候过渡就开始发生了,那么如何知道过渡什么时候结束呢?

Transitionend 事件

想要知道过渡什么时候结束,就要监听 transitionend 事件(事件名称全是小写字母)。

  1. $('.circle').one('transitionend', function() {
  2. alert('过渡结束啦!');
  3. });

这里使用 one 方法而不是 on 方法是为了避免 transitionend 事件多次执行。one 方法添加的事件回调只会执行一次,更多信息参考官方 API

不过这只是标准的事件名称写法,在标准之前浏览器有各自的实现方式以及不同的事件名称(比如低版本的 Chrome 和 Safari 的该事件名称就叫 webkitTransitionEnd),所以为了兼容更多的浏览器,一种比较笨拙的方式可以写成像下面这样:

  1. $('.circle').one('transitionend webkitTransitionEnd oTransitionEnd otransitionend', function() {});

很长一串,而且这种写法还有一点问题!

在这里可以看到为什么是上面这些事件名称,而没有 msTransitionEnd 之类。

为了根据浏览器更有针对性地添加 transitionend 事件回调,而不是像上面那样一骨碌地全加上,就需要先判断一下该浏览器到底支持哪种 transitionend 事件名称,判断方法则是根据浏览器支持 CSS 过渡的属性名称而定:

  1. var el = document.createElement('bootstrap'); // 创建一个元素用于测试
  2. if (el.style.transition !== undefined) {
  3. // 判断元素的 style.transition 属性如果存在
  4. // 则以此类推该浏览器支持标准的 CSS transition 属性以及标准的 transitionend 事件
  5. } else if (el.style.WebkitTransition !== undefined) {
  6. // 判断元素的 style.WebkitTransition 属性如果存在
  7. // 则该浏览器支持替代的 webkitTransitionEnd 事件
  8. } else {...}

按照当前的主流浏览器趋势总共需要判断四种不同前缀的属性名称:

  1. el.style.transition
  2. el.style.WebkitTransition
  3. el.style.MozTransition
  4. el.style.OTransition

判断方式就是这样,废话就说到这里,直接上正牌代码,Bootstrap transition.js 内部的判断函数:

  1. function transitionEnd() {
  2. // 创建一个元素用于测试
  3. var el = document.createElement('bootstrap');
  4. // 将所有主流浏览器实现方式整合成一个对象,用于遍历
  5. // key 是属性名称
  6. // value 是事件名称
  7. var transEndEventNames = {
  8. WebkitTransition : 'webkitTransitionEnd',
  9. MozTransition : 'transitionend',
  10. OTransition : 'oTransitionEnd otransitionend',
  11. transition : 'transitionend'
  12. };
  13. // 循环遍历上面那个对象,判断 CSS 属性是否存在
  14. for (var name in transEndEventNames) {
  15. if (el.style[name] !== undefined) {
  16. return { end: transEndEventNames[name] };
  17. }
  18. }
  19. return false;
  20. }

执行该函数可以得到一个对象 {end: 'transitionend'} 或者 false (表示浏览器不支持 CSS 过渡),该对象的 end 属性保存着浏览器所支持的 transitionend 事件对应的名称:

  1. var transition = transitionEnd();

比如我使用低版本的 Chrome 浏览器的话,那么得到的对象就是 {end: 'webkitTransitionEnd'} 这样;如果使用 IE 8 则是 false,然后就可以添加该事件的回调函数了:

  1. // 如果 transition 为 false 则不添加事件回调
  2. transition && $('.circle').one(transition.end, function() {});

为了与 jQuery 保持一致,将该返回结果赋值到 $.support.transition 上:

  1. $.support.transition = transitionEnd();
  2. // 使用方式是类似的
  3. $.support.transition && $('.circle').one($.support.transition.end, function() {});

EmulateTransitionEnd

事件名称的问题基本上解决了,但是这个事件有个问题就是有时根本不会触发,这是因为属性值没有发生变化或没有绘制行为发生。要确保每次回调都会被调用,我们增加一个定时器即可:

  1. $.fn.emulateTransitionEnd = function(duration) {
  2. var called = false; // transitionend 事件是否已触发标识
  3. var $el = this;
  4. $(this).one($.support.transition.end, function () {
  5. called = true; // 表示已触发
  6. });
  7. var callback = function() {
  8. if (!called) {
  9. $($el).trigger($.support.transition.end); // 未触发,强制其触发
  10. }
  11. };
  12. setTimeout(callback, duration); // 一段时间后检测是否触发
  13. return this;
  14. };

该方法的作用是一段时间(就是过渡持续的时间 transition-duration )过后如果 transitionend 事件没有发生则强制在该元素上触发这个事件。

  1. $('.circle').one($.support.transition.end, function() {});
  2. $('.circle').emulateTransitionEnd(1000); // 这个时间是过渡持续的时间

这样确保过渡之后一定会有回调。到这里,基本上就差不多了,不过 $.support.transition.end 好恶心啊!能不能像添加其它事件回调一样使用事件名称字符串的形式,比如 'click',当然可以。

自定义事件

  1. $(function () {
  2. $.support.transition = transitionEnd();
  3. // 支持过渡的时候才执行后面的代码
  4. if (!$.support.transition) {return;}
  5. $.event.special.bsTransitionEnd = {
  6. bindType: $.support.transition.end,
  7. delegateType: $.support.transition.end,
  8. handle: function (e) {
  9. if ($(e.target).is(this)) {
  10. return e.handleObj.handler.apply(this, arguments);
  11. }
  12. }
  13. };
  14. });

添加事件回调的时候就可以像这样:

  1. $('.circle').one('bsTransitionEnd', function() {})
  2. .emulateTransitionEnd(1000);

其它

CSS 动画同样也有一个 animationend 事件,同时还有 animationstartanimationiteration 事件,可以参考这种方式自己写一个。

参考资料

Bootstrap transition.js 插件详解的更多相关文章

  1. Bootstrap transition.js 插件

    Bootstrap transition.js 插件详解   Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,而其中的 transition.js 就 ...

  2. 转载 JS组件Bootstrap Select2使用方法详解

    JS组件Bootstrap Select2使用方法详解 作者:懒得安分 字体:[增加 减小] 类型:转载 时间:2016-01-26我要评论 这篇文章主要为大家介绍了JS组件Bootstrap Sel ...

  3. 使用bootstrap的JS插件实现模态框效果

    在上一篇文章中,我们使用 js+css 实现了模态框效果,在理解了模态框的基本实现方法和实现效果后,我们就要寻找更快捷的方法,又快又好的来完成模态框开发需求,从而节约时间,提高效率.一个好的轮子,不仅 ...

  4. Bootstrap Table使用方法详解

    http://www.jb51.net/article/89573.htm bootstrap-table使用总结 bootstrap-table是在bootstrap-table的基础上写出来的,专 ...

  5. Uploadify 上传文件插件详解

    Uploadify 上传文件插件详解 Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.不过官方提供的实例时php版本的,本文将详细介绍Uploadify在Aspnet中 ...

  6. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

  7. Google自写插件详解

    谷歌插件详解,跳转至个人主页查看. GoogleExtension

  8. Maven系列第6篇:生命周期和插件详解,此篇看过之后在maven的理解上可以超越同级别90%的人!

    maven系列目标:从入门开始开始掌握一个高级开发所需要的maven技能. 这是maven系列第6篇. 整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部 ...

  9. ThreeJS系列1_CinematicCameraJS插件详解

    ThreeJS系列1_CinematicCameraJS插件详解 接着上篇 ThreeJS系列1_CinematicCameraJS插件介绍 看属性的来龙去脉 看方法作用 通过调整属性查看效果 总结 ...

随机推荐

  1. Java多线程系列--“JUC原子类”04之 AtomicReference原子类

    概要 本章对AtomicReference引用类型的原子类进行介绍.内容包括:AtomicReference介绍和函数列表AtomicReference源码分析(基于JDK1.7.0_40)Atomi ...

  2. Android UI设计中一些不错的示例及第三方控件

    1.二级ListView自定义布局ExpandableListView http://pan.baidu.com/s/1mhlJh12 密码:nhc2 2.ListView实现各种动画效果ListVi ...

  3. web前端学习笔记(CSS盒子的浮动)

    在标准流中,一个块级元素在水平方向会自动伸展,直到包含它的元素的边界:而在竖直方向和兄弟元素依次排列,不能并排.使用“浮动”方式后,块级元素的表现就会有所不同.      CSS中有一个float属性 ...

  4. T-SQL---多值模糊查询的处理

    多值模糊查询的处理 所谓多值模糊查询,就是应用程序中传递过来多个参数,对这些参数做拆分,拆分之后,对拆分结果的key值分别做模糊查询处理 对于精确匹配时,不管是单个Key值还是多个Key值,都很容易处 ...

  5. Hichart 资料收集

    Hichart简单使用Highcharts选项配置详细说明文档(zz) http://www.helloweba.com/view-blog-156.html  by 澳米科技 Highcharts提 ...

  6. ASP.NET Core实现OAuth2.0的ResourceOwnerPassword和ClientCredentials模式

    前言 开发授权服务框架一般使用OAuth2.0授权框架,而开发Webapi的授权更应该使用OAuth2.0授权标准,OAuth2.0授权框架文档说明参考:https://tools.ietf.org/ ...

  7. .net概念之程序集说明

    一.程序集的一些基本概念: 程序集是包含一个或多个类型定义文件和资源文件的集合.它允许我们分离可重用类型的逻辑表示和物理表示. 程序集是一个可重用.可实施版本策略和安全策略的单元.它允许我们将类型和资 ...

  8. 使用C#向Sql Sever中存取网络图片和本地图片(二进制流的形式)

    先是做普通的,存储我们本地的图片,将它转化为二进制流存储到数据库对应的表中. 代码如下: string path = "../../A.jpg"; FileStream fs = ...

  9. C#导出Excel那些事

    Excel导出 Excel导出的意义 因为在项目中有些报表数据客户需要导出功能,那么导出为Excel就十分有必要了,可是有些客户的机器上并没有安装Excel或者安装的版本参差不一.那么我们在这样的情况 ...

  10. Android 添加桌面快捷方式操作

    /** * 为程序创建桌面快捷方式 */ private void addShortcut(){ Intent shortcut = new Intent(“com.android.launcher. ...