2010-12-31 10 views
6

diciamo avere elemento come questojQuery (evento): guardare stile elemento

<div class="watch-me" style="display: none;">Watch Me Please</div> 

come possiamo vedere l'elemento sopra stile è display: none, come posso fare script per guardare questo elemento. quando lo stile di quell'elemento è modificato su display: block, verrà generato un codice.

molte grazie ...

risposta

17

Per quanto ne so, l'unico modo per fare questo sarebbe con un timer.

ho creato un piccolo plugin per jQuery (sì, proprio qui, in questo momento) che fa questo nei confronti di un set di jQuery:

EDIT questo plugin è ora su GitHub: https://github.com/jacobrelkin/jquery-watcher

$.fn.watch = function(property, callback) { 
    return $(this).each(function() { 
     var self = this; 
     var old_property_val = this[property]; 
     var timer; 

     function watch() { 
      if($(self).data(property + '-watch-abort') == true) { 
      timer = clearInterval(timer); 
      $(self).data(property + '-watch-abort', null); 
      return; 
      } 

      if(self[property] != old_property_val) { 
      old_property_val = self[property]; 
      callback.call(self); 
      } 
     } 
     timer = setInterval(watch, 700); 
    }); 
}; 

$.fn.unwatch = function(property) { 
    return $(this).each(function() { 
     $(this).data(property + '-watch-abort', true); 
    }); 
}; 

Usage :

$('.watch-me').watch('style', function() { 
    //"this" in this scope will reference the object on which the property changed 
    if($(this).css('display') == 'block') { 
     //do something... 
    } 
}); 

Per cancellare questa proprietà watcher:

$('.watch-me').unwatch('style'); 
+1

L'ho provato localmente e funziona. :) –

+1

Per tutti gli interessati: https://github.com/jrelkin/jquery-watcher –

+0

e quindi quale sarà il codice qui? '//" questo "in questo ambito farà riferimento all'oggetto su cui è stata modificata la proprietà' – GusDeCooL

1

Dal momento che non si può fare affidamento sul DOM Mutation Events a causa di alcun supporto per IE prima delle 9, io penso ti verrà richiesto di impostare un timer di polling per guardare. Per esempio:

var watched = $('.watch-me'); 
var lastDisplay = watched.css('display'); 

// Peek at the property about twice per second 
setInterval(function(){ 
    var curDisplay = watched.css('display'); 
    if (curDisplay!=lastDisplay){ 
    // Do what you want here. 
    lastDisplay = curDisplay; 
    } 
},500); 

Se si desidera annullare l'osservazione dopo che cambia una volta:

var watched = $('.watch-me'); 
var lastDisplay = watched.css('display'); 
var timer = setInterval(function(){ 
    if (watched.css('display')!=lastDisplay){ 
    // Do what you want here. 
    clearInterval(timer); 
    } 
},500); 
3
function startPolling() 
{ 
    var handle = window.setInterval(function(){ 

     var element = $(".watch-me"); 
     if (element.css("display") == "block") { 
      // trigger the event 
      window.clearInterval(handle); 
     } 

    }, 100); 
} 

Quando si desidera iniziare a guardare è sufficiente scrivere:

startPolling(); 
9

Si può utilizzare la funzione object.watch tuttavia non è standard, esiste già un'implementazione cross-browser Object.watch() for all browsers?

$('.watch-me').get(0).watch('style', handlerFunction); 
+0

+1 ma lo hai scritto tu stesso? :) Immagino che il brio valga ancora qualcosa. – Ziggy

0

Questo è altamente sperimentale (siete stati avvertiti!) E potrebbe non essere una buona misura per il vostro problema o di rispondere a questa domanda, ma è venuto in mente che si possono fare due cose:

1 - Sostituisci il metodo core .toggle di jQuery per aggiungere alcuni dati agli elementi a cui viene applicato.

2 - associare un gestore di eventi changeData agli elementi, come di jQuery 1.4.4

Ciò significa, si può far succedere qualcosa ogni volta che un elemento viene attivata. Lo stesso principio potrebbe applicarsi ai metodi e .show oa qualsiasi altro metodo.

// 1 - override .toggle() 
var original = jQuery.fn.toggle; 
jQuery.fn.toggle = function() { 
    console.log("Override method: toggle()"); 

    // call the original toggle 
    original.apply(this, arguments); 

    // record the element's visibility 
    $(this).data("visible", $(this).is(":visible")); 

    return this; 
}; 

// 2 - bind a changeData event handler to a 'watch list' 
$('div').bind("changeData", function() { 
    alert("Visibility changed to: " + $.data(this, 'visible')); 
}); 

<!-- exhaustive test markup --> 
<div id="test">Hello</div> 
<div id="test2" style="display:none">Hello 2</div> 

// go! 
$(document).ready(function() { 
    $("#test").toggle(); 
    $("#test2").toggle(); 
}); 

Provalo qui: http://jsfiddle.net/karim79/nreqv/1/

2

ho scritto un plugin jQuery per la visione di modifiche sul DOM proprietà degli elementi/attributi e le proprietà CSS che alcuni potrebbero trovare più intuitivo/più facile da utilizzare: jQuery.watch

Per ottenere ciò che desideri, devi fare qualcosa del genere:

$('.watch-me').watch({ 
    'display': function(oldVal, newVal, elm) { 
     if (newVal == 'block') { 
      // Do something 
     } 
    } 
}); 

Il plugin supporta anche tenere traccia dei valori di ritorno dei metodi jQuery sugli elementi osservati, in modo da poter, ad esempio, attivare un callback quando il valore di ritorno di un metodo jQuery cambia quando viene chiamato su un determinato elemento.

0

Questo potrebbe non essere considerato come risposta alla domanda, ma sarebbe meglio utilizzare gli eventi personalizzati JQuery e il metodo .trigger piuttosto che utilizzare intervalli e guardare (che consuma solo risorse).

Più precisamente, gli elementi possono sottoscrivere nuovi eventi attivati ​​da oggetti che stanno "guardando".

Date un'occhiata qui:

http://www.sitepoint.com/jquery-custom-events/

0

controllo https://developer.mozilla.org/en/docs/Web/API/MutationObserver

var target = _DOM_; 
var lastDisplayStyle = _DOM_.style.display; 
var observer = new MutationObserver(function (mutations) { 
    mutations.forEach(function (mutation) { 
     if (mutation.type === "attributes") { 
      if (lastDisplayStyle !== _DOM_.style.display){ 
       // your code there 
      } 
     } 
    }); 
}); 

var config = { attributes: true }; 
observer.observe(target, config); 

P.S. watch/unwatch sono deprecati. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/watch Non utilizzare le soluzioni setInterval!