Bootstrap transition.js 插件
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 事件,可以参考这种方式自己写一个。
参考资料
Bootstrap transition.js 插件的更多相关文章
- Bootstrap transition.js 插件详解
Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,而其中的 transition.js 就是为了判断当前使用的浏览器是否支持 CSS 过渡.下面先来简单 ...
- 使用bootstrap的JS插件实现模态框效果
在上一篇文章中,我们使用 js+css 实现了模态框效果,在理解了模态框的基本实现方法和实现效果后,我们就要寻找更快捷的方法,又快又好的来完成模态框开发需求,从而节约时间,提高效率.一个好的轮子,不仅 ...
- 《玩转Bootstrap(JS插件篇)》笔记
导入JavaScript插件 不论是单独导入还一次性导入之前必须先导入jQuery库. 一次性导入 <script src="js/bootstrap.min.js"> ...
- 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-2 动画过渡
动画过渡(Transitions) 这一小节我们先来讲“动画过渡(Transitions)”这个插件的使用,源文件:transition.js Bootstrap框架默认给各个组件提供了基本动画的过渡 ...
- 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-1导入JavaScript插件
导入JavaScript插件 Bootstrap除了包含丰富的Web组件之外,如前面介绍的下拉菜单.按钮组.导航.分页等.他还包括一些JavaScript的插件. Bootstrap的JavaScri ...
- Bootstrap的js插件之側边栏停靠(affix)
以下是一个比較常见的側边栏停靠的样例: <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- Bootstrap的js插件之轮播(carousel)
轮播请查看下面演示样例.基本已经涵盖最经常使用的一个轮播 <!DOCTYPE html> <html lang="en"> <head> < ...
- Bootstrap的js插件之警告框(alert.js)
data-dismiss="alert"--为关闭button加入该属性能够使其自己主动为警告框赋予关闭功能. .fade .in--为警告框在关闭时加入动画效果. 很多其它细节參 ...
- Bootstrap的js插件之按钮(button)
1)属性: data-loading-text="载入中..."--使button呈现载入状态: data-toggle="button"--使按钮可以切换状态 ...
随机推荐
- EasyUI DataGrid和Pagination
连接一台EasyUI项目驱动学习 DataGrid数据表格及Pagination分页一起介绍 一.通过<table>标记创建DataGrid,嵌套<th>标签定义列表 < ...
- StackExchange.Redis 使用
StackExchange.Redis 使用 - 事件(五) 摘要: ConnectionMultiplexer 可以注册如下事件ConfigurationChanged- 配置更改时Configur ...
- 关于“类不能支持Automation操作”错误的解决方法
一段程序IE上老是提示“类不支持Automation操作”的错误,IE6.7.8都一样,但是Firefox可以,后来网上找到如下解决方法: 重新注册下以下文件,问题便解决了:msscript.ocxd ...
- 13 于C#如何获得在IP住址
首先,需要加入一个命名空间 using System.Net.NetworkInformation; using System.Net.Sockets; 以下是具体代码 GetPrivateIP(); ...
- 【Java】【Flume】Flume-NG源代码分析的启动过程(两)
本节分析配置文件的解析,即PollingPropertiesFileConfigurationProvider.FileWatcherRunnable.run中的eventBus.post(getCo ...
- UVa - The 3n + 1 problem 解读
这个问题并计算质数了一下相间隔似的.思想上一致. 注意问题: 1 i 可能 大于或等于j -- 这里上传.小心阅读题意,我没有说这个地方不能保证.需要特殊处理 2 计算过程中可能溢出,的整数大于最大值 ...
- linux 使用外部设备的(光盘) 安装和更新库
1. 安装光盘(文件夹不存在,创建) mount -t auto /dev/cdrom /mnt/cdrom 2. 更改索引文件,指定读取本地文件 vi /etc/yum.repos.d/CentOS ...
- UVa 11205 - The broken pedometer
称号:给你p一个LED在同一个显示器组成n一个.显示每个显示器上的符号(LED的p长度01串) 问:用最少p几个比特位,您将能够这些区分n不同的符号.同样不能(其他位置上设置0处理) 分析:搜索.枚举 ...
- JAVA —— 文件输入输出
import java.io.*; public class FileIO { public static void main(String[] args) { //1.相对路径 File testF ...
- 【Nginx】显示器port管理
监听port属于server虚拟主机,由server{}块内的listen配置项决定. 也就是说,在server{}块配置项内定义了该虚拟主机所要监听的port. 在处理配置文件http块内main级 ...