我有一个自定义的HTMLElement,它可以按预期工作,但是我找不到将参数传递给构造函数的方法。相反,我正在访问传递自定义标记中的值,但是随后我不得不在https://source.unsplash.com/1600x900/?roblox
中设置这些值,对此我不满意。
这是我现在正在做的基本版本:
connectedCallback()
我宁愿将videoId直接传递给构造函数,类似这样(不起作用):
JS:
class TrackingPreview extends HTMLElement {
constructor() {
super();
const video = document.createElement('video');
video.setAttribute('controls', '');
video.setAttribute('width', '1920');
video.setAttribute('height', '1080');
shadow.appendChild(video);
this.video = video;
}
connectedCallback() {
const videoId = this.getAttribute('video-id');
this.video.id = videoId;
}
}
HTML页面上的JS脚本:
class TrackingPreview extends HTMLElement {
constructor(videoId) {
super();
const video = document.createElement('video');
video.setAttribute('id', videoId);
video.setAttribute('controls', '');
video.setAttribute('width', '1920');
video.setAttribute('height', '1080');
shadow.appendChild(video);
}
connectedCallback() {
}
}
是否可以将值传递给自定义构造函数?这些文档暗示有可能,但对如何做到却不是很有帮助。
答案 0 :(得分:1)
请记住,常规HTML元素均不带有构造函数参数:不要依赖它们。取而代之的是,依靠具有JS属性支持的属性,并根据custom elements spec将其连接起来。
因此,以与Image
的以下代码相同的方式:
let img = new Image();
img.src = "https://example.com/someimage.jpg";
img.width = ...
...
或脚本元素:
let script = document.createElement("script");
script.src = ...
// or script.textContent = ...
您的组件不需要构造函数属性。您将像这样使用它:
let preview = TrackingPreview();
preview.width = 1920;
preview.height = 1080;
或HTML格式
<track-preview width="100" height="200" ...></track-preview>
让您的自定义元素对设置的那些属性做出反应:
class TrackingPreview extends HTMLElement {
static get observedAttributes() {
return [`width`, `height`];
}
constructor() {
super();
const shadow = this.attachShadow({mode: 'open'});
const video = this.video = document.createElement('video');
video.setAttribute(`controls`, `controls`);
video.setAttribute(`width`, this.getAttribute(`width`) || 1920);
video.setAttribute(`height`, this.getAttribute(`height`) || 1080);
shadow.appendChild(video);
}
get width() {
return this.video.width;
}
set width(val) {
this.setAttribute(`width`, val);
}
get height() {
return this.video.height;
}
set height(val) {
this.setAttribuite(`height`, val);
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === `width`) {
this.video.width = newValue;
}
if (name === `height`) {
this.video.height = newValue;
}
// ...
}
// ...
}
答案 1 :(得分:0)
您可以使用new
关键字:
const tacking_preview = new TrackingPreview( id )
答案 2 :(得分:0)
Web组件的构造函数的规则非常严格。一个规则是不允许您将任何参数传递给构造函数。
https://w3c.github.io/webcomponents/spec/custom/#custom-element-conformance
请同时使用属性和属性
class TrackingPreview extends HTMLElement {
static get observedAttributes() {
return ['videoid'];
}
constructor() {
super();
const video = document.createElement('video');
video.setAttribute('controls', '');
video.width = 192;
video.height = 108;
this.video = video;
this.attachShadow({mode: 'open'}).appendChild(video);
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
this.video.setAttribute('id', newVal);
}
}
get videoId() {
return this.video.getAttribute('id');
}
set videoId(val) {
if (val == null) { // check for null and undefined
this.removeAttribute('videoid');
}
else {
this.setAttribute('videoid', val);
}
}
}
customElements.define('tracking-preview', TrackingPreview);
setTimeout(function() {
let el = document.querySelector('tracking-preview');
if (el) {
console.log(el.videoId);
el.videoId = 99;
console.log(el.videoId);
}
}, 500);
<tracking-preview videoid="10"></tracking-preview>
设置属性videoid
后,将调用attributeChangedCallback
函数,并将该值向下传递到video
元素。
在超时功能中,我同时读写videoId
属性的videoid
属性。