Cross-browser Getter and Setter

前端 未结 4 451
误落风尘
误落风尘 2020-12-23 17:52

This works in modern Chrome/Firefox/Opera but fails in IE8. Haven\'t tried it in IE9. How can I make this cross-browser compatible, including IE7+? (Fiddle here.)

         


        
相关标签:
4条回答
  • 2020-12-23 18:30

    Here is the workaround for IE6/7/8. I performed the test and it works very well!

    Update: The link is broken, you can see the code of from my testing here:

        // Super amazing, cross browser property function, based on http://thewikies.com/
    function addProperty(obj, name, onGet, onSet) {
    
        // wrapper functions
        var
            oldValue = obj[name],
            getFn = function () {
                return onGet.apply(obj, [oldValue]);
            },
            setFn = function (newValue) {
                return oldValue = onSet.apply(obj, [newValue]);
            };
    
        // Modern browsers, IE9+, and IE8 (must be a DOM object),
        if (Object.defineProperty) {
    
            Object.defineProperty(obj, name, {
                get: getFn,
                set: setFn
            });
    
        // Older Mozilla
        } else if (obj.__defineGetter__) {
    
            obj.__defineGetter__(name, getFn);
            obj.__defineSetter__(name, setFn);
    
        // IE6-7
        // must be a real DOM object (to have attachEvent) and must be attached to document (for onpropertychange to fire)
        } else {
    
            var onPropertyChange = function (e) {
    
                if (event.propertyName == name) {
                    // temporarily remove the event so it doesn't fire again and create a loop
                    obj.detachEvent("onpropertychange", onPropertyChange);
    
                    // get the changed value, run it through the set function
                    var newValue = setFn(obj[name]);
    
                    // restore the get function
                    obj[name] = getFn;
                    obj[name].toString = getFn;
    
                    // restore the event
                    obj.attachEvent("onpropertychange", onPropertyChange);
                }
            };  
    
            obj[name] = getFn;
            obj[name].toString = getFn;
    
            obj.attachEvent("onpropertychange", onPropertyChange);
    
        }
    }
    
    0 讨论(0)
  • 2020-12-23 18:31

    There is a "definePropery" method that will essentially allow you to create accessor methods (getters/setters) on Objects without the need to invoke a function call like setProp() / getProp().

    The syntax is a little weird but I've been able to get this to work on Firefox, Chrome, Safari and IE9.

    Say I have JavaScript Object called "Person".

    function Person()
    {
     // set a default value //
        this.__name = 'John';
     // add getter & setter methods //
        Object.defineProperty(this, "name", {
            get: function() {
            // additional getter logic
                return this.__name;
            },
            set: function(val) {
                this.__name = val;
            // additional setter logic
            }
        });
    }
    
    var p = new Person();
    console.log(p.name); // 'John'
    p.name = 'Stephen';
    console.log(p.name); // 'Stephen'
    

    More info on Mozilla's site here.

    0 讨论(0)
  • 2020-12-23 18:34

    I don't believe you can.

    In IE8 and lower, property access is mere property access. There's no way to run function code without explicitly invoking the function.

    I think in IE8 you may be able to with DOM elements, but I don't believe it works for regular native objects.

    0 讨论(0)
  • 2020-12-23 18:38

    You cannot, the syntax is not supported in browsers that did not implement it. Its going to be quite a while before you'll be able to use that syntax without having CBC problems. Be grateful IE6 is pretty much dead in North America.

    0 讨论(0)
提交回复
热议问题