Класс настраиваемого элемента: this.getAttribute ('data- *') возвращает null

Я скопировал и вставил в код из примера Mozzila https://developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements#Observed_attributes в файлы на моем компьютере, и когда я запускаю его, я получаю ноль при каждом вызове this.getAttribute. Я вижу, что он работает по ссылке выше, но когда я запускаю свой скопированный проект, он равен нулю, то же самое происходит в другом проекте, который я написал, на основе этого примера:

HTML файл:

If nothing appeared below, then your browser does not support Custom Elements yet.
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>

JS файл:

// Create a class for the element
class XProduct extends HTMLElement {
  constructor() {
    // Always call super first in constructor
    super();

    // Create a shadow root
    var shadow = this.attachShadow({mode: 'open'});

    // Create a standard img element and set it's attributes.
    var img = document.createElement('img');
    img.alt = this.getAttribute('data-name');
    img.src = this.getAttribute('data-img');
    img.width = '150';
    img.height = '150';
    img.className = 'product-img';

    // Add the image to the shadow root.
    shadow.appendChild(img);

    // Add an event listener to the image.
    img.addEventListener('click', () => {
      window.location = this.getAttribute('data-url');
    });

    // Create a link to the product.
    var link = document.createElement('a');
    link.innerText = this.getAttribute('data-name');
    link.href = this.getAttribute('data-url');
    link.className = 'product-name';

    // Add the link to the shadow root.
    shadow.appendChild(link);
  }
}

// Define the new element
customElements.define('x-product', XProduct);

person Amalin    schedule 10.03.2017    source источник


Ответы (2)


Вы должны использовать this.getAttribute() в connectedCallback() методе, поскольку атрибуты могут быть еще не определены при вызове метода constructor().

Это тот случай, когда constructor() вызывается сразу после анализа <x-product>, когда его атрибуты еще не прикреплены.


Обратите внимание, что он все равно может работать, если вы поместите инструкцию customElement.define() после html-кода <x-product data-...>. Это связано с тем, что атрибуты уже прикреплены к элементам <x-product>, когда тег определен как настраиваемый элемент.

Дополнительные сведения см. В этом вопросе.

person Supersharp    schedule 10.03.2017
comment
Совершенно верно! Теперь я понимаю, почему теперь он внезапно работает после того, как я переместил функциональность в connectedCallback (), спасибо! - person Amalin; 11.03.2017

Я также столкнулся с этой проблемой, когда getAttribute возвращал null при вызове из конструктора. Я заметил, что в примере индексный файл, тег имеет атрибут defer. Как только я добавил атрибут defer в свой тег скрипта, вызов getAttribute из конструктора начал работать.

person Anthony Tietjen    schedule 17.03.2021