mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
📦 refactor(scroll-out-player): replace scroll listener to intersectionOberver
This commit is contained in:
parent
ad85e9fd5e
commit
7e3fa08dcd
2
src/global.d.ts
vendored
2
src/global.d.ts
vendored
@ -519,7 +519,7 @@ declare global {
|
||||
checkInCenter: boolean,
|
||||
fullscreenGiftBox: boolean,
|
||||
scrollOutPlayer: boolean,
|
||||
scrollOutPlayerTriggerPlace: string[],
|
||||
scrollOutPlayerTriggerPlace: string,
|
||||
scrollOutPlayerAutoPause: boolean,
|
||||
scrollOutPlayerAutoLightOn: boolean,
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
let videoEl: HTMLVideoElement;
|
||||
let playerWrap: HTMLElement;
|
||||
let mode = '视频中间';
|
||||
let observer: IntersectionObserver;
|
||||
|
||||
enum MODE {
|
||||
TOP = '视频顶部',
|
||||
@ -8,52 +8,19 @@ enum MODE {
|
||||
BOT = '视频底部',
|
||||
}
|
||||
|
||||
function getToTop(_mode: string, client: DOMRect): number {
|
||||
function getToTop(_mode: string): number {
|
||||
switch (_mode) {
|
||||
case MODE.TOP:
|
||||
return client?.top;
|
||||
return 1;
|
||||
case MODE.MID:
|
||||
return client?.top + client?.height / 2;
|
||||
return 0.5;
|
||||
case MODE.BOT:
|
||||
return client?.top + client?.height;
|
||||
default:
|
||||
return 0;
|
||||
default:
|
||||
return 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
// run callback when video el scroll out.
|
||||
let handlePlayerOut = function (_mode: string, callback?: () => void) {
|
||||
const videoClient = playerWrap?.getBoundingClientRect();
|
||||
if (videoClient?.top && videoClient.height) {
|
||||
let toTop = getToTop(_mode, videoClient);
|
||||
if (toTop <= 0) {
|
||||
callback ? callback() : '';
|
||||
// get ready to check when the video el came back.
|
||||
window.addEventListener('scroll', onPlayerBackEvent, {
|
||||
passive: true,
|
||||
});
|
||||
// remove out listener when got out.
|
||||
window.removeEventListener('scroll', onPlayerOutEvent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// run callback when video el scroll back.
|
||||
let handlePlayerBack = function (_mode: string, callback?: () => void) {
|
||||
const videoClient = playerWrap?.getBoundingClientRect();
|
||||
if (videoClient?.top && videoClient.height) {
|
||||
let toTop = getToTop(_mode, videoClient);
|
||||
if (toTop >= 0) {
|
||||
callback ? callback() : '';
|
||||
// this will done by play listener
|
||||
window.addEventListener('scroll', onPlayerOutEvent, {
|
||||
passive: true,
|
||||
});
|
||||
window.removeEventListener('scroll', onPlayerBackEvent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let lightOff = () => {};
|
||||
let lightOn = () => {};
|
||||
async function initLights() {
|
||||
@ -76,74 +43,82 @@ async function initLights() {
|
||||
lightOn = () => setLight(false);
|
||||
}
|
||||
|
||||
function onPlayerOutEvent() {
|
||||
handlePlayerOut(mode, () => {
|
||||
if (settings.scrollOutPlayerAutoPause && !videoEl.paused) videoEl.pause();
|
||||
// 满足条件: 自动开灯功能启用、自动关灯功能启用、没有启用自动暂停
|
||||
// 补充: 当启用自动关灯与自动暂停时, 自动开灯动作由自动暂停完成
|
||||
if (
|
||||
settings.scrollOutPlayerAutoLightOn &&
|
||||
settings.autoLightOff &&
|
||||
!settings.scrollOutPlayerAutoPause
|
||||
)
|
||||
lightOn();
|
||||
});
|
||||
}
|
||||
|
||||
function onPlayerBackEvent() {
|
||||
handlePlayerBack(mode, () => {
|
||||
if (settings.scrollOutPlayerAutoPause && videoEl.paused) videoEl.play();
|
||||
// 回来时自动关灯
|
||||
// 满足条件: 自动开灯功能启用、自动关灯功能启用、没有启用自动暂停、视频播放中
|
||||
if (
|
||||
settings.scrollOutPlayerAutoLightOn &&
|
||||
settings.autoLightOff &&
|
||||
!settings.scrollOutPlayerAutoPause &&
|
||||
!videoEl.paused
|
||||
)
|
||||
lightOff();
|
||||
});
|
||||
}
|
||||
|
||||
function addPlayerOutEvent() {
|
||||
window.addEventListener('scroll', onPlayerOutEvent, { passive: true });
|
||||
// window.addEventListener('scroll', onPlayerOutEvent, { passive: true });
|
||||
observer.observe(playerWrap);
|
||||
}
|
||||
|
||||
function removePlayerOutEvent() {
|
||||
window.removeEventListener('scroll', onPlayerOutEvent);
|
||||
// window.removeEventListener('scroll', onPlayerOutEvent);
|
||||
observer.unobserve(playerWrap);
|
||||
}
|
||||
|
||||
function mountListener() {
|
||||
let intersectingCall = () => {
|
||||
if (settings.scrollOutPlayerAutoPause && videoEl.paused) videoEl.play();
|
||||
if (
|
||||
settings.scrollOutPlayerAutoLightOn &&
|
||||
settings.autoLightOff &&
|
||||
!settings.scrollOutPlayerAutoPause &&
|
||||
!videoEl.paused
|
||||
)
|
||||
lightOff();
|
||||
};
|
||||
|
||||
let disIntersectingCall = () => {
|
||||
if (settings.scrollOutPlayerAutoPause && !videoEl.paused) videoEl.pause();
|
||||
if (
|
||||
settings.scrollOutPlayerAutoLightOn &&
|
||||
settings.autoLightOff &&
|
||||
!settings.scrollOutPlayerAutoPause
|
||||
)
|
||||
lightOn();
|
||||
};
|
||||
|
||||
let createObserver = (mode?: string) =>
|
||||
new IntersectionObserver(
|
||||
([e]) => {
|
||||
e.isIntersecting ? intersectingCall() : disIntersectingCall();
|
||||
},
|
||||
{
|
||||
root: document,
|
||||
threshold: getToTop(mode ? mode : settings.scrollOutPlayerTriggerPlace),
|
||||
}
|
||||
);
|
||||
|
||||
function mountPlayListener() {
|
||||
Observer.videoChange(async () => {
|
||||
videoEl.addEventListener('play', addPlayerOutEvent);
|
||||
// onPlayerOutEvent 不会在我们手动暂停视频时移除, 所以需要监听暂停.
|
||||
videoEl.addEventListener('pause', removePlayerOutEvent);
|
||||
// videoEl.addEventListener('pause', removePlayerOutEvent);
|
||||
videoEl.addEventListener('ended', removePlayerOutEvent);
|
||||
});
|
||||
}
|
||||
|
||||
async function setup() {
|
||||
(async function setup() {
|
||||
await initLights();
|
||||
addSettingsListener('triggerPlayerOutPlace', (value) => (mode = value));
|
||||
addSettingsListener('scrollOutPlayerTriggerPlace', (value) => {
|
||||
removePlayerOutEvent();
|
||||
observer = createObserver(value);
|
||||
addPlayerOutEvent();
|
||||
console.log(observer);
|
||||
});
|
||||
videoEl = dq('.bilibili-player-video video') as HTMLVideoElement;
|
||||
playerWrap = (dq('.player-wrap') || dq('.player-module')) as HTMLElement;
|
||||
mountListener();
|
||||
}
|
||||
setup();
|
||||
observer = createObserver();
|
||||
mountPlayListener();
|
||||
})();
|
||||
|
||||
export default {
|
||||
reload: () => {
|
||||
window.addEventListener('scroll', onPlayerOutEvent);
|
||||
mountListener();
|
||||
addPlayerOutEvent();
|
||||
mountPlayListener();
|
||||
},
|
||||
unload: () => {
|
||||
// remove all listener
|
||||
Observer.videoChange(async () => {
|
||||
videoEl.removeEventListener('play', addPlayerOutEvent);
|
||||
// umount player listener
|
||||
Observer.videoChange(async () => { videoEl.removeEventListener('play', addPlayerOutEvent);
|
||||
videoEl.removeEventListener('pause', removePlayerOutEvent);
|
||||
videoEl.removeEventListener('ended', removePlayerOutEvent);
|
||||
});
|
||||
window.removeEventListener('scroll', onPlayerOutEvent);
|
||||
window.removeEventListener('scroll', onPlayerBackEvent);
|
||||
removePlayerOutEvent();
|
||||
},
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user