jQuery addClass 方法链接以执行 CSS 转换
jQuery addClass method chaining to perform CSS transitions
我想做什么(坏了):
<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
class.
为什么 jQuery 直到我的 #3 才进行转换?
更新:
所以我接受了 Stryner 的回答,因为它对我有用,现在我又遇到了同样的问题。上面的代码是 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
class.
之前的坐标开始获取动画
这是 prep
class:
#screen_wrapper img.prep {
top: 0px;
left: 506px;
}
但图像实际上是从这个 class 开始的,它是使用 removeClass()
jQuery 方法删除的:
.animate_out {
visibility: visible;
top: 0px;
left: -506px;
}
transition
属性 工作正常:
$('#screen_wrapper img').css('transition','left 1000ms');
我怀疑这些 force 重新计算样式:
window.getComputedStyle(document.getElementById('photo'+0)).left;
$('#screen_wrapper img:eq(0)').css('left');
我正在使用 Chromium:
Version 45.0.2454.101 Ubuntu 14.04 (64-bit)
更新
它不起作用的例子:
http://jsfiddle.net/me8ukkLe/12/
"CSS3 transitions allows you to change property values smoothly (from one value to another), over a given duration."
第一个场景发布:
为了使 css
过渡正常工作,您需要将 css
属性 指定给要进行过渡的元素。在您的示例中,您正在 left
属性 上进行转换,但它的初始值未在 div css
.
中定义
为了修复它,只需添加 left
属性.
div {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
left: 0px;
}
工作示例:http://jsfiddle.net/0bm4wq7h/14/
发布的第二个场景与发布的第三个场景:
尽管两个示例都没有为 div
定义 left
属性,但与第二个场景相比,第三个场景的工作原理是因为延迟由 console.log
引起。
在第一个语句中,
$('div').css({
'transition': 'left 1000ms'
}).addClass('left');
class
left
添加到 div
元素,后者在内部添加 left
属性。但是添加 console.log($('div').css('left') 会调用 window.getComputedStyle (如 Stryner 所述),它会注册计算值并添加 $('div').addClass('left_more');
基本上让它有机会执行从 left : 100px
到 left : 600px
的转换。
好问题!这种行为一开始肯定看起来很奇怪。解释清楚这一点也有点棘手,但首先,请了解以下内容:
1) Javascript 函数自动执行
在 JS 中,函数总是从头到尾 运行,中间没有任何其他操作发生的可能性。这就等于说JS是单线程语言.
2) 浏览器也无法中断javascript
不仅JS代码不会运行ning在一个函数中途被阻止,代码是运行ning的浏览器选项卡也不会插话!这意味着当 JS 函数 运行ning 时,网页上的(几乎)所有内容(重绘、动画、样式表应用程序等)都会停止。如果你想测试这个,你可以在控制台中尝试运行ning while (true) { var i = 'yo'; }
。 (警告:这会让你难过)
3) JS 函数内部的状态对浏览器是不可见的
因为浏览器不能在 JS 函数中间中断,这意味着浏览器永远无法知道在该函数中途发生的任何状态。浏览器只能根据函数完成后保持的状态进行操作。不清楚?举例说明:
var someGlobalValue = null;
function lol() {
someGlobalValue = 'hi';
someGlobalValue = 'hello';
someGlobalValue = 'ok';
}
当函数 lol
为 运行 时,someGlobalValue
会采用多个值,但浏览器将 只会知道最后一个值 , 因为它必须在中途插话才能看到其他人(这是它做不到的!)
4) CSS JS 函数内部的状态同样对浏览器不可见
css州也是如此! (现在您可能会看到,实际上我正在开始回答您的问题)。
如果调用以下函数:
function lol() {
$('.thing').css('left', '10px');
$('.thing').css('left', '30px');
}
浏览器 永远不会 应用 left: 10px
值,因为它不会在函数中途执行任何操作!浏览器只能使用函数的结果,即完成的结果。
正在回答您的问题!!
fiddle 1
left_more
class 紧跟在 left
class 之后 - 浏览器永远不会看到 left
class,并应用css 函数结束后的样式 - 应用 left_more
class,但由于没有初始左值,因此没有动画。 (css 级联;虽然两个 class 都存在,但 left_more
完全覆盖 left
)
fiddle 2
同样的问题 - left
class 在浏览器可以处理之前被覆盖
fiddle 3
这是有效的,因为该值是通过调用 css
设置的,然后不会被覆盖,因为 addClass
用于设置值应该动画到的位置。 console.log
无关紧要 - 重要的是 css
函数调用。一旦该函数完成,就会有两条信息,一条是 css
值,另一条是 class
值。这与另一个例子形成对比,在另一个例子中,函数 运行s 之后只剩下 一条 条信息:class
值。
如果您只想使用 classes,并且仍然要进行转换,则流程必须如下所示:
1) 添加 left
class
2)退出函数,允许浏览器查看状态
3) 添加left_more
class
对不起这篇文章哈哈。但我认为由于问题的微妙性,这需要很长的解释。
当它调用 $('div').css('left')
时,您的转换在案例三中有效,因为 jQuery 将调用 Tim Taubert(Mozilla 员工)的方法 window.getComputedStyle
(or a very similar method depending on browser compatibility issues). In a blog post,技巧如下:
getComputedStyle()
in combination with accessing a property value
actually flushes all pending style changes and forces the layout
engine to compute our <div>
’s current state.
在不强制重新计算布局的情况下,重新计算会延迟到添加了 类(left
和 left-more
)之后,这将计算其在 400px
的位置.
Example Fiddle - 使用 getComputedStyle
并访问 .left
这里有几个问题。在给出的示例中,添加第一个 left
class 时不会发生转换的原因是,为了让渲染引擎为 属性 设置动画,属性 需要已经有一个值。在这种情况下,left
没有值,因此不会发生转换。
链接时不起作用的原因是因为特异性。 jQuery 将添加两个 classes,并且当调用呈现页面时,由于它们共享的特殊性,将应用最后添加的 left 定义。
在单独的时间添加 class 而不是链式添加似乎起作用的原因是,当 console.log 访问 css 元素的值。 Stryner 在他的回答中指出了这一点: 。这是一个非常好的发现。
这是一个应用示例,因此无需猜测 left 的值。
发生的事情的实质是找到元素的偏移量以获得左侧的像素偏移量。然后将该值应用于左侧样式 属性。那时,当元素仍然没有改变位置时,渲染引擎被调用以更新左侧 属性。然后删除 属性 以确保特异性不会优先于 class 定义,然后应用 class 定义。这将有助于第一次相遇时的过渡。
$('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>
我想做什么(坏了):
<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
class.
为什么 jQuery 直到我的 #3 才进行转换?
更新:
所以我接受了 Stryner 的回答,因为它对我有用,现在我又遇到了同样的问题。上面的代码是 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
class.
这是 prep
class:
#screen_wrapper img.prep {
top: 0px;
left: 506px;
}
但图像实际上是从这个 class 开始的,它是使用 removeClass()
jQuery 方法删除的:
.animate_out {
visibility: visible;
top: 0px;
left: -506px;
}
transition
属性 工作正常:
$('#screen_wrapper img').css('transition','left 1000ms');
我怀疑这些 force 重新计算样式:
window.getComputedStyle(document.getElementById('photo'+0)).left;
$('#screen_wrapper img:eq(0)').css('left');
我正在使用 Chromium:
Version 45.0.2454.101 Ubuntu 14.04 (64-bit)
更新
它不起作用的例子: http://jsfiddle.net/me8ukkLe/12/
"CSS3 transitions allows you to change property values smoothly (from one value to another), over a given duration."
第一个场景发布:
为了使 css
过渡正常工作,您需要将 css
属性 指定给要进行过渡的元素。在您的示例中,您正在 left
属性 上进行转换,但它的初始值未在 div css
.
为了修复它,只需添加 left
属性.
div {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
left: 0px;
}
工作示例:http://jsfiddle.net/0bm4wq7h/14/
发布的第二个场景与发布的第三个场景:
尽管两个示例都没有为 div
定义 left
属性,但与第二个场景相比,第三个场景的工作原理是因为延迟由 console.log
引起。
在第一个语句中,
$('div').css({
'transition': 'left 1000ms'
}).addClass('left');
class
left
添加到 div
元素,后者在内部添加 left
属性。但是添加 console.log($('div').css('left') 会调用 window.getComputedStyle (如 Stryner 所述),它会注册计算值并添加 $('div').addClass('left_more');
基本上让它有机会执行从 left : 100px
到 left : 600px
的转换。
好问题!这种行为一开始肯定看起来很奇怪。解释清楚这一点也有点棘手,但首先,请了解以下内容:
1) Javascript 函数自动执行
在 JS 中,函数总是从头到尾 运行,中间没有任何其他操作发生的可能性。这就等于说JS是单线程语言.
2) 浏览器也无法中断javascript
不仅JS代码不会运行ning在一个函数中途被阻止,代码是运行ning的浏览器选项卡也不会插话!这意味着当 JS 函数 运行ning 时,网页上的(几乎)所有内容(重绘、动画、样式表应用程序等)都会停止。如果你想测试这个,你可以在控制台中尝试运行ning while (true) { var i = 'yo'; }
。 (警告:这会让你难过)
3) JS 函数内部的状态对浏览器是不可见的
因为浏览器不能在 JS 函数中间中断,这意味着浏览器永远无法知道在该函数中途发生的任何状态。浏览器只能根据函数完成后保持的状态进行操作。不清楚?举例说明:
var someGlobalValue = null;
function lol() {
someGlobalValue = 'hi';
someGlobalValue = 'hello';
someGlobalValue = 'ok';
}
当函数 lol
为 运行 时,someGlobalValue
会采用多个值,但浏览器将 只会知道最后一个值 , 因为它必须在中途插话才能看到其他人(这是它做不到的!)
4) CSS JS 函数内部的状态同样对浏览器不可见
css州也是如此! (现在您可能会看到,实际上我正在开始回答您的问题)。
如果调用以下函数:
function lol() {
$('.thing').css('left', '10px');
$('.thing').css('left', '30px');
}
浏览器 永远不会 应用 left: 10px
值,因为它不会在函数中途执行任何操作!浏览器只能使用函数的结果,即完成的结果。
正在回答您的问题!!
fiddle 1
left_more
class 紧跟在 left
class 之后 - 浏览器永远不会看到 left
class,并应用css 函数结束后的样式 - 应用 left_more
class,但由于没有初始左值,因此没有动画。 (css 级联;虽然两个 class 都存在,但 left_more
完全覆盖 left
)
fiddle 2
同样的问题 - left
class 在浏览器可以处理之前被覆盖
fiddle 3
这是有效的,因为该值是通过调用 css
设置的,然后不会被覆盖,因为 addClass
用于设置值应该动画到的位置。 console.log
无关紧要 - 重要的是 css
函数调用。一旦该函数完成,就会有两条信息,一条是 css
值,另一条是 class
值。这与另一个例子形成对比,在另一个例子中,函数 运行s 之后只剩下 一条 条信息:class
值。
如果您只想使用 classes,并且仍然要进行转换,则流程必须如下所示:
1) 添加 left
class
2)退出函数,允许浏览器查看状态
3) 添加left_more
class
对不起这篇文章哈哈。但我认为由于问题的微妙性,这需要很长的解释。
当它调用 $('div').css('left')
时,您的转换在案例三中有效,因为 jQuery 将调用 Tim Taubert(Mozilla 员工)的方法 window.getComputedStyle
(or a very similar method depending on browser compatibility issues). In a blog post,技巧如下:
getComputedStyle()
in combination with accessing a property value actually flushes all pending style changes and forces the layout engine to compute our<div>
’s current state.
在不强制重新计算布局的情况下,重新计算会延迟到添加了 类(left
和 left-more
)之后,这将计算其在 400px
的位置.
Example Fiddle - 使用 getComputedStyle
并访问 .left
这里有几个问题。在给出的示例中,添加第一个 left
class 时不会发生转换的原因是,为了让渲染引擎为 属性 设置动画,属性 需要已经有一个值。在这种情况下,left
没有值,因此不会发生转换。
链接时不起作用的原因是因为特异性。 jQuery 将添加两个 classes,并且当调用呈现页面时,由于它们共享的特殊性,将应用最后添加的 left 定义。
在单独的时间添加 class 而不是链式添加似乎起作用的原因是,当 console.log 访问 css 元素的值。 Stryner 在他的回答中指出了这一点:
这是一个应用示例,因此无需猜测 left 的值。
发生的事情的实质是找到元素的偏移量以获得左侧的像素偏移量。然后将该值应用于左侧样式 属性。那时,当元素仍然没有改变位置时,渲染引擎被调用以更新左侧 属性。然后删除 属性 以确保特异性不会优先于 class 定义,然后应用 class 定义。这将有助于第一次相遇时的过渡。
$('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>