js自定义组件
// 自定义组件
// 1.继承html组件
class myImg extends HTMLImageElement{
constructor() {
super()
setTimeout(() => {
this.src = "https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg"
},1000)
}
}
customElements.define('my-img',myImg,{
extends: 'img'
})
// 2.自定义组件
class myCom extends HTMLElement{
constructor() {
super()
this.innerHTML = `<button>自定义按钮</button>`
}
}
customElements.define('my-com',myCom)
自定义组件扩展
index.html
<my-dailog title='外部标题'></my-dailog>
<script type='module'>
import Dailog from './dailog.js'
document.querySelector('my-dailog').addEventListener('success',e => {
console.log('自定义框',e.detail)
}) // 给success事件增加监听
</script>
dailog.js
export default class Dailog extends EventTarget{
constructor(opts){
super()
let defaultOpts = {
width: '30%',
height: '250px',
titile: '测试表示',
content: '测试内容',
dragable: true, // 是否可拖拽
maskable: true, // 是否有遮罩
isCancle: false // 是否取消
}
this.opts = Object.assign(defaultOpts, opts)
this.init()
}
init(){
this.createDom()
// 创建success事件监听,并把Dailog里面的success参数赋值给它
this.addEventListener('success', this.opts.success)
if(!this.opts.maskable){
this.divEle.querySelector('.k-wrapper').style.display = 'none'
}
let dialog = this.divEle.querySelector('.k-dialog')
this.dialog = dialog
let inputValue = this.divEle.querySelector('.input-inner')
dialog.addEventListener('click',(e) => {
console.log(e.target.className)
switch(e.target.className){
case 'k-close':
this.close()
break;
case 'k-cancel':
this.close()
break;
case 'k-primary':
this.confirm(inputValue.value)
inputValue.value = ''
this.close()
break;
}
},false)
if(this.opts.dragable){
this.drag()
}
}
drag(e){
this.dialog.addEventListener('mousedown',(e) => {
// 点击的x - 元素距离左边框的距离 = 点击的x距离元素框的左边距离
// offsetLeft获取的距离没有px单位
let x = e.clientX - this.dialog.offsetLeft
// 点击的y - 元素距离上边框的距离 = 鼠标的坐标y距离元素框的上边距离
let y = e.clientY - this.dialog.offsetTop
document.onmousemove = (e) => {
let xx = e.clientX
let yy = e.clientY
this.dialog.style.top = yy - y + 'px'
this.dialog.style.left = xx - x + 'px'
}
},false)
document.addEventListener('mouseup',() => {
document.onmousemove = ''
},false)
}
confirm(value){
// 把之前addEventListener注册的事件监听实例化,并且传入参数
let event = new CustomEvent('success',{
detail: value
})
// 执行回调函数,执行之后,Dailog里面的success的 e.detail里面会有value值
this.dispatchEvent(event)
}
createDom(){
let divEle = document.createElement('div')
divEle.innerHTML = `
<div class="k-wrapper"></div>
<div class="k-dialog" style='width:${this.opts.width};height:${this.opts.height}'>
<div class="k-header">
<span class="k-title">${this.opts.title}</span><span class="k-close">X</span>
</div>
<div class="k-body">
<span>${this.opts.content}</span>
<input class="input-inner" type="text" />
</div>
<div class="k-footer">
${this.isCancle ? '<span class="k-cancel">取消</span>' : ''}
<span class="k-primary">确定</span>
</div>
</div>
`
document.body.appendChild(divEle)
this.divEle = divEle
this.divEle.style.display = 'none'
}
close(){
this.divEle.style.display = 'none'
}
open(){
this.divEle.style.display = 'block'
}
}
class newDailog extends HTMLElement{
constructor() {
super()
let dailog = new Dailog({
title: this.title,
success:(e)=>{
// this指向组件my-com,调用my-com的自定义事件success
this.dispatchEvent(new CustomEvent('success',{
// detail指向的是my-com组件里注册success事件的detail。e.detail 指向的是Dailog里面的success事件
detail: e.detail
}))
}
})
this.innerHTML = `<button>点击自定义按钮</button>`
this.onclick = () => {
dailog.open()
}
}
get title(){
// 获取this.title,接受返回值,?? 表示前者是''也属于true,增加精确性
return this.getAttribute('title') ?? '默认标题'
}
}
// 自定义my-dailog元素
customElements.define('my-dailog',newDailog)