css3动画事件transitionend和animationend详解

在做界面的时候通常会使用css3的transitionanimation属性来实现动画效果,假如有这样一种需求——在动画执行完成后需要执行自定义业务逻辑,如抽奖转盘、拆红包、小游戏等场景,这个时候需要怎么去实现呢?

方法一

使用定时器setTimeout,设定一个和动画时长一样的time,过time时间后去执行业务逻辑。

setTimeout(function () {}, time);

这种方式简单除暴,一定程度上能满足需求,但更好是方式是使用transitionendanimationend事件。

方法二

transitionendanimationend是JavaScript原生支持的事件,对应css3的transitionanimation属性。

transitionend

示例:

var transitionEle = document.querySelector("#transition_ele");  
transitionEle.addEventListener("transitionend", function () {}, false);

注意:

transitionend事件会在 css transition 结束后触发。 当transition完成前移除transition时,比如移除css的transition-property属性,事件将不会被触发,如在transition完成前设置 display 为”none”,事件同样不会被触发。

关于transitionend事件的多次执行。假如设置transitionProperty=“width,height,background-color,transform”,这里width、height、background-color、transform四个属性都被改变了,那么这个时候transitionend会执行4次,这是因为transitionend事件执行了几次是取决于transition-property的设置(如果某个属性没有改变值,那么是不会触发transitionend的事件)。而在实际的运用中,往往只需要所有的动画结束后执行一次transitionend的事件来达效果,这个时候就需要做一些处理,让transitionend事件在多个css属性改变的情况下执行一次,示例:

var transitionFlag = true;  
transitionEle.addEventListener("transitionend", function (e) {  
    // or e.target === this  
  if (e.target === e.currentTarget && transitionFlag) {  
        transitionFlag = false;  
  // do something  
  }  
}, false);

兼容:

由于各个浏览器有不同的前缀,所以使用JavaScript代码时还要检测支持哪种,示例:

/* From Modernizr */
function whichTransitionEvent() {
    var t;
    var el = document.createElement('fakeelement');
    var transitions = {
        'transition'		: 'transitionend',
        'OTransition'		: 'oTransitionEnd',
        'MozTransition'		: 'transitionend',
        'WebkitTransition'	: 'webkitTransitionEnd'
    }
    for(t in transitions){
        if( el.style[t] !== undefined ){
            return transitions[t];
        }
    }
}
/* Listen for a transition! */
var transitionEvent = whichTransitionEvent();
transitionEvent && transitionEle.addEventListener(transitionEvent, function () {
    console.log('Transition complete!  This is the callback, no library needed!');
});

animationend

事实上animation动画有三个事件:

  • animationstart -css动画开始后触发
  • animationiteration – css动画重复播放时触发
  • animationend – css动画完成后触发

示例:

var animationEle = document.querySelector("#animation_ele");  
// 动画开始时事件  
animationEle.addEventListener("animationstart", function () {}, false);  
// 动画重复运动时事件  
animationEle.addEventListener("animationiteration", function () {}, false);  
// 动画结束时事件  
animationEle.addEventListener("animationend", function () {}, false);

注意:

animationend事件会在一个 css动画完成时触发(不包括完成前就已终止的情况,例如元素变得不可见或者动画从元素中移除)。

关于animationend事件的多次执行。不同于transitionend事件,animationend只会在动画完成后执行一次,但是如果在外层添加这个监听事件,并且监听元素里面还有动画,则里面元素动画结束也会执行这个animationend事件,这个时候就需要做一些处理,示例:

var animationFlag = true;  
animationEle.addEventListener("animationend", function (e) {  
    // or e.target === this  
  if (e.target === e.currentTarget && animationFlag) {  
        animationFlag = false;  
  // do something  
  }  
}, false);

兼容:

不同的浏览器要求使用不同的前缀,具体写法如下:

  • No prefix – animationstart, animationiteration, animationend
  • Webkit – webkitAnimationStart, webkitAnimationIteration, webkitAnimationEnd
  • Mozilla – mozAnimationStart, mozAnimationIteration, mozAnimationEnd
  • MS – MSAnimationStart, MSAnimationIteration, MSAnimationEnd
  • O – oAnimationStart, oAnimationIteration, oAnimationEnd

兼容方法:

function whichAnimationEvent() {
    var t,
        el = document.createElement("fakeelement");
    var animations = {
        "animation"      : "animationend",
        "OAnimation"     : "oAnimationEnd",
        "MozAnimation"   : "animationend",
        "WebkitAnimation": "webkitAnimationEnd"
    }
    for (t in animations) {
        if (el.style[t] !== undefined) {
            return animations[t];
        }
    }
}

var animationEvent = whichAnimationEvent();
animationEvent && animationEle.addEventListener(animationEvent, function () {
    console.log('Animation complete!  This is the callback, no library needed!');
});

CSS美化滚动条样式

滚动条是个很常见的东西,浏览网页的时候都会看到它的身影,但浏览器自带的滚动条通常不太美观,必要的时候我们会调整其样式以适配页面的UI设计,下面就介绍如何通过CSS美化滚动条样式。

兼容性

Webkit内核浏览器对滚动条样式支持较好,这里说的Webkit内核浏览器包括谷歌的Chrome浏览器,苹果公司的Safari浏览器,以及最新的Opera浏览器。这些浏览器加起来占有超过半数的桌面浏览器市场份额,对于移动端浏览器,基本上是Chrome浏览器和Safari浏览器的天下,唯一的遗憾是火狐浏览器,至今没有对CSS滚动条属性做任何的改进,至于IE浏览器,你可能会感到意外,IE浏览器是最早的一个支持滚动条外观CSS自定义的浏览器,早在IE5.5版时就支持,但仅支持颜色的改变,这些属性今天仍然是延用的。鉴于目前浏览器市场的格局,我们可以大胆的通过CSS来实现滚动条的美化。

Webkit下面的CSS滚动条属性

常用的有以下几个属性

  1. ::-webkit-scrollbar 滚动条整体部分
  2. ::-webkit-scrollbar-thumb 滚动条里面的小方块,能向上向下移动(或往左往右移动,取决于是垂直滚动条还是水平滚动条)
  3. ::-webkit-scrollbar-track 滚动条的轨道(里面装有Thumb)
  4. ::-webkit-scrollbar-button 滚动条的轨道的两端按钮,允许通过点击微调小方块的位置。
  5. ::-webkit-scrollbar-track-piece 内层轨道,滚动条中间部分(除去)
  6. ::-webkit-scrollbar-corner 边角,即两个滚动条的交汇处
  7. ::-webkit-resizer 两个滚动条的交汇处上用于通过拖动调整元素大小的小控件

简约版

::-webkit-scrollbar {
	width: 4px;
	height: 4px;
}
::-webkit-scrollbar-track {
	background: #f6f6f6;
	border-radius: 2px;
}
::-webkit-scrollbar-thumb {
	background: #aaa;
	border-radius: 2px;
}
::-webkit-scrollbar-thumb:hover {
	background: #747474;
}
::-webkit-scrollbar-corner {
	background: #f6f6f6;
}

这些CSS属性同样适用于局部滚动条美化,如:

HTML

<div class="scroll">
    <div class="content">
        <p>这里是内容区域</p>
        <p>这里是内容区域</p>
        <p>这里是内容区域</p>
        <p>这里是内容区域</p>
        <p>这里是内容区域</p>
        <p>这里是内容区域</p>
        <p>这里是内容区域</p>
    </div>
</div>

CSS

.scroll {
	width: 200px;
	height: 200px;
	overflow: auto;
}
.scroll .content {
	width: 400px;
	height: 400px;
}
.scroll::-webkit-scrollbar {
	width: 4px;
	height: 4px;
}
.scroll::-webkit-scrollbar-track {
	background: #f6f6f6;
	border-radius: 2px;
}
.scroll::-webkit-scrollbar-thumb {
	background: #aaa;
	border-radius: 2px;
}
.scroll::-webkit-scrollbar-thumb:hover {
	background: #747474;
}
.scroll::-webkit-scrollbar-corner {
	background: #f6f6f6;
}

前端轮子之uncss去除无用的css

通常一个运行维护多年的产品会产生很多无用的代码,多余的代码不仅给开发员带来维护的负担,也给产品的用户体验造成负面效应,对于网站或Web应用尤其如此,有没有一种便捷高效(偷懒)的方式或者工具帮助我们清除这些无用的代码呢?今天要介绍的主角uncss就能满足一部分需求,它是一款基于NodeJS的应用,可完全自动的帮助我们清除无用的CSS代码,并且使用真的非常简单。

项目地址:https://github.com/uncss/uncss

通过npm安装uncss

npm install -g uncss

一个基本的用法是直接在命令行窗口里输入uncss命令:

uncss http://www.yxxme.com > styles.css

该命令执行输出的结果就是一个你想要的,剔除了所有无用的CSS规则的完整的样式表文件。

uncss究竟是如何做到这些的呢?大概分为以下几步:

1、首先PhantomJS会加载整个HTML页面,然后执行JavaScript。
2、接着从HTML页面里提取页面中所有的CSS样式。
3、然后用css-parse分析并连接所有的样式规则。
4、用document.querySelector过滤出哪些CSS选择器是没有用到的。
5、最后用剩下的CSS规则生成输出文件

跟其它NodeJS工具一样,它里面提供了很多JavaScriptAPI,下面是一个使用它的API的例子:

var uncss = require('uncss');

var files   = ['my', 'array', 'of', 'HTML', 'files', 'or', 'http://urls.com'],
    options = {
        ignore       : ['#added_at_runtime', /test\-[0-9]+/],
        media        : ['(min-width: 700px) handheld and (orientation: landscape)'],
        csspath      : '../public/css/',
        raw          : 'h1 { color: green }',
        stylesheets  : ['lib/bootstrap/dist/css/bootstrap.css', 'src/public/css/main.css'],
        ignoreSheets : [/fonts.googleapis/],
        timeout      : 1000,
        htmlroot     : 'public',
        report       : false,
        banner       : false,
        uncssrc      : '.uncssrc',
        userAgent    : 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X)',
        inject       : function(window){ window.document.querySelector('html').classList.add('no-csscalc', 'csscalc'); }
    };

uncss(files, options, function (error, output) {
    console.log(output);
});

/* Look Ma, no options! */
uncss(files, function (error, output) {
    console.log(output);
});

/* Specifying raw HTML */
var rawHtml = '...';

uncss(rawHtml, options, function (error, output) {
    console.log(output);
});

如果你不打算使用NodeJS或仅做测试,作者提供了一个在线uncss工具https://uncss-online.com/

也可以工具项目情况配合以下构建工具使用:

WordPress更新出现维护提示

WordPress在升级程序、主题、插件时,都会先切换到维护模式,也就是显示 “正在执行例行维护,请一分钟后回来(Briefly unavailable for scheduled maintenance. Check back in a minute.)”,如果升级顺利,也就几秒左右就恢复正常;但是如果由于网速不佳等原因导致升级中断,WordPress就会一直停留在维护模式,不论前台还是后台,都一直显示“正在执行例行维护,请一分钟后回来”。
出现这种情况后,在WordPress根目录下会生成一个.maintenance文件,将这个文件删除后即可正常。如果在FTP中未发现该文件,可以在本地建一个同名文件,内容为空就好,然后上传到WordPress根目录即可。或者登陆Linux系统通过ll -a命令可查看该文件,然后执行删除命令即可。

WordPress活动及新闻RSS错误

新装或更新WordPress后,在后台面板首页WordPress活动及新闻卡片中肯能会出现RSS错误。出现的原因大概是由于网络原因,WordPress去获取官方的最新动态的时候超时导致的,而且一段时间内不会自动更新,所以下次登录后台面板的时候任然会看到提示,作为一个强迫症患者,这样的情况是不能容忍的。
有没有办法让卡片中的内容恢复正常呢?其实也很简单。首先打开数据库的wp_options表,不出意外的话会在表中看到有一条记录,其内容正是显示在后台面板的提示代码:

<div class="rss-widget"> 
   <p><strong>RSS错误:</strong> WP HTTP Error: cURL error 28: Operation timed out after 10000 milliseconds with 50297 bytes received</p> 
</div> 
<div class="rss-widget"> 
   <p><strong>RSS错误:</strong> WP HTTP Error: cURL error 28: Operation timed out after 10000 milliseconds with 13403 bytes received</p> 
</div>

尝试删除这条记录(数据库操作前记得备份)后,重新登录后台面板,这时候WordPress就会尝试再次去获取数据,如果获取到了就好了,如果任然出现不正常的提示,就多试几次,或者检查一下网络后再尝试。