jQuery addClass 方法链接以执行 CSS 转换



我想做什么(坏了(:

<div></div>
<button>go</button>
$('button').click(function () {
    $('div').css({
        'transition': 'left 1000ms'
    }).addClass('left').addClass('left_more');
});

http://jsfiddle.net/0bm4wq7h/13/

还是坏了

<div></div>
<button>go</button>
$('button').click(function () {
    $('div').css({
        'transition': 'left 1000ms'
    }).addClass('left');
    console.log('test');
    $('div').addClass('left_more');
});

http://jsfiddle.net/fwL3dwz2/3/

但这有效

<div></div>
<button>go</button>
$('button').click(function () {
    $('div').css({
        'transition': 'left 1000ms'
    }).addClass('left');
    console.log($('div').css('left'));
    $('div').addClass('left_more');
});

http://jsfiddle.net/j8x0dzbz/5/

我知道我的 CSS 过渡需要一个起点。这就是我添加left类的原因。

为什么jQuery直到我的#3才进行转换?

更新:

所以我接受了斯特里纳的回答,因为它对我有用,现在我又遇到了同样的问题。上面的代码是这个JavaScript的简化版本:

$('#screen_wrapper img:eq(0)').removeClass().addClass('prep'); //starting point
window.getComputedStyle(document.getElementById('photo'+0)).left; //force the the styling to get recomputated using raw JavaScript 
$('#screen_wrapper img:eq(0)').css('left');//force the the styling to get recomputated using jQuery
$('#screen_wrapper img:eq(0)').addClass('animate_in');//animate to the "animate_in" class coordinates from the "prep" class coordinates

正在发生的事情是,我从prep类之前的坐标开始制作动画。

这是prep类:

#screen_wrapper img.prep {
    top: 0px;
    left: 506px;
}

但是图像实际上是从这个类开始的,该类是使用 removeClass() jQuery 方法删除的:

.animate_out {
    visibility: visible;
    top: 0px;
    left: -506px;
}

transition属性工作正常:

$('#screen_wrapper img').css('transition','left 1000ms');

我怀疑这些强制重新计算样式:

window.getComputedStyle(document.getElementById('photo'+0)).left;
$('#screen_wrapper img:eq(0)').css('left');

我正在使用铬:

Version 45.0.2454.101 Ubuntu 14.04 (64-bit)

更新

它不起作用的示例:http://jsfiddle.net/me8ukkLe/12/

当它调用$('div').css('left')时,你的转换在情况三下有效,因为jQuery将调用该方法window.getComputedStyle(或一个非常相似的方法,取决于浏览器兼容性问题(。在 Tim Taubert(Mozilla 员工(的一篇博客文章中,描述了这个技巧:

getComputedStyle()与访问属性值结合使用 实际上刷新所有挂起的样式更改并强制布局 引擎来计算我们<div>的当前状态。

如果不强制重新计算布局,重新计算将延迟到两个类(leftleft-more(都相加之后,这将计算其在400px的位置。

示例小提琴 - 使用getComputedStyle和访问.left

"CSS3 转换允许您在给定的持续时间内平滑地更改属性值(从一个值到另一个值(。

发布的第一个场景:

为了使css转换正常工作,您需要为要对其执行转换的元素指定 css 属性。在您的示例中,您正在对 left 属性进行转换,但它的初始值未在 div css 中定义。

为了修复它,只需添加left属性。

div {
    position: absolute;
    width: 10px;
    height: 10px;
    background-color: red;
    left: 0px;
}

工作示例:http://jsfiddle.net/0bm4wq7h/14/

已发布的第二个方案与已发布的第 3 个方案:

尽管这两个示例都没有为div定义left属性,但与第二个场景相比,第三个场景之所以有效是因为console.log造成的延迟。

在第一条声明中,

$('div').css({
        'transition': 'left 1000ms'
    }).addClass('left');

class left将添加到 div 元素中,该元素在内部添加 left 属性。但是添加控制台.log($('div'(.css('left'(会调用window.getComputedStyle(如Stryner所提到的(,它注册计算值并添加$('div').addClass('left_more');基本上给了它一个从left : 100pxleft : 600px的转换的机会。

好问题!这种行为乍一看确实很奇怪。清楚地解释这一点也有点棘手,但首先,请了解以下内容:

1(Javascript函数原子执行

在 JS 中,函数总是从头到尾运行,中途没有任何其他操作发生的可能性。这相当于说JS是一种单线程语言

2(浏览器也不能中断javascript。

不仅阻止 JS 代码在函数中途运行,而且运行代码的浏览器选项卡也不会插入!这意味着当JS函数运行时,网页上(几乎(所有内容(重绘,动画,样式表应用程序等(都会停止。如果要对此进行测试,可以尝试在控制台中运行while (true) { var i = 'yo'; }。(警告:这会让你难过(

3( JS函数内部的状态对浏览器是不可见的

因为浏览器不能在JS函数的中间中断,这意味着浏览器永远无法知道在所述函数中途发生的任何状态。浏览器只能根据函数完成后保留的状态进行操作。㗵?举例说明:

var someGlobalValue = null;
function lol() {
    someGlobalValue = 'hi';
    someGlobalValue = 'hello';
    someGlobalValue = 'ok';
}

当函数lol运行时,someGlobalValue假定多个值,但浏览器只会知道最后一个值,因为它必须在中途插入才能看到其他值(它不能这样做!

4(JS函数内部的CSS状态对浏览器同样不可见

这同样适用于 css 状态!(现在你可能会看到我实际上开始回答你的问题(。

如果调用以下函数:

function lol() {
    $('.thing').css('left', '10px');
    $('.thing').css('left', '30px');
}

浏览器永远不会应用 left: 10px 值,因为它在函数的中途不执行任何操作!浏览器只能处理函数的结果,一个完整的结果。

回答您的问题!!

小提琴 1

left_more类紧跟在left类之后 - 浏览器永远不会看到left类,并在函数结束后应用 css 样式 - 应用 left_more 类,但由于不存在初始左值,因此没有动画。(css 级联;当两个类都存在时,left_more完全覆盖left(

小提琴 2

同样的问题 - left类在浏览器可以处理它之前被覆盖

小提琴 3

这是有效的,因为该值是通过调用 css 来设置的,然后不会被覆盖,因为addClass用于设置值应动画到的位置。console.log无关紧要 - 重要的是css函数调用。该函数完成后,有 2 条信息,一条是css值,另一条是class值。这与另一个示例形成对比,其中函数运行后只剩下一条信息:class值。

如果您只想使用类,并且仍然进行转换,则流程必须如下所示:

1( 添加left类2(退出功能,允许浏览器查看状态3( 添加left_more

为作文而战,哈哈。但我认为这需要很长的解释,因为这个问题很微妙。

这里有几个问题。在给出的示例中,添加第一个left类时不会发生转换的原因是,为了使呈现引擎对属性进行动画处理,该属性需要已经具有值。在这种情况下,left没有值,因此不会发生转换。

链接时它不起作用的原因是因为特异性。 jQuery将添加这两个类,当调用呈现页面时,由于它们共享的特殊性,将应用最后添加的左侧定义。

它似乎可以通过在单独的时间添加类而不是链接来工作的原因是,当控制台访问元素的 css 值时.log渲染引擎是从 jQuery 隐式调用的。斯特里纳在这里的回答中指出了这一点:https://stackoverflow.com/a/33902053/1026459。这是一个非常好的发现。

下面是一个应用的示例,以便不需要猜测 left 的值。

发生的事情的实质是发现元素的偏移量以获得左侧的像素偏移量。然后,该值将应用于左侧样式属性。此时,当元素仍未更改位置时,将调用呈现引擎来更新 left 属性。然后删除该属性以确保特异性不优先于类定义,然后应用类定义。这将促进第一次相遇时的过渡。

jsFiddle Demo

$('button').click(function() {
    $('div').css({'transition':'left 1000ms'}).each(function(){	
        $(this).css('left',$(this).offset().left); 
        window.getComputedStyle(this,null).getPropertyValue("left");
    }).css('left','').addClass('left');
});
button {
    margin-top: 30px;
}
div {
    position: absolute;
    width: 10px;
    height: 10px;
    background-color: red;
}
.left {
    left: 100px;
}
.left_more {
    left: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button>go</button>

相关内容

  • 没有找到相关文章

最新更新