我正在研究构建香草网络组件.我以前使用过Polymer,你可以将模板,样式和JavaScript放在一个文件中.如果可能的话,我希望用'vanilla'网页组件实现这一目标,但无法解决问题.我从这里获取代码并将其添加到我正在使用的文件中,如下所示:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Component test</title>
<link rel="import" href="x-foo-from-template.html">
</head>
<body>
<x-foo-from-template></x-foo-from-template>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这失败了,因为当我们尝试选择模板时它不存在,因为此时模板不在DOM中(对吗?).
有没有办法实现这个目标?我个人更喜欢这种方法在JavaScript中使用创建HTML document.createElement
.
javascript web-component html5-template custom-element html5-import
是否可以让DocumentFragments包含tr,th或td标签?
如果我这样做:
var template = document.createRange().createContextualFragment(
'<table></table>'
);
console.log(template.childNodes);
Run Code Online (Sandbox Code Playgroud)
我得到的输出[table]
。
如果我这样做:
var template = document.createRange().createContextualFragment(
'<td></td>'
);
console.log(template.childNodes);
Run Code Online (Sandbox Code Playgroud)
我得到[]
!!!?!?的输出
如果我这样做:
var template = document.createRange().createContextualFragment(
'<td><p></p></td>'
);
console.log(template.childNodes);
Run Code Online (Sandbox Code Playgroud)
我得到[p]
??!?!?!! ??!?!?????!
最后,如果我这样做:
var template = document.createRange().createContextualFragment(
'<span><td></td></span>'
);
console.log(template.childNodes);
Run Code Online (Sandbox Code Playgroud)
我知道[span]
了-TD哪里去了?
我不明白这里的矛盾之处。文档片段是否可能仅包含某些元素?我想做的是类似于上述第二个操作,然后使用检索td querySelector
。
谢谢
假设我创建并插入了一个这样的元素
<template id="react-web-component">
<span>template stuff</span
<script src="/static/js/bundle.js" type="text/javascript"></script>
</template>
<script>
(function (window, document) {
const doc = (document._currentScript || document.currentScript).ownerDocument;
const proto = Object.create(HTMLElement.prototype, {
attachedCallback: {
value: function () {
const template = doc.querySelector('template#react-web-component').content;
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template.cloneNode(true));
},
},
});
document.registerElement('react-web-component', { prototype: proto });
})(window, document);
</script>
<react-web-component></react-web-component>
Run Code Online (Sandbox Code Playgroud)
现在我想使用 aquerySelector
来访问我的元素的开放阴影 dom。像这样:
document.querySelector('react-web-component::shadow')
Run Code Online (Sandbox Code Playgroud)
但这不起作用。有没有其他办法?
编辑以回应@Supersharp 的回答
对不起,我没有说清楚。我使用的 webpack
style-loader
只接受一个 CSS 选择器,它与 一起使用document.querySelector
,所以我要的是一个我可以用这种方式使用的 CSS 选择器。
我在 JavaScript 中有一个数组,如下所示:
var pattern = [ ["C5", 3], , , , , , , , ["C5", 3], , , ]
Run Code Online (Sandbox Code Playgroud)
我想将它存储在这样的 json 文件中:
{
"pattern": [
["C5", 3], , , , , , , , ["C5", 3], , ,
]
}
Run Code Online (Sandbox Code Playgroud)
JSONLint 告诉我这个:
Parse error on line 6:
... ], , ,
---------------------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['
Run Code Online (Sandbox Code Playgroud)
所以我明白我不能让逗号之间的空格为空。什么类似于空,但被 JSON 标准接受?
这个模式文件是我正在制作的 Javascript Music Tracker 的一部分,它类似于脉冲跟踪器,我希望 json 文件尽可能干净。
我正在使用这段代码:
function setShadowDOM(i, css){
[].forEach.call(document.getElementsByTagName(i), function(hostVal) {
var _root = hostVal.createShadowRoot();
_root.innerHTML = '<style>:host ' + css + '</style><content></content>';
})
}
Run Code Online (Sandbox Code Playgroud)
我也读这个.
怎么解决这个?会有什么选择?
最近,我一直在使用ContentEditable开发一个简单的编辑器。该应用程序的要求很简单,唯一的例外是能够插入受常规编辑操作保护的文本块。
这些文本块无法编辑,并且必须表现为单个字符,才能在其中移动光标或将其删除。
生成的HTML的示例如下所示:
<div id="editor" contenteditable style="height: 400px; border: 1px solid black; margin: 4px; padding: 4px; overflow:auto;">
"This is standard text with a "
<span class="attrib">
#shadow-root
"PROTECTED"
"_"
</span>
" block"
</div>
Run Code Online (Sandbox Code Playgroud)
尽管这提供了我需要的受保护文本部分,但它有两个主要问题我无法解决:
有没有更好的方法可以做到这一点,还是无法以这种方式使用影子DOM?
在 Javascript 中,我试图动态创建一个 HTML<template>
元素,附加一个<h1>
元素作为其子元素,克隆模板的内容,然后将模板附加到文档正文。
问题是当我访问content
模板的属性时它只是返回#document-fragment
。
这是代码:
var temp = document.createElement('template');
var h1 = document.createElement('h1');
h1.textContent = 'hello';
var div = document.createElement('div').appendChild(h1)
temp.appendChild(div)
console.log('temp: ', temp)
console.log('temp content: ', temp.content)
var c = document.importNode(temp.content, true)
document.body.appendChild(c)
Run Code Online (Sandbox Code Playgroud)
这是输出console.log's
:
我在这里做错了什么?为什么模板的内容显示为空?
我正在尝试创建一个自定义表格行,但很难让它正常运行。我尝试了以下两种方法,它们给出了奇怪的结果。我意识到这很容易在没有自定义元素的情况下实现,但这是一个更大项目的一个小例子。我可以改变什么来达到预期的结果?
class customTableRow extends HTMLElement {
constructor(){
super();
var shadow = this.attachShadow({mode: 'open'});
this.tableRow = document.createElement('tr');
var td = document.createElement('td');
td.innerText = "RowTitle";
this.tableRow.appendChild(td);
var td2 = document.createElement('td');
td2.innerText = "RowContent";
td2.colSpan = 4;
this.tableRow.appendChild(td2);
shadow.appendChild(this.tableRow);
}
}
customElements.define('custom-tr', customTableRow);
//Attempt 2
var newTr = new customTableRow;
document.getElementById('table2Body').appendChild(newTr);
Run Code Online (Sandbox Code Playgroud)
td {
border: 1px solid black;
}
Run Code Online (Sandbox Code Playgroud)
<span>Attempt 1:</span>
<table>
<thead>
<tr>
<th>One</th>
<th>Two</th>
<th>Three</th>
<th>Four</th>
<th>Five</th>
</tr>
</thead>
<tbody>
<custom-tr />
</tbody>
</table>
<hr>
<span>Attempt 2:</span>
<table id="table2">
<thead>
<tr>
<th>One</th> …
Run Code Online (Sandbox Code Playgroud)我正在编写一个Chrome扩展程序,该扩展程序可以在页面加载或更改时修改元素属性。
我使用突变观察者来做到这一点。但是,在加载/更改shadow-dom(即嵌入式Twitter帖子)时,不会调用观察者的处理程序。
有没有一种方法可以在阴影域加载/更改时获取事件,或将变异观察者挂钩到该事件?
谢谢!
我刚刚开始使用Web组件,如果我理解正确,那么任何人都可以重用它们.是否有可能创建一个任何人都可以使用的组件,只需向他们的静态站点添加一段html(类似于添加JavaScript小部件的方式,只需复制粘贴几行代码),或者是否需要有人安装?或者这不是Web组件的预期用例?
javascript ×10
html ×6
shadow-dom ×5
arrays ×1
css ×1
dom ×1
html5-import ×1
json ×1
polymer ×1