简体   繁体   中英

does onchange event internally listens to setter for element's accessors?

I know, to register our own elementTypes, we use

Object.defineProperties(ElementPrototype,{
 get: function(){

 },
 set: function(newVal) {

 }
});

now it works fine for value attribute as long as i am not attaching onchange listener, but in case i do , this setter is never called, one reason i can think of is that this onchange internally overrides my setter and put its own, which leads to my setter never being called. so doing

elem.value = "newvalue";

will not trigger my setter function. So

First is my conclusion correct?

2nd what is work around?

Edit :- Assuming ElementType is my own Copy of Element, i am not trying to modify existing Tag Element,

Host objects are only required to provide minimal support for ECMAScript features. See ECMAScript §4 : " …host objects, whose description and behaviour are beyond the scope of this specification except to indicate that they may provide certain properties that can be accessed and certain functions that can be called from an ECMAScript program ".

For example, browsers aren't required to support prototype inheritance for DOM objects (though most of them do). It's also evident in how host objects are given special treatment in various parts of ECMA-262, eg for the typeof operator .

The bottom line is that host objects aren't required to support all features of ECMAScript, you should only expect them to support the features they provide through published documentation.

More generally, there is a principle that you shouldn't mess with objects that you don't own. That is, don't add properties and behaviours to host, built–in or other script objects unless you have explicit permission to do so. The primary reasons are:

  1. Host objects may be implemented differently in different hosts, so something that "works" in one host may not (or throw errors) in another.

  2. Features being added by script may be added in a later version of the host environment, causing conflicts that aren't easily resolved (eg jQuery's each method, introduced while ECMAScript ed 3 was the specification, has a different name and takes parameters in a different order than the ES5 forEach method, introduced later)

  3. If modifying host or built–in objects by 3rd party scripts becomes de rigour , feature testing will become extremely difficult. It's easy enough to test for a feature, but not so easy to tell which implementation of a particular feature you're dealing with (eg order and number of parameters), further increasing complexity.

Modifying other native objects is sometimes OK, eg if you have a plugin, it may have a settings or parameters object that you can modify, but you shouldn't go replacing entire methods.

If you want to extend the behaviour of a host object, create a proxy and use that.

I may be wrong, but it seems like what you want to do is fire a change event on your custom element when its value attribute is changed. This is how you could do that.

Define component

xtag.register('my-element', {
    accessors: {
        value: {
            attribute: {},
            get: function () {
                return this._value;
            },
            set: function (v) {
                if (v === this._value) return; // unchanged

                var change = { from: this._value, to: v }; // optional

                this._value = v; // set new value

                xtag.fireEvent(this, 'change', { // event
                    detail: change,
                    bubbles: true,
                    cancelable: true
                });
            }
        }
    }
});

HTML

<my-element value="2"></my-element>

Try it out

var el = document.querySelector('my-element');

// add event listener

el.addEventListener('change', function (e) {
    console.log('value changed from %s to %s', e.detail.from, e.detail.to);
});

// change the value

el.value = 4; 

// this will cause the 'change' event to fire
// the listener will output this to the console:

// "value changed from 2 to 4"

Because we've set the change event's bubbles option to true , we can also use event delegation.

xtag.addEvent(document.body, 'change:delegate(my-element)', function (e) {
    console.log('Value of <my-element> somewhere in <body> changed');
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM