【问题标题】:Using jQuery in Internet Explorer to Pierce Shadow DOM在 Internet Explorer 中使用 jQuery 来穿透 Shadow DOM
【发布时间】:2020-07-07 11:09:36
【问题描述】:

我正在尝试在带有 ShadowDom 封装的 Angular Elements Web 组件中使用 jQuery,但遇到了 Internet Explorer 问题,特别是 IE11。解析到 shadowRoot 并使用 jQuery find 方法和 ID 以外的选择器时会触发错误。错误信息是:

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 的一个已知问题并在 IE11 中穿透 shadow DOM?有什么解决办法吗?

【问题讨论】:

    标签: jquery internet-explorer-11 web-component shadow-dom angular-elements


    【解决方案1】:

    我找到了一种在 IE11 和 Chrome 上始终有效的解决方法。将 shadow DOM 元素放在具有 ID 的容器 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> 
    

    【讨论】:

      【解决方案2】:

      使用F12开发者工具调试javascript后,可以看到span是未定义的。因此,它将显示“无法获取未定义或空引用的属性'长度'”错误。

      要解决此错误,请尝试从“element”变量中查找 span 元素,而不是从“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>
      

      【讨论】:

      • 感谢您的回答。我运行了您的更改,发现它在 IE11 中提供了预期的结果,但在 Chrome 中无法正常工作。在 Chrome 中,span.length 等于 0,这是有道理的,因为影子 DOM 应该防止从外部执行的查询中选择它包含的元素。引用 shadowRoot 是访问其元素的方式。看起来 jQuery 在 IE11 中以多种方式无法与 shadow DOM 一起正常工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多