jQuery.fadeIn 和 fadeOut 的 CSS3 替换

Posted

技术标签:

【中文标题】jQuery.fadeIn 和 fadeOut 的 CSS3 替换【英文标题】:CSS3 replacement for jQuery.fadeIn and fadeOut 【发布时间】:2013-12-14 08:56:34 【问题描述】:

我编写了少量代码来尝试复制 jQuery 的 .fadeIn().fadeOut() 函数,使用 CSS 过渡以在触摸设备上看起来更好。

理想情况下,我希望避免使用库,这样我就可以准确地编写我想要的内容,并作为学习练习。

fadeOut 运行良好。

fadeIn 的想法是使用 CSS3 过渡来调整元素的不透明度,之后该元素将被设置为 display:block;(使用 is-hidden 类)以确保它仍然不能被点击或覆盖下面的东西它。

fadeIn 不工作。我认为这是由于在删除 is-hiding 类的同时添加了 is-animating 类。由于没有发生转换,因此不会触发 transitionEnd 事件:

function fadeIn (elem, fn) 
  var $elem = $(elem);

  $elem.addClass('is-animating');
  $elem.removeClass('is-hidden');
  $elem.removeClass('is-hiding');

  $elem.on(transitionEndEvent, function () 

    $elem.removeClass('is-animating');

    if (typeof fn === 'function') 
      fn(); 
    
  );
; 

还有 CSS

.is-animating 
  @include transition(all 2000ms);


.is-hiding 
  // Will transition
  @include opacity(0);


.is-hidden 
  // Won't transition
  display: none;

这是代码:CodePen link

更新:我发现了我所说的 hack,但效果很好:CSS3 replacement for jQuery.fadeIn and fadeOut

此修复后的工作代码:Fixed

没有setTimeout 的解决方案将非常有价值。

【问题讨论】:

【参考方案1】:

我已经设法通过做一些感觉不自然和骇人听闻的事情来解决这个问题:

function fadeIn (elem, fn) 
  var $elem = $(elem);

  $elem.addClass('is-animating');
  $elem.removeClass('is-hidden');

  // Smelly, setTimeout fix
  setTimeout(function () 
    $elem.removeClass('is-hiding');
  , 0);

  $elem.on(transitionEndEvent, function () 

    $elem.removeClass('is-animating');

    if (typeof fn === 'function') 
      fn(); 
    
  );
; 

setTimeout 函数添加到包含可转换属性的类可解决此问题。

这里的工作代码:Codepen fixed code

【讨论】:

【参考方案2】:

您可能需要考虑几个插件来满足您的需求:

jQuery.transition.js 改进了现有的 jQuery 动画方法,以便在支持它们的浏览器中使用 CSS 过渡。

Transit 添加了一个transition 函数,您可以使用它来定义自己的过渡。它使用 jQuery 的效果队列,因此您可以将更改后的 display 值排队以在 opacity 完成过渡后运行。

【讨论】:

jQuery.transition.js 好像好几年没更新了。不过,Transit 很有希望。【参考方案3】:

使用关键帧的替代解决方案

js

var div=document.getElementsByTagName('div')[0],
    btn=document.getElementsByTagName('button')[0];

div.addEventListener('webkitAnimationEnd',function(e)
 div.style.display=div.classList.contains('hide')?'none':'';
,false);

btn.addEventListener('click',function(e)
 div.style.display='';
 div.classList.toggle('hide');
,false);

css3

div
 background-color:green;
 -webkit-animation:x 700ms ease 0ms 1 normal running;/*normal*/
 opacity:1;

div.hide
 -webkit-animation:x 700ms ease 0ms 1 reverse running;/*reverse*/
 opacity:0;

@-webkit-keyframes x
 0%opacity:0;
 100%opacity:1;

例子

http://jsfiddle.net/qQM5F/8/


这是一个原型

Object.defineProperty(htmlElement.prototype,'toggleOpacity',value:function()
 function check(e)
  this.style.display=this.classList.contains('hide')?'none':'';
  this.removeEventListener('webkitAnimationEnd',check,false);// clean up
 
 this.addEventListener('webkitAnimationEnd',check,false);
 this.style.display='';
 this.classList.toggle('hide');
,writable:false,enumerable:false);

css

.fade
 -webkit-animation:x 700ms ease 0 1 normal;
 opacity:1;

.fade.hide
 -webkit-animation:x 700ms ease 0 1 reverse;
 opacity:0;

@-webkit-keyframes x
 0%opacity:0
 100%opacity:1

用法

你需要淡入淡出的元素需要一个 fade 类,然后用它切换

element.toggleOpacity();

例子

http://jsfiddle.net/qQM5F/9/

【讨论】:

【参考方案4】:

我不知道您真正想要实现什么,但如果您使用 css3,那么您使用的是现代浏览器。在这种情况下,纯 css 和 javascript 是更好的解决方案。

关键在于你如何编写 css 过渡。

这里是js代码

var div=document.getElementsByTagName('div')[0],
    btn=document.getElementsByTagName('button')[0];
div.addEventListener('click',function()
 this.classList.add('hide');
,false);
div.addEventListener('webkitTransitionEnd',function(e)
 console.log(e.propertyName);
,false);
btn.addEventListener('click',function(e)
 div.classList.toggle('hide');
,false);

css代码

div
 width:200px;height:200px;
 opacity:1;
 overflow:hidden;
 line-height:200px;
 text-align:center;
 background-color:green;
    -webkit-transition:opacity 700ms ease 300ms,height 300ms ease ;

div.hide
 height:0px;
 opacity:0;
    -webkit-transition:opacity 700ms ease,height 300ms ease 700ms;
 /*add the various -moz -ms .. prefixes for more support*/

和html

some text 
<div>click here</div>
some text
<button>toggle</button>

这是一个例子。

http://jsfiddle.net/qQM5F/1/

【讨论】:

令人惊讶的简洁解决方案!话虽如此,我希望它能够处理一系列元素,而不仅仅是那些定义了height 的元素 - 只要在你的示例中没有设置height,它就不再那么好看了(并且可用的高度黑客太令人不快了)。我还想尝试尽可能接近地复制$.fadeIn$.fadeOut 的功能——这意味着动画不透明度,然后设置display:block; 以适应当前使用这些功能的项目(并依赖于检查display == block ) 等 你应该找到一个可以像第一个例子一样应用延迟的 css 样式。disply:none 重置整个过渡。

以上是关于jQuery.fadeIn 和 fadeOut 的 CSS3 替换的主要内容,如果未能解决你的问题,请参考以下文章

JQuery fadeIn fadeOut 与 setInterval 偶尔工作

jQuery fadeIn fadeOut 背景问题

Jquery FadeIn/Out连续旋转器

IE7/IE8 中的 jQuery FadeIn 文本:动画期间的文本别名

jQuery:FadeIn/To 和 SlideDown 新元素

jquery fadeIn()方法 语法