不管是link导入的样色还是<style>标签样色都可以被隔离,不影响shadow dom外层的样式
代码
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="UTF-8">
<Meta http-equiv="X-UA-Compatible" content="IE=edge">
<Meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrap {
background: red;
padding: 10px;
}
.Box {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div class="wrap">
123
<div class="Box">
<div class="wrap">
原来的内容,开启attachShadow后,不在显示
</div>
</div>
</div>
<script>
window.addEventListener("DOMContentLoaded", function() {
var Box = document.querySelector(".Box");
//开启沙箱模式
/**
* mode 参数:
* open控制显示
* closed控制不显示
* attachShadow 函数不能多次调用,
* **/
Box.attachShadow({
mode: 'open'
});
var shadow = Box.shadowRoot;
var gloal = "gloal";
//样色隔离 DEMO1============================================
var style = document.createElement("style");
var innerH = `
.wrap{
background:green;
width:200px;
height:200px;
}
`;
style.innerHTML = innerH;
shadow.appendChild(style);
var wrapShadowBox = document.createElement("div");
wrapShadowBox.className = "wrap";
shadow.appendChild(wrapShadowBox);
//样色隔离 DEMO2============================================
var style2 = document.createElement("link");
style2.setAttribute("href", "shadow.css");
style2.setAttribute("rel", "stylesheet");
shadow.appendChild(style2);
//a标签===========
var aLabel = document.createElement("a");
aLabel.setAttribute("href", "https://developer.mozilla.org/zh-CN/docs/Web/API/Element/attachShadow");
aLabel.innerHTML = "aLink"
shadow.appendChild(aLabel);
///js隔离demo=========无效
var scriptShadowBox = document.createElement("script");
scriptShadowBox.innerHTML = `
console.log("scriptShadow document",document.querySelector(".wrap"));
window.aaaaaaaaaaaaaaaaaa="100";
bbb=200;
console.log("隔离 window.aaaaaaaaaaaaaaaaaa", window.aaaaaaaaaaaaaaaaaa,'bbb',bbb)
`;
shadow.appendChild(scriptShadowBox);
console.log("非隔离 window.aaaaaaaaaaaaaaaaaa", window.aaaaaaaaaaaaaaaaaa, 'bbb', bbb);
})
</script>
</body>
</html>
浏览器支持:
目前除了IE其他PC平台的浏览器支持良好
废弃:
createShadowRoot 不再支持,请使用上述demo中的attachShadow
Video标签
其实Shadow DOM是非常常见的功能,只是我们没有发觉,例如video标签就用到了Shadow DOM,只是它设置的mode是closed,所以控制板上看不到对应的dom,即使在浏览器上是 可以看到的(例如进度条)
我们打开浏览器的【显示用户代理Shadow Dom】,就可以看到如下的Dom结构
参考:
Web Components | Chaoszhu's Blog
而js沙箱使用proxy或者Object.definedobject 对window的set和get 进行拦截就可以实现
proxy提供拦截的方式更加多,包括deleteProperty.
参考:
JS 沙箱隔离简单实现_大名张无忌的博客-CSDN博客_沙箱隔离
从零开始写一个微前端框架-沙箱篇 - SegmentFault 思否
js沙箱 qiankun
在qiankun中,proxy对象会被在eval+with作为全局对象使用,两个沙箱互相不影响,且可以使用window的功能参考链接
// js 代理沙箱 基本实现
class ProxySandBox {
constructor() {
const rawWindow = window
const proxyWindow = {}
this.proxy = new Proxy(proxyWindow, {
get(target, key) { // target为第一个参数(代理对象proxyWindow)
return target[key] || window[key]
},
set(target, key, value) {
target[key] = value
return true
}
})
}
}
const ProxySandBox1 = new ProxySandBox()
const ProxySandBox2 = new ProxySandBox()
window.a = 1;
// 沙箱1
((window) => {
window.a = 2
})(ProxySandBox1.proxy);
// 沙箱2
((window) => {
window.a = 3
})(ProxySandBox1.proxy)
// 代理沙箱,互不影响window
console.log(window.a) // 1