fix: 预览按钮重复插入

feat: 预览放大时无需鼠标悬停
This commit is contained in:
wsgh0202 2025-06-25 23:55:08 +08:00
parent 408b3efd93
commit 7450e19854
No known key found for this signature in database
GPG Key ID: F9658C3FEDCF6979

View File

@ -32,38 +32,96 @@ const entry: ComponentEntry = async () => {
* @returns {HTMLElement}
*/
function createPreviewButton(className: string): HTMLElement {
const ComponentClass = Vue.extend(PreviewButton)
// #region 局部定义
/**
*
* @param show
* @param btn
*/
const toggleButtonIcon = (show: boolean, btn: any) => {
btn.enlarged = show
}
/**
*
* @param {MouseEvent} event -
*/
const onMouseExitHandler = (event: MouseEvent) => {
event.stopPropagation()
}
/**
*
* @param {boolean} show -
* @param {Element} movingDom - DOM
*/
const toggleMouseExitHandler = (show: boolean, movingDom: Element) => {
if (show) {
movingDom.addEventListener('mouseleave', onMouseExitHandler, true)
} else {
movingDom.removeEventListener('mouseleave', onMouseExitHandler, true)
// 触发mouseleave事件停止预览
const mouseLeaveEvent = new MouseEvent('mouseleave')
movingDom.dispatchEvent(mouseLeaveEvent)
}
}
/**
*
* @param {Element} movingDom - DOM
* @param {boolean} show -
*/
const toggleVideoControls = (movingDom: Element, show: boolean) => {
const video = movingDom.querySelector('video')
if (video) {
video.controls = show
}
}
// 提升 popupChangeHandler 到外部作用域,确保引用一致
let popupChangeHandler: (show: boolean) => void
// #endregion
// 创建 Vue 实例
const ComponentClass = Vue.extend(PreviewButton)
const instance = new ComponentClass({
propsData: {
btnClass: className,
btnOnClickCallback: (e: MouseEvent) => {
e.preventDefault()
// 监听 popup-change 事件
const popupChangeHandler = (show: boolean) => {
// 关闭弹窗时重置图标
if (!show) {
instance.enlarged = false
if (!videoContainer) {
return
}
const movingDom = instance.$el.parentElement.closest('.bili-video-card__image,.pic-box')
// 监听弹窗状态变化事件
if (!popupChangeHandler) {
popupChangeHandler = (show: boolean) => {
// 切换按钮图标
toggleButtonIcon(show, instance)
// 切换鼠标移出事件监听
toggleMouseExitHandler(show, movingDom)
// 切换视频控件显示
toggleVideoControls(movingDom, show)
if (!show) {
videoContainer.$off('popup-change', popupChangeHandler)
}
}
}
// 根据当前状态切换预览
if (instance.enlarged) {
if (videoContainer) {
videoContainer.$off('popup-change', popupChangeHandler)
videoContainer.closePopup()
}
videoContainer.closePopup()
} else {
const video = instance.$el.parentElement.closest('.bili-video-card__image,.pic-box')
if (videoContainer) {
videoContainer.$on('popup-change', popupChangeHandler)
videoContainer.openPopup(video)
}
videoContainer.$off('popup-change', popupChangeHandler)
videoContainer.$on('popup-change', popupChangeHandler)
videoContainer.openPopup(movingDom)
}
// 切换按钮图标
instance.enlarged = !instance.enlarged
},
},
})
@ -81,7 +139,8 @@ const entry: ComponentEntry = async () => {
function insertPreviewButton(node: HTMLElement, className: string) {
const wrap = node.querySelectorAll('.v-inline-player,.v-recommend-inline-player')
wrap.forEach(it => {
if (it.querySelector(`.${className}`)) {
// 检查父元素下是否已经有该按钮,避免重复插入
if (it.parentElement.querySelector(`.${className}`)) {
return
}