我创建了一个普通的自定义元素:
document.registerElement("my-el", { prototype: Object.create(HTMLElement.prototype) });
Run Code Online (Sandbox Code Playgroud)
该元素使用 Shadow DOM 和<style>其中的标签。但是,我想让用户在主样式表中定义自定义元素的大小。它通过引用自定义标签来工作,但这是执行此类操作的推荐方法吗?
例如:
my-el {
width: 300px;
height: 50px;
background: green;
}
Run Code Online (Sandbox Code Playgroud) 我们有一个巨大的 Web 组件 (2MB) 当前正在元素中加载<head>,但这极大地减少了页面加载时间。
我在想我们是否可以以某种方式延迟加载我们的 Web 组件?
我正在尝试构建一个用于教学内容的自定义 TinyMCE 编辑器,该编辑器将允许将某些块包装为“活动”。一个内容块中将有多个活动,因此它们将具有 ID 作为主键等。
我的挑战是实现一个允许这样做的插件——理想情况下,我会使用短代码,但它们很容易出错。我正在考虑使用通过 Polymer 呈现的自定义 HTML 标签——这可以做到吗?
所以我正在编写一个聚合物应用程序。我已经为加载覆盖层编写了一个非聚合物 Web 组件,我可以在加载 Polymer 时以及应用程序 Websocket 连接/重新连接时显示该组件。
下面是一些 CSS 的运用,我必须给出我正在做的事情的指示:
.overlay {
background: #000;
bottom: 0;
height: 100%;
left: 0;
opacity: 0;
pointer-events: none;
position: fixed;
right: 0;
transition: opacity 0.2s;
top: 0;
width: 100%;
z-index: 9999999;
}
.overlay[opened] {
opacity: 0.8;
pointer-events: auto;
}
.loader {
display: none;
}
.overlay[opened] .loader {
display: block;
}
Run Code Online (Sandbox Code Playgroud)
现在,这个覆盖层和基于 CSS 的加载器动画仅在实际加载应用程序时使用,但是如果 WebSocket 断开连接,它也会显示。
我的问题是,出于性能原因,我是否应该从 DOM 中完全删除该元素,然后在需要时将其添加回来?覆盖层在不使用时完全透明并且加载器动画被隐藏的事实是否意味着它们对绘图性能没有影响?
注意:如果可能的话,我希望避免“不要微优化”答案;)
Shadow DOM 支持使用<link>标签来加载样式,其范围与声明的样式相同<style>,这非常方便,但带来的问题是样式仅在准备就绪时才应用,并且在加载样式时存在 FOUC:defined例如,使用自定义元素的伪选择器无法阻止这种情况。我遇到的另一个问题是在构建或连接自定义元素时测量影子根内部的元素,因为在加载和应用样式表后才知道“真实”尺寸,我不知道什么时候会发生这种情况(也许ResizeObserver实施时会有帮助吗?)
任何人都可以想出一种聪明的方法来解决这些问题(无需手动内联样式或使用构建步骤)?我的担心有道理吗?考虑到<link rel="stylesheet>在<head>块渲染中并且此功能应该与此类似,是否可以将其视为错误?
我正在尝试使用纯 javascript Web 组件进行无框架工作。我希望我的 Web 组件能够独立工作并在不同的站点上使用,但我也希望两个组件能够进行通信。因此它们应该能够在不紧密耦合的情况下进行通信。
当我使用 Angular 时,这很容易。我可以通过 HTML 属性将对象传递给组件,并且组件将其作为对象而不是字符串接收。但在纯 JavaScript 中,属性始终是字符串。传递对象或以其他方式使 Web 组件相互了解并能够进行通信的正确方法是什么?
如何设置 Webpack 4.5 将具有自己的 css 文件的 html 文件注入到主index.html中,而无需 Angular、React 等框架,并且我想要注入的每个 html 文件都没有 javaScript 文件?
我已经创建了单独的 html 文件并将它们注入到index.html中,但还没有弄清楚如何使这些 html 模板拥有自己的本地范围的 css 文件。
在home.html内部,我希望能够像平常一样
使用home.css
中的类(即不喜欢<div className={styles.foo}>,这是我发现的最接近的)
<div class=foo></div>
<div>
<p class=bar></p>
</div>
Run Code Online (Sandbox Code Playgroud)
.foo {background: red;}
.bar {background: green;}
Run Code Online (Sandbox Code Playgroud)
并自动将其范围限定为本地范围,以便在我的index.html中我可以注入home.html而不会发生CSS冲突,并且每个.html文件都不需要它自己的.js文件。
<!doctype html>
<html lang="en">
<head>
<title>Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="styles.css" rel="stylesheet">
</head>
<body>
<div id="pages">
<!-- inject page templates below -->
<section id="home" …Run Code Online (Sandbox Code Playgroud) 我想设置web-component-tester来测试我的 web 组件。我通过 npm (devDependency) 安装了它并创建了以下脚本:
包.json:
"scripts": {
"wcttest": "./node_modules/.bin/wct --npm src/app/modules/essen/components/essen-list/test/wct-test.html"
},
Run Code Online (Sandbox Code Playgroud)
正如脚本所述,我在那里有 .html 文件。但是现在,如果我运行脚本npm run wcttest,则会打开以下路线:
http://localhost:8081/components/wc-frontend/generated-index.html?cli_browser_id=0wc-frontend项目文件夹的根名称在哪里。但我不明白,为什么它components首先打开了路径。
测试打开了我安装的所有浏览器,但只有一个白页。如果我打开控制台有以下脚本:
<script>
WCT.loadSuites(["src/app/modules/essen/components/essen-list/test/wct-test.html"]);
<script>
Run Code Online (Sandbox Code Playgroud)
这里的路径看起来是正确的。
wct-test.html
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<script src="../../../../../../../node_modules/mocha/mocha.js</script>
<script src="../../../../../../../node_modules/wct-mocha/wct-
mocha.js"></script>
<script src="../../../../../../../node_modules/web-component-tester/browser.js"></script>
<script type="module" src="../essen-list.component.js"></script>
</head>
<body>
<mp-essen-list></mp-essen-list>
<script>
suite('suite', function () {
const list = document.body.querySelector('mp-essen-list');
test('test', function () {
list.setAttribute('value', 100);
assert.equal(list.value, 100);
//console.log('test');
//assert.equal(list.shadowRoot.querySelector('#speisekarte').style.left, 50);
});
});
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
编辑: …
在 iOS 14 上使用带有 Safari 的 webComponent 时(iOS 13 工作正常),日期输入呈现为日期输入,但行为呈现为文本输入。所有其他浏览器和设备都按预期工作。
代码是否存在问题,或者是否有适用于 iOS 14 的更好/不同的方法?将内容作为 HTML 字符串 (innerHTML) 读取时,输入按预期工作。
HTML:
<h1>Without template tag</h1>
<input type="date" />
<input type="time" />
<input type="datetime-local" />
<input type="number" />
<input type="text" />
<h1>With template tag</h1>
<div id="type-tester"></div>
<template id="test1">
<div>
<input type="date" />
<input type="time" />
<input type="datetime-local" />
<input type="number" />
<input type="text" />
</div>
</template>
<template id="test2">
<div>
<input type="date" />
<input type="time" />
<input type="datetime-local" />
<input type="number" />
<input type="text" /> …Run Code Online (Sandbox Code Playgroud) 我在测试上下文中对 shadowroot 中的元素执行操作时遇到困难。假设我有一个 Web 组件<my-component />,它包含一个按钮<input id="my-button" type="submit" />
从 chrome 控制台,我可以执行以下操作:
document.getElementsByTagName('my-component')[0].shadowRoot.querySelector('#my-button').click()
Run Code Online (Sandbox Code Playgroud)
我正在努力与 puppeteer 做同样的事情。
it('should click the button', async () => {
await page.goto(`https://localhost:${port}`, {
waitUntil: ['networkidle0', 'load'],
});
await page.$eval('my-component', (el: Element) => {
el.shadowRoot.querySelector('#my-button').click();
});
});
Run Code Online (Sandbox Code Playgroud)
单击该按钮应该会向我的服务器发出一个 http 请求,该请求会检索一些数据,然后我想在 dom 中对其进行断言。请求永远不会触发。建议?
web-component typescript jestjs web-component-tester puppeteer
web-component ×10
javascript ×6
css ×2
html ×2
shadow-dom ×2
ios14 ×1
jestjs ×1
npm ×1
polymer ×1
puppeteer ×1
styles ×1
tinymce ×1
typescript ×1
webpack ×1