你如何监听 JavaScript 中移动的 HTML 元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7074907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 22:52:42  来源:igfitidea点击:

How do you listen for a HTML element moving in JavaScript?

javascriptjqueryjavascript-events

提问by Pat

I have an HTML element that I need to track another element. Specifically, I need to have the top left and top right corners of both elements be positioned the same. When a window gets resized, the resize event gets triggered and I can adjust the position of the dependent element. However, if the element being tracked is repositioned (but not resized), I do not see any DOM event.

我有一个 HTML 元素,我需要跟踪另一个元素。具体来说,我需要让两个元素的左上角和右上角的位置相同。当窗口调整大小时,会触发调整大小事件,我可以调整依赖元素的位置。但是,如果被跟踪的元素被重新定位(但没有调整大小),我看不到任何 DOM 事件。

How can we find out if a DOM element has been moved? We are using the latest jQuery.

我们如何知道一个 DOM 元素是否被移动了?我们正在使用最新的 jQuery。

Here is a code sample.

这是一个代码示例。

Note that elementOneand mouseTrackingdivs are there to show elements that get moved for "some" reason that is outside the control of my code.

请注意,elementOnemouseTrackingdiv 用于显示因“某种”原因而移动的元素,这些原因超出了我的代码的控制范围。

  1. This code works for the elementOnecase.
  2. MouseTrackingTrackerdoes not track a moving element.
  3. ResizerTrackerdoes not put the border around the complete text in the overflow case.
  1. 此代码适用于这种elementOne情况。
  2. MouseTrackingTracker不跟踪移动元素。
  3. ResizerTracker在溢出情况下不会在完整文本周围放置边框。

I would like the trackingDivs to move and resize no matter the reason for the tracked element's reasons for changing.

无论被跟踪元素的更改原因是什么,我都希望 trackingDivs 能够移动和调整大小。

This code relies on the window resize being the hooked event. Hooking some event that fires when the element changes its dimensions is closer to what I need.

此代码依赖于作为挂钩事件的窗口调整大小。钩住一些在元素改变其尺寸时触发的事件更接近我需要的。

<!DOCTYPE html>
<html>
<head>
  <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.js"></script>
  <style type="text/css">
#elementOne { float : right;width : 200px; display:inline-block}
#resizer { float : left; display:inline-block}
.trackedDiv { width:50px; height:50px; background-color: blue }
.trackingDiv { position:absolute; z-index: 1; border:3px green; border-style: solid;}
</style>
<script>
  $(function() {
      $( window ).bind("resize",function(){
          $("#elementOne").trigger("reposition");
          $("#mouseTracking").trigger("reposition");
          $("#resizer").trigger("reposition");
       });

       var repositionFunction = function(selfish, element){
           var self = $(selfish);
           var offset = self.offset();
           var selfTop = offset.top;
           var selfLeft = offset.left;

           var selfWidth = self.width();
           var selfHeight = self.height();
           $(element).css({
              top: selfTop,
              left: selfLeft,
              width : selfWidth,
              height : selfHeight
           });
       }
       $(document).mousemove(function(ev){
           $("#mouseTracking").position({
             my: "left bottom",
             of: ev,
             offset: "3 -3",
             collision: "fit"
           });
         });

       var timedShort = function() {
           $('#resizer').html("Really short").resize();
           setTimeout(timedLong, 10000);
       }
       var timedLong = function() {
           $('#resizer').html("Really longggggggggggggggggggggggggggggggggggggggggggggggggggg text").resize();
           setTimeout(timedShort, 10000);
       }
       setTimeout(timedLong, 10000);

       $("#elementOne").bind("reposition",
               function() { repositionFunction(this, "#elementOneTracker"); });
       $("#mouseTracking").bind("reposition",
               function() { repositionFunction(this, "#mouseTrackingTracker"); });
       $("#resizer").bind("reposition",
               function() { repositionFunction(this, "#resizerTracker"); });
  });
  </script>
</head>
<body>
  <div class="trackedDiv" id="mouseTracking">tracks mouse</div>
  <div class="trackingDiv" id="mouseTrackingTracker"></div>
  <div style="clear:both;"></div>
  <div class="trackedDiv" id="resizer">resizer: resizes</div>
  <div class="trackingDiv" id="resizerTracker"></div>
  <div class="trackedDiv" id="elementOne">elementOne: floats to the right</div>
  <div class="trackingDiv" id="elementOneTracker"></div>
</body>
</html>

回答by BGerrissen

You can fire custom events with jquery whenever you reposition the element.

每当您重新定位元素时,您都可以使用 jquery 触发自定义事件。

$( window ).bind("resize",function(){

   $("#elementOne").css({
      top: 200,
      left: 200
   }).trigger("reposition");

});

// and now you can listen to a "reposition event"

$("#elementOne").bind("reposition",function(){

   var self = $(this);
   $("#elementTwo").css({
      top: self.css("top"),
      left: self.css("left")
   });

});

So you can provide event hooks yourself with some manual coding, which is useful since cool events like DOMAttrModified and so on, are not fully supported in all browsers. The downside, you have to do it all yourself.

因此,您可以通过一些手动编码自己提供事件挂钩,这很有用,因为并非所有浏览器都完全支持 DOMAttrModified 等很酷的事件。不利的一面是,您必须自己完成所有工作。

回答by Jacob

Unfortunately, there are no reliable events to tell you when an element moves or is resized. You could resort to pollingthe element, though that won't necessarily be the most performant solution:

不幸的是,当元素移动或调整大小时,没有可靠的事件告诉您。您可以使用轮询元素,尽管这不一定是性能最高的解决方案:

setInterval(repositionElement, 10);

Another option is to make your element "track" the other element purely through CSS. For this to work, you'll need a "wrapper" around the element you're tracking, and the other element:

另一种选择是让您的元素完全通过 CSS“跟踪”另一个元素。为此,您需要在要跟踪的元素和另一个元素周围使用“包装器”:

#wrapper-around-element-to-track
{
    position: relative;
} 

#tracked-element
{
    position: absolute;
    /* set top and left to position, if necessary */
}

#tracking-element
{
    position: absolute;
    /* set top and left to position, if necessary */
}

Since you're already using jQuery, you can also use the resize event pluginto simulate the resize event on any element, but if I recall the last time I looked at it, it simply does the polling like I mentioned.

由于您已经在使用 jQuery,您还可以使用resize 事件插件来模拟任何元素上的 resize 事件,但如果我记得上次查看它时,它只是像我提到的那样进行轮询。

回答by Andreas K?berle

There is the DOMAttrModifiedevent, but its only impleneted in Firefox and Chrome. But as you need a JavaScript function to start the element moving, you can firing a custom event with Jqueryin this place.

DOMAttrModified事件,但它只在Firefox 和 Chrome 中实现。但是由于您需要一个 JavaScript 函数来开始移动元素,您可以在这个地方使用 Jquery触发一个自定义事件