Shadow DOM, Firefox 및 contenteditable
This is more of a short note about some experiments when working with web components that I’m publishing as a reference for future me (or other people that experience the same issue).
저는 바닐라 JS에서 쉽게 사용할 수 있는 Felte 래퍼를 만들기 위해 웹 컴포넌트를 실험해왔습니다. Felte의 기능 중 하나는 브라우저의 기본 입력(
input
, textarea
, select
)을 기반으로 하지 않는 사용자 정의 필드 구성 요소를 사용하는 기능입니다. 내가 보여주는 예는 속성이 [contenteditable=“true”]
인 div입니다. 이 실험을 테스트하는 동안 Firefox에서 이상한 동작이 발생하는 것을 발견했습니다. 각 필드를 완벽하게 클릭하고 입력할 수 있지만 키보드만 사용하여 양식을 사용하려고 하면(각 필드로 탭 이동) 포커스가 이동했지만 입력을 시도하면 항상 초점을 맞춘 첫 번째 필드에 텍스트가 추가됩니다.또 다른 혼란스러운 동작은 요소 자체를 클릭할 때 요소를 입력할 수 있어도 케어가 전혀 표시되지 않는다는 것입니다. 따라서 요소 자체를 편집할 수 있음을 사용자에게 알리는 시각적 신호가 없습니다. 현재 open issue on bugzilla that seems to be exactly this 가 있습니다.
물론 이러한 행동은 용납될 수 없습니다. 특히 양식(및 일반적으로 웹 응용 프로그램)은 키보드 사용자가 액세스할 수 있어야 하기 때문입니다. the demo I was working on가 올바르게 작동하려면 즉각적인 해결책을 찾으러 갔습니다. 몇 가지 조사를 한 후 저에게 더 일관되게 작동하는 솔루션은 렌더링 시 필드에 추가
[contenteditable]
하지 않고 대신 포커스에 속성을 동적으로 추가하고 흐림 효과를 제거하는 이벤트 리스너를 추가하는 것입니다.function handleFocus(e) {
e.target.setAttribute('contenteditable', '');
}
function handleBlur(e) {
e.target.removeAttribute('contenteditable');
}
// We query the shadowRoot of the element that contains
// our `contenteditable` fields
element.shadowRoot
.querySelectorAll('div[role="textbox"]')
.forEach((el) => {
el.addEventListener('focusin', handleFocus);
el.addEventListener('focusout', handleBlur);
});
또는 더 쉽게 재사용할 수 있도록 다음과 같이 동작하는 사용자 지정 요소를 만듭니다.
function handleFocus(e) {
e.target.setAttribute('contenteditable', '');
}
function handleBlur(e) {
e.target.removeAttribute('contenteditable');
}
export class MyField extends HTMLElement {
constructor() {
super();
// Make the element focusable
this.setAttribute('tabindex', '0');
// Assign a role for assistive technologies
this.setAttribute('role', 'textbox');
// Some default styles
this.style.display = 'block';
this.style.cursor = 'text';
}
connectedCallback() {
this.addEventListener('focusin', handleFocus);
this.addEventListener('focusout', handleBlur);
}
disconnectedCallback() {
this.removeEventListener('focusin', handleFocus);
this.removeEventListener('focusout', handleBlur);
}
}
customElements.define('my-field', MyField);
이 방법으로
<my-field></my-field>
를 [contenteditable]
"div"로 사용할 수 있습니다!이 기사는 초점이
[contenteditable]
요소에서 올바르게 작동하도록 만드는 것에 대해서만 걱정한다는 점을 명심하십시오. 사용 사례에 따라 이와 같은 작업을 수행할 때 고려해야 할 사항이 더 있습니다.
Reference
이 문제에 관하여(Shadow DOM, Firefox 및 contenteditable), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/pabloabc/shadow-dom-firefox-and-contenteditable-fph텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)