自定义组件WebComponents加HTML模板template元素及shadowDOM影子DOM及定义一些事件
自定义组件WebComponents加HTML模板template元素及shadowDOM影子DOM及定义一些事件
Web Components自定义组件,可以自定义一个类似于div的元素,里面的事件可以自定义。template元素HTML模板,可以把一堆的DOM元素放到一起。shadow DOM影子DOM,可以在一个元素内放置独属于自己的元素,可配合slot标签做插槽。shadowRoot相当于一个阉割的document,但它只有独立的css作用域而没有独立的js作用域。
加了一些事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>WebComponents浏览器原生组件</title>
</head>
<body>
<template id="outTemplate">
<div>位于自定义组外的HTML无主模版1</div>
<div>div2</div>
</template>
<my-web-component fang="test">
自定义组件默认插槽内容
<template> 默认插槽内容 </template>
<template id="innerTemplate">
<p>位于自定义组件中的HTML无主模版2</p>
<div>div2</div>
</template>
<template slot="name2-slot">
<span>name2-slot插槽内容</span>
</template>
<h3 slot="name1-slot">name1-slot插槽内容</h3>
</my-web-component>
<div>原生div元素</div>
<span>原生span元素</span>
</body>
<script>
//初始化自定义组件的值。
class MyWebComponent extends HTMLElement {
constructor() {
super();
this.组件自定义变量 = "初始值";
console.log("在自定义组件整个生命周期中只会被触发一次。", this);
this.num = 0;
//监听事件,并修改自定义事件。实际上可以创建生命周期函数。
this.addEventListener("click", () => {
this.num++;
console.log(this.num);
});
this.自定义组件私有方法 = (event) => {
console.log("自定义组件私有方法", event);
};
//设置影子DOM
const js写的HTML模板 = document.createDocumentFragment(); //手动创建一个template元素。
js写的HTML模板.appendChild(document.createElement("div"));
js写的HTML模板.querySelector("div").innerHTML = `
<p>p1</p>
<p>自定义组件中用js写的自定义HTML模板中插入的p元素中文本</p>
`;
console.log("js写的HTML模板-->", js写的HTML模板);
const 影子DOM根节点open型 = this.attachShadow({ mode: "open" }); //获取open型的当前组件的影子DOM根节点。
影子DOM根节点open型.innerHTML = `
<h1 οnclick="console.log('点击了影子DOM中的标题',[this],[event.target],[event])">影子DOM中的标题</h1>
<p οnclick="event.target.getRootNode().host.自定义组件私有方法(event)">直接在dom中调用自定义组件私有方法-影子DOM中的p元素</p>
<div class="slot">
<span>默认插槽1</span>
<slot>默认插槽slot空的默认值</slot>
</div>
<div class="name1-slot">
<span>具名插槽1</span>
<slot name="name1-slot">具名插槽slot name="name1-slot"的默认值</slot>
</div>
<div class="default-slot">
<span>默认插槽2</span>
<slot name="default">默认插槽slot name="default"的默认值</slot>
</div>
<div class="name2-slot">
<span>具名插槽2</span>
<slot name="name2-slot">具名插槽slot name="name2-slot"的默认值</slot>
</div>
<div οnclick="自定义组件私有方法(event.target,'点击了影子DOM中的div元素1')">影子DOM中的div元素1</div>
<div class="last-div">影子DOM中的div元素2</div>
<style>
div{border: 1px solid rgb(255,255,0);}
p{font-size:20px;font-weight:100;}
.slot{color:red}
.default-slot{color:green}
.name1-slot{color:blue}
.name2-slot{color:pink}
.last-div{cursor:pointer}
</style>
<script>
//不执行这些代码
var 影子DOM内自定义方法 = (event,说明=''){
console.log(说明, event)
}
影子DOM内自定义方法('影子DOM内自定义方法')
<\/script>
`;
this.shadowRoot.appendChild(js写的HTML模板); //设置了this.attachShadow()后this.shadowRoot才有值。
const 影子DOM事件方法 = (event) => {
console.log("自定义组件专属函数", event);
};
this.shadowRoot
.querySelector(".last-div")
.addEventListener("click", 影子DOM事件方法);
console.log("影子DOM根节点open型-->", 影子DOM根节点open型);
}
自定义组件上的自定义方法(event, 说明 = "") {
console.log(说明, event);
}
connectedCallback(event) {
console.log("组件被加到DOM上或在节点树中移动时触发。", event);
}
disconnectedCallback(event) {
console.log("当组件被从DOM上移除时触发。", event);
}
adoptedCallback(event) {
console.log("组件被document.adoptNode()移动到新文档时触发", event);
}
attributeChangedCallback(name, oldValue, newValue) {
console.log("当组件的attribute改变时触发", name, oldValue, newValue);
}
observedAttributes(value) {
console.log("observedAttributes(),在这里返回自定义元素的属性", value);
console.log("this.组件自定义变量--->", this.组件自定义变量);
return ["fang"];
}
get fang() {
console.log(value, "get fang()", this.组件自定义变量);
this.getAttribute("fang") || "";
}
set fang(value) {
console.log(value, "get fang()", this.组件自定义变量);
this.组件自定义变量 = "初始值" + value;
this.setAttribute("fang", value);
}
}
//注册自定义组件;
window.customElements.define("my-web-component", MyWebComponent);
</script>
</html>
参考
- Web组件API – 自定义组件要看
- 原生js也可以自定义组件
- 深入理解Web Components
- Web Components-MDN文档
- HTML Imports - 在当前文档中导入html文档并使用其中的一部分
- 利用废弃的html rel import实现页面include功能 - 就是用自定义组件来实现
- HTMLUnknownElement与HTML5自定义元素的故事 - 自定义组件的来源
- HTMLUnknownElement - 无效的HTML元素 - MDN文档
- 影子DOM v1: 自足的Web组件 - 关于一个web组件的详细讲解
<slot>- MDN文档- 把富文本封装在 shadow DOM 中,要注意些啥? - shadowRoot 相当于一个阉割的 document,但它只有独立的 css 作用域而没有独立的 js 作用域
- 使用 shadow DOM - MDN
- html通过模板字符串写入script标签
- 原生js绑定事件的方法和dom操作
- shadow DOM的介绍和使用
- 影子节点ShadowDOM – 自定义组件要看
自定义组件WebComponents加HTML模板template元素及shadowDOM影子DOM及定义一些事件的更多相关文章
- 自定义元素–为你的HTML代码定义新元素
注意:这篇文章介绍的 API 尚未完全标准化,并且仍在变动中,在项目中使用这些实验性 API 时请务必谨慎. 引言 现在的 web 严重缺乏表达能力.你只要瞧一眼“现代”的 web 应用,比如 GMa ...
- Vue 组件6内联模板
如果子组件有inline-template特性,组件将把它的内容当做模板,而不是把它当做分发内容,这样模板更灵活. <my-component inline-template> <d ...
- 设置tabBar、使用第三方插件和自定义组件使用简单实例
创建小程序项目进入时填写,因需要用上第三方插件,所以要填上开发者的APPID,前往微信公众平台去注册一个账号获取APPID,在设置=>开发设置可以查看相关appid信息 简单思路 底部导航添加三 ...
- axure复用-自定义组件,母版(模板)
组件(控件)是用于设计线框图的用户界面元素.在组件(控件)面板中包含有常用的控件库,如按钮.图片.文本框等.从组件面板中拖动一个控件到线框图区域中,就可以添加一个组件.组件可以从一个线框图中被拷贝(C ...
- Vue 组件&组件之间的通信 之 template模板引用与动态组件的使用
template模板引用 在component的template中书写大量的HTML元素很麻烦. Vue提供了<template>标签,可以在里边书写HTML,然后通过ID指定到组建内的t ...
- 在Vue.js2.0中组件模板子元素数量问题
在Vue中当利用组件进行开发时候,组件所使用的模板只可以应用于一个根实例,当你需要添加多个子元素的时候,可以用一个div将它们包裹起来,代码如下: <template id="task ...
- 微信小程序开发--模板(template)使用,数据加载,点击交互
微信小程序视图层提供了 模板(template),可以在模板中定义代码片段,然后在不同的地方调用.结果在数据渲染那懵逼了.按照官网上对模板的说明和对数据的加载. 1.定义模板 使用name属性,作为模 ...
- iview table里面 插入下拉列表组件(自定义组件)一定要加key,不加key,table开始会加载所有数据,然后再从第2页点回第一页,就会走onChange事件,混乱的逻辑,切记加:key
iview table里面 插入下拉列表组件(自定义组件)一定要加key,不加key,table开始会加载所有数据,然后再从第2页点回第一页,就会走onChange事件,混乱的逻辑,切记加:key 关 ...
- angular4自定义组件非input元素实现ngModel双向数据绑定
在angular里我们一般都是给input元素添加[(ngModel)]="value"实现数据双向绑定,如果想实现自定义的组件上实现ngModel双向数据绑定应该怎么办呐... ...
- vue 上拉加载自定义组件,超好用哦
1.创建组件components > zj-roll > index.vue <template> <div> <slot></slot> ...
随机推荐
- [转帖]《Linux性能优化实战》笔记(十九)—— DNS 解析原理与故障案例分析
一. 域名与 DNS 解析 域名主要是为了方便让人记住,而 IP 地址是机器间的通信的真正机制.以 time.geekbang.org 为例,最后面的 org 是顶级域名,中间的 geekbang 是 ...
- 【转帖】text-davinci-003和ChatGPT之间的不同点
https://zhuanlan.zhihu.com/p/603709081 先看下GPT的发展时间线 InstructGPT(2022 年 1 月)是一系列 GPT-3 模型(包括 text-dav ...
- [转帖]-O1,-O2,-O3编译优化知多少
1.从.c文件到可执行文件,其间经历了几步? 高级语言是偏向人,按照人的思维方式设计的,机器对这些可是莫名奇妙,不知所谓.那从高级语言是如何过渡到机器语言的呢?这可是一个漫长的旅途呀! 其中,得经历这 ...
- 商智C店H5性能优化实战
前言 商智C店,是依托移动低码能力搭建的一个应用,产品面向B端商家.随着应用体量持续增大,考虑产品定位及用户体验,我们针对性能较差页面做了一次优化,并取得了不错的效果,用户体验值(UEI)从一般提升到 ...
- 说透IO多路复用模型
作者:京东零售 石朝阳 在说IO多路复用模型之前,我们先来大致了解下Linux文件系统.在Linux系统中,不论是你的鼠标,键盘,还是打印机,甚至于连接到本机的socket client端,都是以文件 ...
- vite按需加载element-plus,减少项目体积,你必须学会
1.在项目中安装 $ npm install element-plus --save $ yarn add element-plus $ pnpm install element-plus 2.安装对 ...
- 初试高云FPGA
前言 之前一直眼馋Sipeed的Tang系列,正好遇到有工程需要高速控制并行总线,就买了NANO 9K和Primer 20K试试水 买回来先拆的贵的20k,结果发现Sipeed设计师有奇怪的脑回路: ...
- P5963 [BalticOI ?] Card 卡牌游戏【来源请求】
[rt](https://www.luogu.com.cn/problem/P5963)------------## part1### 题意简述给你 $n$ 张纸牌,每张纸牌有两个面.将 $n$ 张纸 ...
- Windows 堆管理机制 [3] Windows XP SP2 – Windows 2003 版本
3. Windows XP SP2 – Windows 2003 3.1 环境准备 环境 环境准备 虚拟机 32位Windows XP SP2 \32位Windows XP SP3 调试器 OllyD ...
- Pytest 源码解读 [1] - [pluggy] 核心设计理念浅读
背景: Pytest 是一个功能强大的 Python 测试框架,它使用了一个名为 "pluggy" 的插件系统来扩展其功能.在 Pytest 的源码中,pluggy 模块负责实现插 ...