Использование jQuery в Internet Explorer для проникновения в теневой DOM

Я пытаюсь использовать jQuery внутри веб-компонента Angular Elements с инкапсуляцией ShadowDom и сталкиваюсь с проблемами с Internet Explorer, в частности с IE11. Ошибка возникает при разрешении в shadowRoot и последующем использовании метода поиска jQuery с селектором, отличным от идентификатора. Сообщение об ошибке:

Unable to get property 'length' of undefined or null reference

Я создал простую страницу, чтобы изолировать проблему, и смог воспроизвести ту же ошибку.

    <h2>Hello from outside the Shadow DOM!</h2>

    <div class='parent'></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/shadydom/1.1.0/shadydom.min.js"></script>
    <script
      src="https://code.jquery.com/jquery-3.4.1.js"
      integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
      crossorigin="anonymous"></script>

    <script>
      // Setup an element in the shadow DOM
      var element = $('.parent')[0];
      var shadow = element.attachShadow({mode: 'open'});

      var text = document.createElement('span');
      text.id = 'subtitle';
      text.textContent = 'Hello from inside the Shadow DOM!';

      shadow.appendChild(text);      
      //-- End Setup

      // This is how the web component code is getting access to the shadow root
      var shadowRoot = $(element.shadowRoot);

      // No problems with this find call
      var subtitle = shadowRoot.find('#subtitle');

      // IE Bug is triggered here
      var span = shadowRoot.find('span');

      console.log('jQuery set count: ' + span.length);
    </script>

А вот стек при возникновении ошибки:

Трассировка стека ошибок

Это известная проблема с jQuery и проникновением в теневой DOM в IE11? Есть какие-нибудь решения?


person redfish819    schedule 26.03.2020    source источник


Ответы (2)


Я нашел обходной путь, который стабильно работает в IE11 и Chrome. Помещение теневых элементов DOM в контейнер div с идентификатором позволяет разрешить контейнер и найти элементы из этого контекста. Вот обновленный код:

<script>
  // Setup an element in the shadow dom
  var element = $('.parent')[0];
  var shadow = element.attachShadow({mode: 'open'});

  var container = document.createElement('div');
  container.id = 'container';
  container.innerHTML = '<span>Hello from inside the Shadow DOM!</span>'

  shadow.appendChild(container);      
  //-- End Setup

  // This is how site search get access to the shadow root
  var shadowRoot = $(element.shadowRoot);

  // Use the shadow root to resolve to the cotnainer by ID 
  // and then finding any other elements in the shadow DOM
  // works as expected.
  var container = shadowRoot.find('#container');
  var span = container.find('span');

  console.log('jQuery set count: ' + span.length);

</script> 
person redfish819    schedule 28.03.2020

После использования инструментов разработчика F12 для отладки javascript мы видим, что диапазон не определен. Таким образом, он покажет ошибку «Невозможно получить длину свойства неопределенной или нулевой ссылки».

Чтобы решить эту ошибку, попробуйте найти элемент span из переменной «element», а не из «shadowRoot». проверьте следующий код:

<script>
    // Setup an element in the shadow DOM
    var element = $('.parent')[0];
    var shadow = element.attachShadow({ mode: 'open' });

    var text = document.createElement('span');
    text.id = 'subtitle';
    text.className = "spanitem";
    text.textContent = 'Hello from inside the Shadow DOM!';

    shadow.appendChild(text);
    //-- End Setup

    // This is how the web component code is getting access to the shadow root
    var shadowRoot = $(element.shadowRoot);

    // No problems with this find call
    var subtitle = shadowRoot.find('#subtitle');

    // 
    var span = $(element).find('span');

    console.log('jQuery set count: ' + span.length); 
</script>
person Zhi Lv    schedule 27.03.2020
comment
Спасибо за Ваш ответ. Я проверил ваши изменения и увидел, что они дают ожидаемый результат в IE11, но не работают правильно в Chrome. В Chrome span.length равен нулю, что имеет смысл, поскольку предполагается, что теневая DOM предотвращает выбор содержащихся в ней элементов из запросов, выполняемых вне ее. Ссылка на shadowRoot - это способ доступа к его элементам. Похоже, что jQuery некорректно работает с теневой DOM в IE11 по разным причинам. - person redfish819; 27.03.2020