jQuery(event): watch element style

余生颓废 提交于 2019-12-18 13:37:23

问题


let say have element like this

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

as we can see the element above style is display: none, how can i make script to watch this element. when that element style is change to display: block then there is some code will be trigger.

many thanks...


回答1:


As far as I know, the only way to do this would be with a timer.

I created a small jQuery plugin (yes, right here, right now) that does this against a jQuery set:

EDIT this plugin is now on 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...
   }
});

To clear this property watcher:

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



回答2:


You may use object.watch function however its non standard, there is already a cross-browser implementation Object.watch() for all browsers?

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



回答3:


function startPolling()
{
    var handle = window.setInterval(function(){

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

    }, 100);
}

When you want to start watching simply write:

startPolling();



回答4:


I wrote a jQuery plugin for watching changes on DOM element properties/attributes and CSS properties that some might find more intuitive/easier to use: jQuery.watch

In order to accomplish what you're after you would do something like this:

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

The plugin also supports tracking the return values of jQuery methods on watched elements, so you could for instance fire a callback when the return value of a jQuery method changes when called on a given element.




回答5:


Since you can't rely on the DOM Mutation Events due to no support for IE before 9, I think you'll be required to set a polling timer to watch. For example:

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);

If you want to cancel the watching after it changes once:

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);



回答6:


This is highly experimental (you have been warned!) and might not be a good fit to your problem or answer to this question, but it has occurred to me that you can do two things:

1 - Override the jQuery's core .toggle method to add some data to the elements it gets applied to.

2 - Bind a changeData event handler to elements, as of jQuery 1.4.4

What that means is, you can make something happen whenever an element gets toggled. The same principle could apply to the .hide and .show methods, or any other methods for that matter.

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

Try it out here: http://jsfiddle.net/karim79/nreqv/1/




回答7:


This might be considered not answering the question, but it would be better to use JQuery custom events and the .trigger method than using intervals and watching (which just consumes resources).

More to the point, elements can subscribe to new triggered events from objects that they are "watch"ing.

Take a look here:

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




回答8:


check 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 are deprecated. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/watch Do not use setInterval solutions!



来源:https://stackoverflow.com/questions/4567987/jqueryevent-watch-element-style

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!