jquery - addClass() 是异步的吗?

标签 jquery css transition

它应该删除类 transition(因此 CSS transition 属性),将 div 移动到 200px(立即),重新应用 transition css 属性,然后动画化(花费 1 秒)右侧的 div。相反,它被卡住了。

看起来应用 css left 属性需要更多时间来按类删除 transition?还是 addClass() 是异步的?

var elem = $('#elem');

elem.removeClass('transition');
elem.css('left', 200);
elem.addClass('transition');
elem.css('left', 0);
#container {
  position: relative;
  width: 400px;
  height: 200px;
  background-color: red;
}
#elem {
  width: 50px;
  height: 50px;
  position: relative;
  left: 0;
  top: 0;
  background-color: blue;
}
.transition.linear.scritta {
  -webkit-transition: all 1.0s linear;
  -moz-transition: all 1.0s linear;
  -ms-transition: all 1.0s linear;
  -o-transition: all 1.0s linear;
  transition: all 1.0s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
  <div id="elem" class="transition linear scritta"></div>
</div>

最佳答案

不,addClass 是同步的。你可以看看source code :

addClass: function( value ) {
  var classes, elem, cur, curValue, clazz, j, finalValue,
      i = 0;

  if ( jQuery.isFunction( value ) ) {
    return this.each( function( j ) {
      jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
    } );
  }

  if ( typeof value === "string" && value ) {
    classes = value.match( rnothtmlwhite ) || [];

    while ( ( elem = this[ i++ ] ) ) {
      curValue = getClass( elem );
      cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );

      if ( cur ) {
        j = 0;
        while ( ( clazz = classes[ j++ ] ) ) {
          if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
            cur += clazz + " ";
          }
        }

        // Only assign if different to avoid unneeded rendering.
        finalValue = stripAndCollapse( cur );
        if ( curValue !== finalValue ) {
          elem.setAttribute( "class", finalValue );
        }
      }
    }
  }

  return this;
}

如果您使用 native API 而不是 jQuery,您会看到相同的结果。

var elem = document.getElementById('elem');

elem.classList.remove('transition');
elem.style.left = '200px';
elem.classList.add('transition');
elem.style.left = '0px';
#container {
  position: relative;
  width: 400px;
  height: 200px;
  background-color: red;
}
#elem {
  width: 50px;
  height: 50px;
  position: relative;
  left: 0;
  top: 0;
  background-color: blue;
}
.transition.linear.scritta {
  -webkit-transition: all 1.0s linear;
  -moz-transition: all 1.0s linear;
  -ms-transition: all 1.0s linear;
  -o-transition: all 1.0s linear;
  transition: all 1.0s linear;
}
<div id="container">
  <div id="elem" class="transition linear scritta"></div>
</div>

当您更改 CSS 样式时,浏览器似乎不会直接更新文档。这可能会产生绘画、重新布局和昂贵的操作,如果您要更改更多样式,这些将毫无用处。

所以他们稍等一下,让您更改更多样式,然后他们会同时更新所有样式。

作为解决方案,您可以尝试使用异步代码:

requestAnimationFrame(function() {
  elem.style.left = '0px';
});

var elem = document.getElementById('elem');

elem.classList.remove('transition');
elem.style.left = '200px';
elem.classList.add('transition');
requestAnimationFrame(function() {
  elem.style.left = '0px';
});
#container {
  position: relative;
  width: 400px;
  height: 200px;
  background-color: red;
}
#elem {
  width: 50px;
  height: 50px;
  position: relative;
  left: 0;
  top: 0;
  background-color: blue;
}
.transition.linear.scritta {
  -webkit-transition: all 1.0s linear;
  -moz-transition: all 1.0s linear;
  -ms-transition: all 1.0s linear;
  -o-transition: all 1.0s linear;
  transition: all 1.0s linear;
}
<div id="container">
  <div id="elem" class="transition linear scritta"></div>
</div>

使用 getComputedStyle 强制更新似乎也有效。

getComputedStyle(elem).transitionDuration; // force update

var elem = document.getElementById('elem');

elem.classList.remove('transition');
elem.style.left = '200px';
elem.classList.add('transition');
getComputedStyle(elem).transitionDuration; // force update
elem.style.left = '0px';
#container {
  position: relative;
  width: 400px;
  height: 200px;
  background-color: red;
}
#elem {
  width: 50px;
  height: 50px;
  position: relative;
  left: 0;
  top: 0;
  background-color: blue;
}
.transition.linear.scritta {
  -webkit-transition: all 1.0s linear;
  -moz-transition: all 1.0s linear;
  -ms-transition: all 1.0s linear;
  -o-transition: all 1.0s linear;
  transition: all 1.0s linear;
}
<div id="container">
  <div id="elem" class="transition linear scritta"></div>
</div>

关于jquery - addClass() 是异步的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40933962/

相关文章:

android - 播放/停止另一个 Activity 的声音

javascript - 如何使警告框后面的背景可点击?

javascript - 通过子导航(焦点功能)的 JS/JQuery keydown 循环无法按预期工作

javascript - jQuery 滚动在 IE 7 和 IE 8 中不起作用

html - 从按钮中删除边框

html - 嵌套列表中的 CSS 过渡

javascript - 如何循环遍历多个对象的json

javascript - 我的 html 文件不会链接到位于父目录中的样式表和 javascript

html - 我如何让 3 个 div 并排放置,最右边的 div 占据剩余宽度?

android - Android中如何制作连续运行的TransitionDrawable动画?