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.
How can we find out if a DOM element has been moved? We are using the latest jQuery.
Here is a code sample.
Note that elementOne
and mouseTracking
divs are there to show elements that get moved for "some" reason that is outside the control of my code.
elementOne
case.MouseTrackingTracker
does not track a moving element.ResizerTracker
does not put the border around the complete text in the overflow case.I would like the trackingDivs to move and resize no matter the reason for the tracked element's reasons for changing.
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>
You can fire custom events with jquery whenever you reposition the element.
$( 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.
Unfortunately, there are no reliable events to tell you when an element moves or is resized. You could resort to polling the 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:
#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 plugin to 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.
There is the DOMAttrModified event, 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 Jquery in this place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With