Firefox中自定义元素shadowRoots中内容可编辑div的不正确行为?

问题描述 投票:0回答:1

我有一个包含一些嵌套自定义元素的程序。这些组件的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 custom-element
1个回答
0
投票

不得不浏览许多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元素解决方案。
© www.soinside.com 2019 - 2024. All rights reserved.