我正在尝试在 Shadow-dom 中实现自定义文本编辑器功能。我需要获取 contenteditable div 内的当前光标位置。
我已经尝试过几种方法。但他们都没有给出所需的输出。
我试图使用 Shadow DOM 获取用户的输入addEventListener(),但没有得到任何响应,任何错误。对元素的引用工作正常,因此console.log(input)打印出正确的元素。
(相同的代码在没有 Shadow DOM 的情况下工作得很好,但我必须将它包含在我的项目中。)
这是我的代码(当然这些事件只是为了检查):
const template = document.createElement('template')
template.innerHTML = /* html */`
<div id="username">
<p>Please choose your username!</p>
<input id="username_input" type="text" placeholder="enter username">
<button>Ok</button>
</div>
`
/**
* @class Quiz
* @extends {window.HTMLElement}
*/
export class Quiz extends window.HTMLElement {
constructor () {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot.appendChild(template.content.cloneNode(true))
}
getUserName () {
const button = this.shadowRoot.querySelector('button')
const inputUname = this.shadowRoot.querySelector('#username input')
console.log(button)
button.addEventListener('click', event => console.log('badum tss'))
inputUname.addEventListener('input', event …Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的网站,类似于这个jsfiddle。一切似乎都工作正常,但在我本地的,但是当我停在第一行 JS 行(在声明自定义元素之前)时,我可以看到没有格式的 div...
<jrg-test>
<div slot="test">
This should work
</div>
</jrg-test>
connectedCallback() {
console.log("Ok we are working")
this.shadowRoot.innerHTML = "<slot name='test'></slot>"
const element = document.createElement('style');
element.textContent = "::slotted(*){background-color:red;color:white;}";
this.shadowRoot.appendChild(element);
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,如果我在渲染自定义元素之前停止,我会看到原始 div。我知道有一些涉及定位和 CSS 的 hacky 解决方案,但是有没有更干净的解决方案。也许我可以专门用 JS 实现一个?
所以主要问题是如何隐藏文本,This should work直到应用红色背景和白色?
我在 Shadow DOM 中创建了一个模式对话框,并在文档加载期间将其注入(使用暴力猴子)到页面中。该对话框包含一个简单的表单。这个想法是提示用户输入。
创建对话框时,它具有焦点。元素可以选项卡式显示,并且我可以挂钩键/鼠标事件。当触发窗口加载事件时就会出现问题。焦点返回到主体(通过document.activeElement在控制台中发出并通过为主体和 shodowroot 挂钩 focusin/out 来验证)。我可以挂接该focusin事件,但到目前为止,我尝试过的任何操作都无法将焦点返回到我的对话框。
对话框的精简版本:
<div id="twifty-translate-dialogue" style="">
#shadow-root (open)
<div class="outer" style="z-index: 2147483647; pointer-events: none;">
<div class="container">
<div id="header" class="">
</div>
<div id="languages" class="">
</div>
<div class="buttons">
<button id="translate" class="button-translate" type="button">Translate</button>
<button id="cancel" class="button-cancel" type="button">Cancel</button>
</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
我希望以下内容能够发挥作用:
window.onload = () => {
document.getElementById("twifty-translate-dialogue").shadowRoot.getElementById("translate").focus()
}
Run Code Online (Sandbox Code Playgroud)
根据我的阅读,应该有两个活跃元素。和#twifty-translate-dialogue影子 DOM #translate。但:
document.activeElement
> <body>
document.getElementById("twifty-translate-dialogue").shadowRoot.getElementById("translate").focus()
document.activeElement
> #twifty-translate-dialogue
document.getElementById("twifty-translate-dialogue").shadowRoot.activeElement
> null
Run Code Online (Sandbox Code Playgroud)
我怎样才能恢复焦点?
更新:解决方法:
window.onload = () => {
window.setTimeout(() …Run Code Online (Sandbox Code Playgroud) Shadow DOM允许我们在文档中创建独立的 DOM 树,这些 DOM 树有自己的节点树,(或多或少)独立的样式管理,并且在某种程度上,仅“渲染”到父 DOM 树中。
我想知道大规模的性能影响。与将所有内容都放在一个大文档中相比,在一个页面上拥有许多 Shadow DOM / Shadow root 是好是坏?
一方面,我猜想,浏览器可能会受益于较小的(子)DOM 树以及在渲染仅包含实际的节点和样式的隔离 Shadow DOM 的内容时必须评估的较少的样式规则。与其内容相关。这可能会对计算工作量产生积极影响。
另一方面,在渲染时额外的“类似文档”元数据或 DOM 树的“合并”是否会减慢浏览器速度或显着增加内存使用量?
我的 html 内容位于影子根中,这些内容都是通过 microblink SDK 动态生成的。
我需要向其添加事件监听器,#fileBtn因此每当单击它时我都需要执行某些操作。但由于它是影子根,我无法访问 DOM 属性。我也为此使用reactjs。
<microblink-ui-web tabs="true" autoscroll="true" style="height: 319.562px;">
#shadow-root (open)
<div class="container root" max-width="500px 600px 630px">
<div class="container main">
<div class="container intro dropzone active">
<div class="flex-vertical">
<p class="intro-label">
<slot name="labels.chooseInputMethod">Choose input method</slot>
</p>
<div class="flex-horizontal">
<input
type="file"
accept="image/png,image/gif,image/bmp,image/jpeg,image/x-png,image/vnd.wap.wbmp"
id="file"
/>
<button type="button" class="intro-button" id="fileBtn">
</button>
<button type="button" class="intro-button" id="cameraLocalBtn">
</button>
</div>
</div>
</div>
</div>
</div
></microblink-ui-web>
Run Code Online (Sandbox Code Playgroud)
提前致谢!!!
Shadow Root是否有维护一个官方列表,其中包含渗透到的CSS 属性的最新详细信息WebComponent?
我认为有以下几点:
colorline-heightfont-familyfont-sizefont-weight都是这样,但至少还有十几个吧?
使用 LitElement 在 Web 组件/shadowDOM 应用程序中使用大型 css 库(如 bootstrap)的最简单方法是什么?
尝试了以下方法:
寻找在此设置中使用 boostrap 的最简单方法。
我正在 Vue 中构建第三方 Web 组件,它的大部分样式都相当依赖 Tailwindcss。
Web 组件的 Shadow-dom 封装了大部分样式和 CSS,因此(大部分)不会有样式从 Web 组件所在的网页渗透到 Shadow dom 的内部,反之亦然。
然而,Tailwind 使用基于 rem 的值来调整几乎所有字体、填充、高度、宽度等的大小。
我刚刚发现,显然,父页面的样式渗入到 Shadow-dom 中的一个例外是,shadow-dom 会将主页样式表的 html{ } 部分中设置的基本字体大小固有到 Shadow-dom 中。
由于基于 rem 的值继承自父级的 html{} 块,这意味着如果主题页面在其页面的 html { 中设置了字体大小,则所有基于 Tailwind 的高度、字体、填充等最终都会被任意调整大小。设置为 16px 以外的任何值的块。
在我返回并尝试从我的组件中完全剥离 Tailwind 之前,有什么方法可以阻止 Shadow-dom 从主页的 html {} 块继承字体大小?对于一个 Web 组件来说,提供几乎所有封装的样式,却被迫从页面继承根字体大小,这似乎很荒谬。
我尝试用 !important 覆盖字体大小,也尝试将组件包装在另一个标签中,但似乎都不起作用。
我创建了一个具有阴影模式“打开”的 Web 组件,其使用方式如下:
<scu-switch checked="true" value="switch1">
<span id="scu-switch-label">Switch On</span>
</scu-switch>
Run Code Online (Sandbox Code Playgroud)
看起来像这样:
然后我使用以下全局 CSS 将按钮添加到网页:
<scu-switch checked="true" value="switch1">
<span id="scu-switch-label">Switch On</span>
</scu-switch>
Run Code Online (Sandbox Code Playgroud)
现在按钮样式已损坏:
当我检查按钮时,我可以看到,全局样式已应用于影子根
内部的范围(并注意它不是插槽内容的一部分)。
Shadow DOM 应该将样式与网页的其余部分隔离。text-align: center尽管它是在 Shadow DOM 之外定义的,为什么在这里应用它?
shadow-dom ×10
javascript ×5
css ×4
html ×4
bootstrap-4 ×1
dom ×1
events ×1
lit-element ×1
microblink ×1
reactjs ×1
tailwind-css ×1
text-align ×1