Bootstrap transition.js 插件详解
Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,而其中的 transition.js 就是为了判断当前使用的浏览器是否支持 CSS 过渡。下面先来简单了解下 CSS 过渡。
CSS 过渡
CSS 过渡是指在 CSS 属性发生改变时在一段时间内平滑地过渡,使用 CSS 伪类可以很方便地使用:
a {
color: #333;
transition: color 1s linear;
}
a:hover {
color: #36f;
}
这里给链接设置了一个 1秒的颜色过渡效果,当鼠标经过链接激活链接 :hover 状态的时候文字的颜色会从黑色平滑地变化为蓝色,鼠标移开时又平滑地变回来。
仅仅依靠伪类来使用过渡显得太单调了,使用 JavaScript 来动态添加删除 class 才能尽情地玩弄过渡:
/* 这是一个圆 */
.circle {
background-color: red;
border-radius: 50%;
height: 100px;
margin-left: 220px;
transition: transform 1s linear;
width: 100px;
}
/* 添加 left 类水平向左偏移 200 像素 */
.circle.left {
transform: translateX(-200px);
}
/* 添加 right 类水平向右偏移 200 像素 */
.circle.right {
transform: translateX(200px);
}
JavaScript 的工作就是简单的删除和添加 class:
function toLeft() {
$('.circle').removeClass('right').addClass('left');
}
function toRight() {
$('.circle').removeClass('left').addClass('right');
}
你让它往左,它不敢往右!demo上面的例子展示了当元素状态改变或者添加了某个 class 的时候过渡就开始发生了,那么如何知道过渡什么时候结束呢?
Transitionend 事件
想要知道过渡什么时候结束,就要监听 transitionend 事件(事件名称全是小写字母)。
$('.circle').one('transitionend', function() {
alert('过渡结束啦!');
});
这里使用 one 方法而不是 on 方法是为了避免 transitionend 事件多次执行。one 方法添加的事件回调只会执行一次,更多信息参考官方 API。
不过这只是标准的事件名称写法,在标准之前浏览器有各自的实现方式以及不同的事件名称(比如低版本的 Chrome 和 Safari 的该事件名称就叫 webkitTransitionEnd),所以为了兼容更多的浏览器,一种比较笨拙的方式可以写成像下面这样:
$('.circle').one('transitionend webkitTransitionEnd oTransitionEnd otransitionend', function() {});
很长一串,而且这种写法还有一点问题!
在这里可以看到为什么是上面这些事件名称,而没有 msTransitionEnd 之类。
为了根据浏览器更有针对性地添加 transitionend 事件回调,而不是像上面那样一骨碌地全加上,就需要先判断一下该浏览器到底支持哪种 transitionend 事件名称,判断方法则是根据浏览器支持 CSS 过渡的属性名称而定:
var el = document.createElement('bootstrap'); // 创建一个元素用于测试
if (el.style.transition !== undefined) {
// 判断元素的 style.transition 属性如果存在
// 则以此类推该浏览器支持标准的 CSS transition 属性以及标准的 transitionend 事件
} else if (el.style.WebkitTransition !== undefined) {
// 判断元素的 style.WebkitTransition 属性如果存在
// 则该浏览器支持替代的 webkitTransitionEnd 事件
} else {...}
按照当前的主流浏览器趋势总共需要判断四种不同前缀的属性名称:
el.style.transition
el.style.WebkitTransition
el.style.MozTransition
el.style.OTransition
判断方式就是这样,废话就说到这里,直接上正牌代码,Bootstrap transition.js 内部的判断函数:
function transitionEnd() {
// 创建一个元素用于测试
var el = document.createElement('bootstrap');
// 将所有主流浏览器实现方式整合成一个对象,用于遍历
// key 是属性名称
// value 是事件名称
var transEndEventNames = {
WebkitTransition : 'webkitTransitionEnd',
MozTransition : 'transitionend',
OTransition : 'oTransitionEnd otransitionend',
transition : 'transitionend'
};
// 循环遍历上面那个对象,判断 CSS 属性是否存在
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] };
}
}
return false;
}
执行该函数可以得到一个对象 {end: 'transitionend'} 或者 false (表示浏览器不支持 CSS 过渡),该对象的 end 属性保存着浏览器所支持的 transitionend 事件对应的名称:
var transition = transitionEnd();
比如我使用低版本的 Chrome 浏览器的话,那么得到的对象就是 {end: 'webkitTransitionEnd'} 这样;如果使用 IE 8 则是 false,然后就可以添加该事件的回调函数了:
// 如果 transition 为 false 则不添加事件回调
transition && $('.circle').one(transition.end, function() {});
为了与 jQuery 保持一致,将该返回结果赋值到 $.support.transition 上:
$.support.transition = transitionEnd();
// 使用方式是类似的
$.support.transition && $('.circle').one($.support.transition.end, function() {});
EmulateTransitionEnd
事件名称的问题基本上解决了,但是这个事件有个问题就是有时根本不会触发,这是因为属性值没有发生变化或没有绘制行为发生。要确保每次回调都会被调用,我们增加一个定时器即可:
$.fn.emulateTransitionEnd = function(duration) {
var called = false; // transitionend 事件是否已触发标识
var $el = this;
$(this).one($.support.transition.end, function () {
called = true; // 表示已触发
});
var callback = function() {
if (!called) {
$($el).trigger($.support.transition.end); // 未触发,强制其触发
}
};
setTimeout(callback, duration); // 一段时间后检测是否触发
return this;
};
该方法的作用是一段时间(就是过渡持续的时间 transition-duration )过后如果 transitionend 事件没有发生则强制在该元素上触发这个事件。
$('.circle').one($.support.transition.end, function() {});
$('.circle').emulateTransitionEnd(1000); // 这个时间是过渡持续的时间
这样确保过渡之后一定会有回调。到这里,基本上就差不多了,不过 $.support.transition.end 好恶心啊!能不能像添加其它事件回调一样使用事件名称字符串的形式,比如 'click',当然可以。
自定义事件
$(function () {
$.support.transition = transitionEnd();
// 支持过渡的时候才执行后面的代码
if (!$.support.transition) {return;}
$.event.special.bsTransitionEnd = {
bindType: $.support.transition.end,
delegateType: $.support.transition.end,
handle: function (e) {
if ($(e.target).is(this)) {
return e.handleObj.handler.apply(this, arguments);
}
}
};
});
添加事件回调的时候就可以像这样:
$('.circle').one('bsTransitionEnd', function() {})
.emulateTransitionEnd(1000);
其它
CSS 动画同样也有一个 animationend 事件,同时还有 animationstart 和 animationiteration 事件,可以参考这种方式自己写一个。
参考资料
- All you need to know about CSS Transitions
- Using CSS transitions
- Detecting CSS Animation Completion with JavaScript
Bootstrap transition.js 插件详解的更多相关文章
- Bootstrap transition.js 插件
Bootstrap transition.js 插件详解 Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,而其中的 transition.js 就 ...
- 转载 JS组件Bootstrap Select2使用方法详解
JS组件Bootstrap Select2使用方法详解 作者:懒得安分 字体:[增加 减小] 类型:转载 时间:2016-01-26我要评论 这篇文章主要为大家介绍了JS组件Bootstrap Sel ...
- 使用bootstrap的JS插件实现模态框效果
在上一篇文章中,我们使用 js+css 实现了模态框效果,在理解了模态框的基本实现方法和实现效果后,我们就要寻找更快捷的方法,又快又好的来完成模态框开发需求,从而节约时间,提高效率.一个好的轮子,不仅 ...
- Bootstrap Table使用方法详解
http://www.jb51.net/article/89573.htm bootstrap-table使用总结 bootstrap-table是在bootstrap-table的基础上写出来的,专 ...
- Uploadify 上传文件插件详解
Uploadify 上传文件插件详解 Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.不过官方提供的实例时php版本的,本文将详细介绍Uploadify在Aspnet中 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- Google自写插件详解
谷歌插件详解,跳转至个人主页查看. GoogleExtension
- Maven系列第6篇:生命周期和插件详解,此篇看过之后在maven的理解上可以超越同级别90%的人!
maven系列目标:从入门开始开始掌握一个高级开发所需要的maven技能. 这是maven系列第6篇. 整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部 ...
- ThreeJS系列1_CinematicCameraJS插件详解
ThreeJS系列1_CinematicCameraJS插件详解 接着上篇 ThreeJS系列1_CinematicCameraJS插件介绍 看属性的来龙去脉 看方法作用 通过调整属性查看效果 总结 ...
随机推荐
- java.lang.Long cannot be cast to java.lang.Integer解决办法
情景: mybatis连接oracle 报错: 测试增的时候,报错 Java.lang.Long cannot be cast to java.lang.Integer:删改没有报错. 排查过程: ...
- iOS-地图报错超出了经纬度范围Invalid Region
做地图定位的时候,使用一下代码 // 经纬度 CLLocationDegrees latitude = [storeDict[@"lat"] doubleValue]; CLLoc ...
- 每日学习总结<二> 2015-9-1
Android: 知识点: 子线程中无法更新UI,因为UI是线程不安全的. Android的UI单线程模式: 不能阻塞UI线程: 不能从UI线程的外部访问Android UI toolkit ...
- Microsoft Azure News(1) 新的数据中心Japan East, Japan West and Brazil South
<Windows Azure Platform 系列文章目录> 微软官方博客今天表示,微软宣布将在日本东部(埼玉县)和日本西部(大阪)提供Windows Azure服务.就在最近,微软为W ...
- 第2/24周 页_SQL Server 中数据存储的基本单位
上周通过探讨SQL Server如何执行一个查询奠定了基础.我也在那里提到页是8kb的缓存.今天我们对页进行进一步集中探讨,从性能调优角度挖掘出更多的细节. 页是SQL Server的基础,在SQL ...
- SQL--局部变量
取值的话:print @变量名, 变量不设置值的话,默认打印出来是:NULL, 输出变量的值:
- CSS基础-插曲
CSS学习 1:通过css来设置边框的颜色 我们可以通过border:10px solid red;来统一的设置颜色,但是我们有的时候需要每个边框的颜色不一样,我们就需要通过各自设置的方法来设置边框的 ...
- Winform 显示Gif图片
代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data ...
- WinPhone学习笔记(四)——磁贴
对每个Windows Phone的使用者来说,给他们的第一印象就是大大小小的磁贴——Metro,本篇介绍的是Windows Phone的磁贴,提到的有开始菜单的磁贴,也有在App里面的磁贴. 开始菜单 ...
- xpath学习积累
"//comment()":“所有注释节点”