fix: 解决父容器相同时,后渲染的水印没有防御功能的问题
This commit is contained in:
parent
f3e71e0795
commit
413305322d
@ -1,7 +1,7 @@
|
|||||||
import { type Ref, onBeforeUnmount, ref } from "vue"
|
import { type Ref, onBeforeUnmount, ref } from "vue"
|
||||||
import { debounce } from "lodash-es"
|
import { debounce } from "lodash-es"
|
||||||
|
|
||||||
type TargetNode<T> = T & { _mutationObserver?: MutationObserver; _resizeObserver?: ResizeObserver }
|
type Observer = { mutationObserver?: MutationObserver; resizeObserver?: ResizeObserver }
|
||||||
|
|
||||||
type DefaultConfig = typeof defaultConfig
|
type DefaultConfig = typeof defaultConfig
|
||||||
|
|
||||||
@ -38,6 +38,11 @@ export function useWatermark(parentEl: Ref<HTMLElement | null> = bodyEl) {
|
|||||||
let mergeConfig: DefaultConfig
|
let mergeConfig: DefaultConfig
|
||||||
/** 水印元素 */
|
/** 水印元素 */
|
||||||
let watermarkEl: HTMLElement | null = null
|
let watermarkEl: HTMLElement | null = null
|
||||||
|
/** 观察器 */
|
||||||
|
const observer: Observer = {
|
||||||
|
mutationObserver: undefined,
|
||||||
|
resizeObserver: undefined
|
||||||
|
}
|
||||||
|
|
||||||
/** 设置水印 */
|
/** 设置水印 */
|
||||||
const setWatermark = (text: string, config: Partial<DefaultConfig> = {}) => {
|
const setWatermark = (text: string, config: Partial<DefaultConfig> = {}) => {
|
||||||
@ -124,9 +129,9 @@ export function useWatermark(parentEl: Ref<HTMLElement | null> = bodyEl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 监听水印容器的变化(DOM 变化 & DOM 大小变化) */
|
/** 监听水印容器的变化(DOM 变化 & DOM 大小变化) */
|
||||||
const addParentElListener = (targetNode: TargetNode<HTMLElement>) => {
|
const addParentElListener = (targetNode: HTMLElement) => {
|
||||||
// 防止重复添加监听
|
// 防止重复添加监听
|
||||||
if (targetNode._mutationObserver || targetNode._resizeObserver) return
|
if (observer.mutationObserver || observer.resizeObserver) return
|
||||||
// 监听 DOM 变化
|
// 监听 DOM 变化
|
||||||
addMutationListener(targetNode)
|
addMutationListener(targetNode)
|
||||||
// 监听 DOM 大小变化
|
// 监听 DOM 大小变化
|
||||||
@ -134,17 +139,17 @@ export function useWatermark(parentEl: Ref<HTMLElement | null> = bodyEl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 移除对水印容器的监听 */
|
/** 移除对水印容器的监听 */
|
||||||
const removeParentElListener = (targetNode: TargetNode<HTMLElement>) => {
|
const removeParentElListener = (targetNode: HTMLElement) => {
|
||||||
// 移除 mutation 监听
|
// 移除 mutation 监听
|
||||||
targetNode._mutationObserver?.disconnect()
|
observer.mutationObserver?.disconnect()
|
||||||
targetNode._mutationObserver = undefined
|
observer.mutationObserver = undefined
|
||||||
// 移除 resize 监听
|
// 移除 resize 监听
|
||||||
targetNode._resizeObserver?.unobserve(targetNode)
|
observer.resizeObserver?.unobserve(targetNode)
|
||||||
targetNode._resizeObserver = undefined
|
observer.resizeObserver = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 监听 DOM 变化 */
|
/** 监听 DOM 变化 */
|
||||||
const addMutationListener = (targetNode: TargetNode<HTMLElement>) => {
|
const addMutationListener = (targetNode: HTMLElement) => {
|
||||||
// 观察器的配置(需要观察哪些变动)
|
// 观察器的配置(需要观察哪些变动)
|
||||||
const mutationObserverOptions: MutationObserverInit = {
|
const mutationObserverOptions: MutationObserverInit = {
|
||||||
// 观察目标节点属性变动
|
// 观察目标节点属性变动
|
||||||
@ -173,24 +178,22 @@ export function useWatermark(parentEl: Ref<HTMLElement | null> = bodyEl) {
|
|||||||
})
|
})
|
||||||
}, 500)
|
}, 500)
|
||||||
// 创建一个观察器实例并传入回调
|
// 创建一个观察器实例并传入回调
|
||||||
const mutationObserver = new MutationObserver(mutationCallback)
|
observer.mutationObserver = new MutationObserver(mutationCallback)
|
||||||
// 以上述配置开始观察目标节点
|
// 以上述配置开始观察目标节点
|
||||||
mutationObserver.observe(targetNode, mutationObserverOptions)
|
observer.mutationObserver.observe(targetNode, mutationObserverOptions)
|
||||||
targetNode._mutationObserver = mutationObserver
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 监听 DOM 大小变化 */
|
/** 监听 DOM 大小变化 */
|
||||||
const addResizeListener = (targetNode: TargetNode<HTMLElement>) => {
|
const addResizeListener = (targetNode: HTMLElement) => {
|
||||||
// 当 targetNode 元素大小变化时去更新整个水印的大小
|
// 当 targetNode 元素大小变化时去更新整个水印的大小
|
||||||
const resizeCallback = debounce(() => {
|
const resizeCallback = debounce(() => {
|
||||||
const { clientWidth, clientHeight } = targetNode
|
const { clientWidth, clientHeight } = targetNode
|
||||||
updateWatermarkEl({ width: clientWidth, height: clientHeight })
|
updateWatermarkEl({ width: clientWidth, height: clientHeight })
|
||||||
}, 500)
|
}, 500)
|
||||||
// 创建一个观察器实例并传入回调
|
// 创建一个观察器实例并传入回调
|
||||||
const resizeObserver = new ResizeObserver(resizeCallback)
|
observer.resizeObserver = new ResizeObserver(resizeCallback)
|
||||||
// 开始观察目标节点
|
// 开始观察目标节点
|
||||||
resizeObserver.observe(targetNode)
|
observer.resizeObserver.observe(targetNode)
|
||||||
targetNode._resizeObserver = resizeObserver
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 在组件卸载前移除水印以及各种监听 */
|
/** 在组件卸载前移除水印以及各种监听 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user