检测由 CSS 过渡引起的 HTML 元素的移动
Posted
技术标签:
【中文标题】检测由 CSS 过渡引起的 HTML 元素的移动【英文标题】:Detect movement of HTML element caused by CSS transitions 【发布时间】:2013-04-06 00:30:21 【问题描述】:我的页面上有一个 Flash 元素,由于 Flash 通常非常精细,因此需要将其定位在整数像素值处(如果需要详细信息,请参阅 Flash webcam access request prompt unresponsive)。
我通过将object
包装在div
中、在object
上设置position:absolute
并使用jQuery 将left
和top
设置为圆角的offset
来实现这一点包含div
。那是一口,这里是代码形式:
<div id="wrapper">
<object id="flash" blah style="position:absolute">
<!-- blah -->
</object>
</div>
<script>
function update()
var p=$('#wrapper').offset();
$('#flash').css('left':Math.round(p.left),'top':Math.round(p.top));
$(document).ready(function()
$(window).resize(update);
update();
);
</script>
而且一切都很好(如果上面的代码有错误,那只是将其删减)
这将在浏览器改变大小时更新位置,当位置被一些 javascript 改变时更新它很容易,但是页面也使用 CSS transition-duration
来动画一些变化。我怎样才能检测到这个?至少,我想检测影响对象的过渡何时发生,并知道它何时停止。理想情况下,我想知道如何捕捉任何运动(例如由字体大小更改或图像加载引起的)。
【问题讨论】:
有一些关于过渡的事件,但我不知道它们有多大用处 您可以检测到过渡何时完成,但仍无法检测到过渡何时开始,至少我不知道。搜索 transitionend 事件 @roasted 谢谢,这是一个开始。它至少现在最终定位正确。如果可能的话,我仍然想在动画期间定位它。致未来的读者:.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend',update);
所以我想没有一个理想的解决方案。也许,在制作动画之前,您可以使用 JS 来检测是否设置了 CSS 过渡。而且我不知道这是否适用于您的情况,但也许最好使用 translate 移动元素; Paul Irish wrote a good article about this.
@sroes translate 不适用,遗憾的是。这样做的重点是删除子像素定位,但 translate 支持子像素并且不够聪明,无法采用方程参数(我需要通过 floor(absolute_coord) - absolute_coord
进行翻译)。
【参考方案1】:
你能检查一下这个小提琴吗:http://jsfiddle.net/DpYNm/ 它会记录运动的开始和结束时间,我不确定它是否能解决您的问题,但它可能会帮助您朝着正确的方向前进!
function checkForMove()
if ($('#testDiv').prop('user_default_width') === undefined)
$('#testDiv').prop('user_default_width', $('#testDiv').width());
$('#testDiv').prop('user_is_moving', false);
if ($('#testDiv').width() != $('#testDiv').prop('user_default_width') && !$('#testDiv').prop('user_is_moving'))
$('#log').html($('#log').html() + "Move started<br/>");
$('#testDiv').prop('user_is_moving', true);
if ($('#testDiv').width() == $('#testDiv').prop('user_default_width') && $('#testDiv').prop('user_is_moving'))
$('#log').html($('#log').html() + "Move ended<br/>");
$('#testDiv').prop('user_is_moving', false);
setTimeout(checkForMove, 1);
checkForMove();
checkForMove 每毫秒调用一次,在第一次调用中,它将 div 的宽度保存到一个属性中。每次它发生变化(转换开始)时,它都会记录并保存一个辅助属性,以确保在转换恢复到默认大小之前不会再次记录。我相信您可以更改该部分以适合您的需求! :)
【讨论】:
每毫秒?!冷酷的!无论如何,我知道我可以使用间隔(你应该使用setInterval
而不是 setTimeout
来处理这样的事情;超时很浪费),但我正在寻找一个事件驱动的解决方案。
我认为没有事件驱动的解决方案。但是,您可以增加超时时间,尽管 1 毫秒对于 cpu 来说是很多时间,即使在 javascript 中也是如此。关于 setTimeout 和 setInterval 之间的区别:它们本质上是相同的,但是 setInterval 将每 x 毫秒执行一次,而我使用 setTimeout 的方式意味着只有在超时中的代码执行完毕后,计时器才会重新启动。 Afaik 他们在内部使用相同的机制。以上是关于检测由 CSS 过渡引起的 HTML 元素的移动的主要内容,如果未能解决你的问题,请参考以下文章