【问题标题】:Detect movement of HTML element caused by CSS transitions检测由 CSS 过渡引起的 HTML 元素的移动
【发布时间】:2013-04-06 00:30:21
【问题描述】:

我的页面上有一个 Flash 元素,由于 Flash 通常非常精细,因此需要将其定位在整数像素值处(如果需要详细信息,请参阅 Flash webcam access request prompt unresponsive)。

我通过将object 包装在div 中、在object 上设置position:absolute 并使用jQuery 将lefttop 设置为圆角的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 进行翻译)。

标签: javascript jquery dom css-transitions


【解决方案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 他们在内部使用相同的机制。
猜你喜欢
  • 1970-01-01
  • 2018-09-23
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
相关资源
最近更新 更多