Detect if an element has been resized via javascript?

后端 未结 3 870
南方客
南方客 2020-12-16 11:44

Is it possible to simply add event listeners to certain elements to detect if their height or width have been modified? I\'d like do this without using something intensive l

3条回答
  •  南方客
    南方客 (楼主)
    2020-12-16 12:43

    Here is a jQuery plugin with watch and unwatch methods that can watch particular properties of an element. It is invoked as a method of a jQuery object. It uses built-in functionality in browsers that return events when the DOM changes, and uses setTimeout() for browsers that do not support these events.

    The general syntax of the watch function is below:

    $("selector here").watch(props, func, interval, id);
    
    • props is a comma-separated string of the properties you wish to watch (such as "width,height").
    • func is a callback function, passed the parameters watchData, index, where watchData refers to an object of the form { id: itId, props: [], func: func, vals: [] }, and index is the index of the changed property. this refers to the changed element.
    • interval is the interval, in milliseconds, for setInterval() in browsers that do not support property watching in the DOM.
    • id is an optional id that identifies this watcher, and is used to remove a particular watcher from a jQuery object.

    The general syntax of the unwatch function is below:

    $("selector here").unwatch(id);
    
    • id is an optional id that identifies this watcher to be removed. If id is not specified, all watchers from the object will be removed.

    For those who are curious, the code of the plugin is reproduced below:

    $.fn.watch = function(props, func, interval, id) {
        /// 
        /// Allows you to monitor changes in a specific
        /// CSS property of an element by polling the value.
        /// when the value changes a function is called.
        /// The function called is called in the context
        /// of the selected element (ie. this)
        ///     
        /// CSS Property to watch. If not specified (null) code is called on interval    
        /// 
        /// Function called when the value has changed.
        ///     
        /// 
        /// optional id that identifies this watch instance. Use if
        /// if you have multiple properties you're watching.
        /// 
        /// A unique ID that identifies this watch instance on this element  
        ///  
        if (!interval)
            interval = 200;
        if (!id)
            id = "_watcher";
    
        return this.each(function() {
            var _t = this;
            var el = $(this);
            var fnc = function() { __watcher.call(_t, id) };
            var itId = null;
    
            if (typeof (this.onpropertychange) == "object")
                el.bind("propertychange." + id, fnc);
            else if ($.browser.mozilla)
                el.bind("DOMAttrModified." + id, fnc);
            else
                itId = setInterval(fnc, interval);
    
            var data = { id: itId,
                props: props.split(","),
                func: func,
                vals: []
            };
            $.each(data.props, function(i) { data.vals[i] = el.css(data.props[i]); });
            el.data(id, data);
        });
    
        function __watcher(id) {
            var el = $(this);
            var w = el.data(id);
    
            var changed = false;
            var i = 0;
            for (i; i < w.props.length; i++) {
                var newVal = el.css(w.props[i]);
                if (w.vals[i] != newVal) {
                    w.vals[i] = newVal;
                    changed = true;
                    break;
                }
            }
            if (changed && w.func) {
                var _t = this;
                w.func.call(_t, w, i)
            }
        }
    }
    $.fn.unwatch = function(id) {
        this.each(function() {
            var w = $(this).data(id);
            var el = $(this);
            el.removeData();
    
            if (typeof (this.onpropertychange) == "object")
                el.unbind("propertychange." + id, fnc);
            else if ($.browser.mozilla)
                el.unbind("DOMAttrModified." + id, fnc);
            else
                clearInterval(w.id);
        });
        return this;
    }
    

提交回复
热议问题