Обнаружение изменений свойств элементов через их атрибуты - JavaScript - PullRequest
0 голосов
/ 05 июля 2018

Мне было интересно, можно ли было обнаружить изменения свойств, внесенные в элементы через их атрибуты.

Например, мы можем добавить наследуемые свойства и методы к элементам, работая с объектом HTMLElement.prototype и его унаследованными прототипами, например ::100100

// Add our global property
HTMLElement.prototype.sandwich = 'double-decker variety';

// Get the <body> element
let body = document.body;
body.sandwich // => 'double-decker variety'

Итак, есть ли способ распространить это на атрибуты элемента?

Или я должен вместо этого работать с Attr.prototype объектом?

// Add our global property
Object.defineProperty(HTMLElement.prototype, 'burger', {
    ...,
    set: function changeBurger(newValue) {
        // Our response
        console.log(`Response: You changed our '${oldValue}' burger to a '${newValue}'`)
    }
});

// Get the <body> element
let body = document.body;

// Response: You changed our 'king-sized' burger to a 'family pack'
body.burger = 'family pack';

// Response: You changed our 'family pack' burger to a 'kids delight'
body.setAttribute('burger', 'kids delight');

Приведенный выше пример также должен применяться к элементам, которых нет в DOM или текущем документе, т. Е. Объектам, инициализированным из конструктора HTMLElement.

Извините, если вопрос кажется немного расплывчатым, и я надеюсь, что приведенные мной примеры могут прояснить тему вопроса.

Спасибо всем, кто хочет найти время, чтобы ответить.

1 Ответ

0 голосов
/ 05 июля 2018

Правильный способ для расширения HTMLElement использует CustomElements , Существует обратный вызов жизненного цикла с именем attributeChangedCallback.

Затем при установке атрибута с помощью objectName.setAttribute ('attrName', 'attrValue') эта функция вызывается.

Вы также можете использовать MutationObserver с config={attributes:true} (будьте осторожны, неправильная реализация сильно повредит производительности).

Другой способ достижения этого - написать функцию, которая читает все атрибуты и конвертирует их в методы установки / получения ... что-то вроде этого

    class WatchableObject{
            constructor(){
                this.handler = ()=>{};
            }
            watch(handler){
                if(!this.beingWatched()) {
                    delete this.handler;

                    let properties = Object.getOwnPropertyNames(this);
                    properties.forEach((prop) => {
                        if (this.hasOwnProperty(prop)) {
                            Object.defineProperty(this, prop, {
                                set: (newValue) => {
                                    let oldValue = this["_" + prop];
                                    this["_" + prop] = newValue;
                                    this.handler.call(this,oldValue,newValue);
                                },
                                get: () => {
                                    return this["_" + prop];
                                }
                            });
                        }
                    });
                }
                this.handler = handler;
            }
            unwatch(){
                this.watch(()=>{});
            }
            beingWatched(){
                return (this.handler.toString() != "()=>{}");
            }
    }

    let a = new WatchableObject();
    a.b = "hello";
    a.c = "daniel";
    a.watch(()=>{alert("a change has been made.")});
    a.b = "bye";
    a.unwatch();
    a.b = "hello again";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...