ShadowDOM v1 - 在 lightdom 中更改了输入文本
ShadowDOM v1 - Input text changed in lightdom
我正在尝试监听自定义组件中的文本更改
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="component.js"></script>
</head>
<body>
<fancy-p>
<p>Bar</p>
<!-- the input should be listened to -->
<input id="foo" type="text" name="text" placeholder="Hello"></input>
</fancy-p>
</body>
</html>
component.js
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
get foo() {
return "foo"
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
p {
color: red;
}
:host {
background-color: blue;
}
</style>
<div data-foo="bar">
<slot></slot>
</div>
`;
let input = this.querySelector("input");
console.log("input is:" + input);
}
});
我尝试监听文本更改并在 connectedCallback
中使用 querySelector
但在 Chrome 70.xx 中选择器 returns null
.
似乎当我设置断点时 lightDOM 未填充(即插槽),但我不知道如何向输入添加事件侦听器。
我该怎么做???
在您的示例中,<input>
被放置在 <slot>
中,这意味着自定义元素之外的代码拥有 <input>
标记。
在下面的代码中,您看到我在自定义元素外部使用 document.querySelector
来获取 <input>
元素,而不是在自定义元素内部使用 this.querySelector
或 this.shadowRoot.querySelector
自定义元素代码。
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
get foo() {
return "foo"
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
p {
color: red;
}
:host {
background-color: blue;
}
</style>
<div data-foo="bar">
<slot></slot>
</div>
`;
let input = this.shadowRoot.querySelector("input");
console.log('inside input=',input); // input will be null
}
});
//Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:
let input = document.querySelector("input");
console.log('outside input=', input);
input.addEventListener('input', () => {
console.log("input is:" + input.value);
});
<fancy-p>
<p>Bar</p>
<input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>
如果你想通过 shadowDOM 访问它,那么你需要在 shadowDOM 中定义它:
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
get foo() {
return "foo"
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
p {
color: red;
}
:host {
background-color: blue;
}
</style>
<div data-foo="bar">
<slot></slot>
<input id="foo" type="text" name="text" placeholder="Hello">
</div>
`;
let input = this.shadowRoot.querySelector("input");
console.log('inside input=',input);
input.addEventListener('input', () => {
console.log("input is:" + input.value);
});
}
});
<fancy-p>
<p>Bar</p>
</fancy-p>
当调用 connectedCallback()
方法时,<input>
元素还没有附加到灯 DOM 上。所以你那个时候用this.querySelector('input')
是拿不到的。
这不是真正的问题:您可以在自定义元素本身上监听 {input}
事件,因为该事件将 冒泡 到父元素。
this.addEventListener( 'input', ev => console.log( ev.target, ev.target.value ) )
参见 运行 示例:
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super()
this.attachShadow({mode: 'open'})
.innerHTML = `
<style>
::slotted(p) { color: red; }
:host { display:inline-block; background-color: blue; }
</style>
<div data-foo="bar">
<slot></slot>
</div>`
this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
}
})
<fancy-p>
<p>Bar</p>
<input id="foo" type="text" name="text" placeholder="Hello">
</fancy-p>
我正在尝试监听自定义组件中的文本更改
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="component.js"></script>
</head>
<body>
<fancy-p>
<p>Bar</p>
<!-- the input should be listened to -->
<input id="foo" type="text" name="text" placeholder="Hello"></input>
</fancy-p>
</body>
</html>
component.js
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
get foo() {
return "foo"
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
p {
color: red;
}
:host {
background-color: blue;
}
</style>
<div data-foo="bar">
<slot></slot>
</div>
`;
let input = this.querySelector("input");
console.log("input is:" + input);
}
});
我尝试监听文本更改并在 connectedCallback
中使用 querySelector
但在 Chrome 70.xx 中选择器 returns null
.
似乎当我设置断点时 lightDOM 未填充(即插槽),但我不知道如何向输入添加事件侦听器。
我该怎么做???
在您的示例中,<input>
被放置在 <slot>
中,这意味着自定义元素之外的代码拥有 <input>
标记。
在下面的代码中,您看到我在自定义元素外部使用 document.querySelector
来获取 <input>
元素,而不是在自定义元素内部使用 this.querySelector
或 this.shadowRoot.querySelector
自定义元素代码。
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
get foo() {
return "foo"
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
p {
color: red;
}
:host {
background-color: blue;
}
</style>
<div data-foo="bar">
<slot></slot>
</div>
`;
let input = this.shadowRoot.querySelector("input");
console.log('inside input=',input); // input will be null
}
});
//Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:
let input = document.querySelector("input");
console.log('outside input=', input);
input.addEventListener('input', () => {
console.log("input is:" + input.value);
});
<fancy-p>
<p>Bar</p>
<input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>
如果你想通过 shadowDOM 访问它,那么你需要在 shadowDOM 中定义它:
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
get foo() {
return "foo"
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
p {
color: red;
}
:host {
background-color: blue;
}
</style>
<div data-foo="bar">
<slot></slot>
<input id="foo" type="text" name="text" placeholder="Hello">
</div>
`;
let input = this.shadowRoot.querySelector("input");
console.log('inside input=',input);
input.addEventListener('input', () => {
console.log("input is:" + input.value);
});
}
});
<fancy-p>
<p>Bar</p>
</fancy-p>
当调用 connectedCallback()
方法时,<input>
元素还没有附加到灯 DOM 上。所以你那个时候用this.querySelector('input')
是拿不到的。
这不是真正的问题:您可以在自定义元素本身上监听 {input}
事件,因为该事件将 冒泡 到父元素。
this.addEventListener( 'input', ev => console.log( ev.target, ev.target.value ) )
参见 运行 示例:
customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super()
this.attachShadow({mode: 'open'})
.innerHTML = `
<style>
::slotted(p) { color: red; }
:host { display:inline-block; background-color: blue; }
</style>
<div data-foo="bar">
<slot></slot>
</div>`
this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
}
})
<fancy-p>
<p>Bar</p>
<input id="foo" type="text" name="text" placeholder="Hello">
</fancy-p>