Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

Shadow DOM与DOM操作

  Shadow DOM确实可以让组件从所在的CSS环境中隔离开来,但程序的节点操作就没那么顺利。虽然外部访问内部元素只能通过一个入口,但默认情况下程序依然可以访问到内部元素。而内部程序访问document时得到的不是当前的文档片段,而是外部的文档,这也很纠结。
<div id="test"></div>
<script>
test.webkitCreateShadowRoot();
//这个webkitShadowRoot属性可以让外部访问Shadow DOM内部的东西
test.webkitShadowRoot.innerHTML="测试";
</script>
  看吧,封装暴露在众目睽睽之下。在谷歌上找到了一个解决这个问题的暴力方法,就是将默认的接口覆写掉。 <div id="test"></div>
<script>
test.webkitCreateShadowRoot();
//覆盖默认的webkitShadowRoot属性
Object.defineProperty(test,"webkitShadowRoot",{get:function(){}});
//这个调用会抛出异常,因此Shadow DOM的内容将不会被非法访问到
test.webkitShadowRoot.innerHTML="测试";
</script>
  另外,从Shadow DOM内部执行脚本也很纠结,毕竟它不是一个JS运行环境的沙盒。 <div id="test"></div>
<template id="temp">
  <div id="a"></div>
  <div id="b"></div>
  <script>
    var s=document.getElementsByTagName("div");
    s=[].map.call(s,function(e){return e.id;});
    console.log(s); //["test"]
  </script>
</template>
<script>
var root=test.webkitCreateShadowRoot();
root.appendChild(document.importNode(temp.content));
</script>
  在Shadow DOM内引用document得到的是全局的document,而我们真正想得到的可能是所在的shadowRoot,所以有时候我们可能要这么写代码。 <div id="test"></div>
<template id="temp">
  <div id="a"></div>
  <div id="b"></div>
  <script>
    var doc=document.currentScript.parentNode;
    var s=doc.getElementsByTagName("div");
    s=[].map.call(s,function(e){return e.id;});
    console.log(s); //["a", "b"]
  </script>
</template>
<script>
var root=test.webkitCreateShadowRoot();
root.appendChild(document.importNode(temp.content));
</script>
  总之,在DOM操作上,Shadow DOM还是有点不利索,也许以后会有更方便的特性。
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^