2011-08-16 9 views
9

Ho un elemento HTML che ho bisogno di tracciare un altro elemento. Nello specifico, ho bisogno che gli angoli in alto a sinistra e in alto a destra di entrambi gli elementi siano posizionati allo stesso modo. Quando una finestra viene ridimensionata, l'evento di ridimensionamento viene attivato e posso regolare la posizione dell'elemento dipendente. Tuttavia, se l'elemento da tracciare viene riposizionato (ma non ridimensionato), non vedo alcun evento DOM.Come si ascolta un elemento HTML che si muove in JavaScript?

Come possiamo scoprire se un elemento DOM è stato spostato? Stiamo usando l'ultima versione di jQuery.

Ecco un esempio di codice.

Nota che le divisioni elementOne e mouseTracking sono lì per mostrare elementi che vengono spostati per "alcuni" motivi che sono fuori dal controllo del mio codice.

  1. Questo codice funziona per il caso elementOne.
  2. MouseTrackingTracker non traccia un elemento in movimento.
  3. ResizerTracker non inserisce il bordo attorno al testo completo nella causa di overflow.

Vorrei che il trackingDivs si spostasse e ridimensionasse, indipendentemente dal motivo per cui i motivi dell'elemento tracciato cambiano.

Questo codice si basa sul ridimensionamento della finestra come evento associato. Agganciare alcuni eventi che si attivano quando l'elemento cambia le sue dimensioni è più vicino a quello che mi serve.

<!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> 
+0

Puoi mostrare un po 'di codice? Come si riposiziona l'elemento, ecc.? –

+0

esempio aggiunto. Spero che aiuti. – Pat

+0

possibile duplicato di [Come sapere quando un elemento DOM si sposta o viene ridimensionato] (http: // stackoverflow.it/questions/3444719/how-to-know-when-an-dom-element-move-or-is-ridimensionato) – thSoft

risposta

2

C'è l'evento DOMAttrModified, ma la sua impleneted solo in Firefox and Chrome. Ma poiché hai bisogno di una funzione JavaScript per avviare l'elemento in movimento, puoi sparare un custom event with Jquery in questo posto.

+3

e la documentazione elenca gli eventi DOMAttrModified come deprecati :-( – Pat

4

È possibile attivare eventi personalizzati con jquery ogni volta che si riposiziona l'elemento.

$(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") 
    }); 

}); 

Così si può fornire evento da soli si aggancia con un po 'di codifica manuale, che è utile in quanto gli eventi cool come DOMAttrModified e così via, non sono completamente supportate in tutti i browser. Il rovescio della medaglia, devi fare tutto da solo.

+0

Non sto riposizionando l'elemento che sto monitorando Ho provato la tua soluzione e sfortunatamente non funziona per i miei casi d'uso Vedi aggiornamento alla domanda originale – Pat

3

Sfortunatamente, non vi sono eventi affidabili da indicare quando un elemento si sposta o viene ridimensionato. Si potrebbe ricorrere a polling l'elemento, anche se questo non sarà necessariamente la soluzione più performante:

setInterval(repositionElement, 10); 

Un'altra opzione è quella di rendere il vostro elemento "traccia" l'altro elemento puramente attraverso i CSS. Per far funzionare tutto questo, avrete bisogno di un "involucro" attorno all'elemento che stai monitorando, e l'altro elemento:

#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 */ 
} 

Dal momento che si sta già utilizzando jQuery, è anche possibile utilizzare il resize event plugin per simulare la resize event su qualsiasi elemento, ma se ricordo l'ultima volta che l'ho guardato, fa semplicemente il polling come ho detto.

+0

Sto arrivando alla triste conclusione che sei corretto – Pat

+0

Qualche idea su come gestire il testo che scorre al di fuori del elemento (resizer quando viene visualizzato "testo molto lungo"). Le dimensioni del resizer non includono il testo in overflow, tuttavia, devo capire come includere il testo in overflow nel mio bordo e gestire correttamente i clic del mouse sul porzione in eccesso del testo. – Pat

Problemi correlati