我有一个包含一些嵌套自定义元素的程序。这些组件的shadowRoot之一的叶子包含元素的实例,例如<div contentEditable>
。在Chrome79和Chromium-Edge-Beta中,contentEditable
功能的作用与人们期望的一样-即,当您单击或制表到元素时,它们会聚焦,显示焦点轮廓,并且可编辑。在FireFox72中,它们的行为不正常,主要是因为单击它只会在某些时间集中在它上面,并且尽管可以将它们制表,但它们不会集中到可以将其键入的位置。
经过一番苦思冥想之后,我想我已经达到了最低限度的复制。它是两个自定义元素:一个根元素ce-main
和一个叶元素ce-leaf
,它们从ce-main
内部任意实例化多次并附加到ce-main
的shadowRoot。
class Main extends HTMLElement {
constructor() { super(); }
connectedCallback() {
this.attachShadow({mode: "open"});
this.shadowRoot.innerHTML = `
<style>
[contentEditable] {
min-height:2em;
padding:.5em;
border:1px dashed rgba(0,0,0,.0625);
}
[contentEditable]:empty::before {
color: rgba(0,0,0,.15);
content: "You should be able to focus and type here.";
cursor:text;
}
</style>
<div id="container" style=""></div>`;
customElements.whenDefined("ce-leaf").then(
() => this.constructFromSomeDataSource()
);
}
constructFromSomeDataSource() {
let rows = [];
for (let i = 0; i < 4; i++) {
let leaf = document.createElement("ce-leaf");
this.shadowRoot.querySelector("#container").appendChild(leaf);
};
}
}
class Leaf extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = `
<div contentEditable></div>
`;
}
}
customElements.define("ce-main", Main);
customElements.define("ce-leaf", Leaf);
<ce-main></ce-main>
如果不使用shadowRoot
,则一切都可以在Chrome / EdgeBeta / Firefox中很好地聚焦:
class Main extends HTMLElement {
constructor() { super(); }
connectedCallback() {
customElements.whenDefined("ce-leaf").then(
() => this.constructFromSomeDataSource()
);
}
constructFromSomeDataSource() {
let rows = [];
for (let i = 0; i < 4; i++) {
let leaf = document.createElement("ce-leaf");
this.appendChild(leaf);
};
}
}
class Leaf extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = `
<div contentEditable></div>
`;
}
}
customElements.define("ce-main", Main);
customElements.define("ce-leaf", Leaf);
[contentEditable] {
min-height:2em;
padding:.5em;
border:1px dashed rgba(0,0,0,.0625);
}
[contentEditable]:empty::before {
color: rgba(0,0,0,.15);
content: "You should be able to focus and type here.";
cursor:text;
}
<ce-main></ce-main>
任何人都可以验证这是否是FF中的错误,或者我是否只是在做与FF中的错误方式不符的事情?
不得不浏览许多Firefox / Focus帖子。
追溯到6年前的FireFox错误中的类似行为:https://bugzilla.mozilla.org/show_bug.cgi?id=904846
在这里找到最佳方法:Clicking outside a contenteditable div stills give focus to it?
处理contenteditable
属性并通过focus()
和click
事件自行设置blur
:
((注意:leafCounter是有效的CSS,仅在StackOverflow内联代码中不起作用,而在JSFiddle中起作用)] >>
class Main extends HTMLElement { constructor() { super(); } connectedCallback() { this.attachShadow({ mode: "open" }) .innerHTML = `<style> ce-leaf div { padding: .5em; cursor: text; counter-increment: leafCounter; } ce-leaf div:empty::before { color: lightgrey; content: "placeholder text #" counter(leafCounter); } [contenteditable]:focus{ background: lightgreen; } </style>` + "<ce-leaf></ce-leaf>".repeat(5); } } class Leaf extends HTMLElement { constructor() { super(); let div = this.appendChild(document.createElement("div")); div.addEventListener("click", evt => { evt.target.contentEditable = true; evt.target.focus(); }); div.addEventListener("blur", evt => { evt.target.contentEditable = false; }); } } customElements.define("ce-main", Main); customElements.define("ce-leaf", Leaf);
<ce-main></ce-main>
<ce-leaf>
是元素!您不需要DIV 内部 <ce-leaf>
自定义元素...
JSFiddle版本在contenteditable
上执行<ce-leaf>
https://jsfiddle.net/CustomElementsExamples/qh05u3eg/
遗憾的是,另一个带有constructor() { super(); this.addEventListener("click", evt => { this.contentEditable = true; this.focus(); }); this.addEventListener("blur", evt => { this.contentEditable = false; }); }
更新:
contenteditable
错误的Firefox:您无法选择部分文本并将其替换为JSfiddle。坚持使用DIV inside元素解决方案。