addEventListener的默认事件满足不了我了⚡,了解下自定义事件吧
前言
之前在上家公司用vue
+ element UI
技术栈的时候,总是感觉到达自己的舒适区了,工作没什么难度~~~ 直到我遇到了select组件
下拉框在滚动页面关不掉的情况,并且,我开始对细节
下手想解决这个问题。
然后,我就一路追踪,翻element UI
的源码,直接找到了v-clickoutside="handleClose"
。感兴趣的小伙伴可以在源码里全局搜索这个关键字。
大致思路: 自定义指令的逻辑中,在整个文档注册了
mousedown
、mouseup
事件,mouseup
触发时会执行createDocumentHandler
函数判断当前DOM是不是select相关的节点,如果不是就执行handleClose
关闭弹窗。
最后在滚动事件触发时执行document.dispatchEvent(new Event("mouseup", { bubbles: true }));
解决了这个问题。
那个时候就准备把笔记整理一下,但是一直没时间~~~
最近这家公司在uniapp
的开发中又碰到了使用document.dispatchEvent(new Event("自定义事件"))
的场景。
这次把这两个案例都在此处整理了一下,给小伙伴们参考一下。
正文
new Event使用方法介绍
new Event('事件类型', 可选对象);
1, 官网中的可选对象介绍:
"bubbles"
,可选,Boolean
类型,默认值为false
,表示该事件是否冒泡。"cancelable"
,可选,Boolean
类型,默认值为false
,表示该事件能否被取消。"composed"
,可选,Boolean
类型,默认值为false
,指示事件是否会在影子 DOM 根节点之外触发侦听器。
2, 案例:
注册一个testEvent
自定义事件
window.addEventListener("testEvent", (e) => {
console.log(e);
});
通过dispatchEvent
触发自定义事件,并且给testEvent
事件设为可冒泡
window.dispatchEvent(new Event("testEvent", { bubbles: true }));
3, 鼠标按下事件默认的禁止冒泡改为允许冒泡
window.addEventListener("mousedown", (e) => {
console.log(e);
});
window.dispatchEvent(new Event("mousedown", { bubbles: true }));
4, 场景:
小伙伴在使用element UI
时,肯定遇到过上图的问题。在使用select
组件时,经常会遇到下拉框关不掉。
其实是因为隐藏逻辑的是在mouseup
事件里写的, 而在移动滚动条的时候并没有触发mouseup
事件。
所以通过进行滚动等事件的时候触发mouseup
事件就行啦
重新注册鼠标点击离开事件
const MousedownEvent = new Event('mousedown', { bubbles: true })
const MouseupEvent = new Event('mouseup', { bubbles: true })
触发自定义事件
document.dispatchEvent(MousedownEvent)
document.dispatchEvent(MouseupEvent)
new CustomEvent使用方法介绍
它可以传递一些自定义的数据,然后在监听时间的回调函数中接收。
1, 案例:
<div onClick="btnTest('开始')">测试点击区域</div>
<script>
function btnTest(e) {
console.log(e);
console.log(window);
window.dispatchEvent(
new CustomEvent("testOne", {
detail: "自定义事件传的数据",
})
);
}
window.addEventListener("testOne", (e) => {
// 此处接收上面传递的 '自定义事件传的数据'
console.log(e);
});
2, 场景:
PS: 下文内容过多,没遇到下面这个场景的小伙伴,学习到此结束啦。可以先收藏,下次遇到这个场景再来看。
通过 new CustomEvent
进行uniapp转的APP端 和 APP端内嵌的H5端 两者的数据通信
具体思路如下(uniapp中的实现):
-
H5端全局封装
通信函数
(监听自定义事件+发送事件名给APP) -
H5端任意页面调用
通信函数
得到APP端的回参
进行自定义逻辑 -
APP端通过
webview
组件中的@message
接口接收H5端传过来的数据 -
APP端通过
this.wv.evalJS
触发H5端封装的dispatchJS
,携带APP中的数据 -
H5端通过
dispatchJS
触发自定义事件
并携带参数,参数在第二步通过APP端的回参
获得
2.1, H5端核心代码
通信函数
-
全局监听
自定义事件
,通过回参接收APP端传过来的数据 -
通过uni.postMessage把
自定义事件名
给到APP端
const useFn = (params) =>
new Promise((resolve) => {
const { action, payload } = params
const Handle = function (event) {
resolve(event.detail)
window.removeEventListener(action, Handle)
}
window.addEventListener(action, Handle)
console.log(action, payload)
uni.postMessage({
data: {
action,
payload,
},
})
})
function getAppEnvUrl() {
return useFn({
action: 'get_app_envurl',
payload: {},
})
}
export default {
getAppEnvUrl
}
dispatchJS函数(index.html里)
function dispatchJS(eventname, data) {
window.dispatchEvent(
new CustomEvent(eventname, {
detail: data,
})
)
}
2.2, APP端核心代码
<template>
<view>
<web-view
:webview-styles="webviewStyles"
:src="url"
@message="getMessage"
></web-view>
</view>
</template>
<script>
import store from '@/store'
export default {
data() {
return {
// 加载webview进度条颜色
webviewStyles: {
progress: {
color: '#FEE039'
}
},
url: '', // 网络路径
wv: null
}
},
methods: {
getMessage(e) {
if (e.detail && e.detail.data && e.detail.data.length > 0) {
this.presets(message)
}
},
presets(message) {
// 加载完webview
const webviewReady = () => {
this.wv = this.$scope.$getAppWebview().children()[0]
}
const getAppEnvUrl = () => {
const params = {
envUrl: this.$store.getters.envUrl
}
this.wv.evalJS(
`dispatchJS('${message.action}', ${JSON.stringify(params)})`
)
}
getAppEnvUrl()
}
}
}
</script>
<style lang="scss" scoped></style>
总结
本文主要介绍了new Event
和new CustomEvent
的使用方法和各自在项目中应用的案例。
细节一般是被忽略的,但是成长也是从抓住细节开始。
这篇文章的来源就是死扣细节,然后不断破案,学习总结出来的。
完结
这篇文章我尽力把我的笔记和想法放到这了,希望对小伙伴有帮助。
欢迎转载,但请注明来源。 最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。
转载自:https://juejin.cn/post/7238999195827109944