为什么 React 悬停时播放或暂停出错
Why there is Error in Playing or Pausing When Hovered in React
我有几个视频要在我的应用程序中显示。
我想要它,如果它悬停它会播放,当鼠标离开它时,它会暂停。但是我的问题是它输出错误 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()
.
下面是我的代码
const Video = ({ video }) => {
const videoRef = useRef();
return (
<div
onMouseOver={() => video?.promoVideoUrl && videoRef?.current?.play()}
onFocus={() => video?.promoVideoUrl && videoRef?.current?.play()}
onMouseOut={() => video?.promoVideoUrl && videoRef?.current?.pause()}
onBlur={() => video?.promoVideoUrl && videoRef?.current?.pause()}
className="col-12"
>
<>
<a target="_blank" href={`/videos/${video.id}`} rel="noreferrer">
<video
ref={videoRef}
muted
height="100%"
width="100%"
poster={video?.poster}
src={video?.url}
loop
preload="auto"
/>
</a>
</>
</div>
);
};
export default Video;
这可能有两个原因。类似问题已在whosebug.com
中回答
原因一 - 调用暂停而不等待播放承诺解决
原因二 - 在选项卡未获得焦点时调用播放
解决方案如下:
const = videoRef.current;
// Initializing values
letisPlaying = true;
// On video playing toggle values
video.onplaying = function() {
isPlaying = true;
};
// On video pause toggle values
video.onpause = function() {
isPlaying = false;
};
// Play video function
function playVid() {
if (video.paused && !isPlaying) {
video.play();
}
}
// Pause video function
function pauseVid() {
if (!video.paused && isPlaying) {
video.pause();
}
}
播放视频时,需要先加载视频,然后才真正播放。如果您在执行此操作时暂停,则会收到错误消息。
解决方案是使用 play
操作返回的承诺,并等待它解决以便暂停。看到这个 article.
const { useRef, useMemo } = React;
const useVideo = (url) => {
const videoRef = useRef();
const handlers = useMemo(() => {
let videoLoaded;
return {
start() {
if(!url || !videoRef.current) return;
videoLoaded = videoRef.current.play()
},
pause() {
if(!url || !videoRef.current) return;
videoLoaded.then(() => {
videoRef.current.pause();
});
}
}
}, [url]);
return {
videoRef,
...handlers
};
};
const Video = ({ video }) => {
const { start, pause, videoRef } = useVideo(video.url);
return (
<div
onMouseOver={start}
onMouseOut={pause}
onFocus={start}
onBlur={pause}
className="col-12"
>
<a target="_blank" href={`/videos/${video.id}`} rel="noreferrer">
<video
ref={videoRef}
muted
height="100%"
width="100%"
poster={video.poster}
src={video.url}
loop
preload="auto"
/>
</a>
</div>
);
};
ReactDOM.render(
<Video video={{ url: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4', id: '' }} />,
root
)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
我有几个视频要在我的应用程序中显示。
我想要它,如果它悬停它会播放,当鼠标离开它时,它会暂停。但是我的问题是它输出错误 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()
.
下面是我的代码
const Video = ({ video }) => {
const videoRef = useRef();
return (
<div
onMouseOver={() => video?.promoVideoUrl && videoRef?.current?.play()}
onFocus={() => video?.promoVideoUrl && videoRef?.current?.play()}
onMouseOut={() => video?.promoVideoUrl && videoRef?.current?.pause()}
onBlur={() => video?.promoVideoUrl && videoRef?.current?.pause()}
className="col-12"
>
<>
<a target="_blank" href={`/videos/${video.id}`} rel="noreferrer">
<video
ref={videoRef}
muted
height="100%"
width="100%"
poster={video?.poster}
src={video?.url}
loop
preload="auto"
/>
</a>
</>
</div>
);
};
export default Video;
这可能有两个原因。类似问题已在whosebug.com
中回答原因一 - 调用暂停而不等待播放承诺解决
原因二 - 在选项卡未获得焦点时调用播放
解决方案如下:
const = videoRef.current;
// Initializing values
letisPlaying = true;
// On video playing toggle values
video.onplaying = function() {
isPlaying = true;
};
// On video pause toggle values
video.onpause = function() {
isPlaying = false;
};
// Play video function
function playVid() {
if (video.paused && !isPlaying) {
video.play();
}
}
// Pause video function
function pauseVid() {
if (!video.paused && isPlaying) {
video.pause();
}
}
播放视频时,需要先加载视频,然后才真正播放。如果您在执行此操作时暂停,则会收到错误消息。
解决方案是使用 play
操作返回的承诺,并等待它解决以便暂停。看到这个 article.
const { useRef, useMemo } = React;
const useVideo = (url) => {
const videoRef = useRef();
const handlers = useMemo(() => {
let videoLoaded;
return {
start() {
if(!url || !videoRef.current) return;
videoLoaded = videoRef.current.play()
},
pause() {
if(!url || !videoRef.current) return;
videoLoaded.then(() => {
videoRef.current.pause();
});
}
}
}, [url]);
return {
videoRef,
...handlers
};
};
const Video = ({ video }) => {
const { start, pause, videoRef } = useVideo(video.url);
return (
<div
onMouseOver={start}
onMouseOut={pause}
onFocus={start}
onBlur={pause}
className="col-12"
>
<a target="_blank" href={`/videos/${video.id}`} rel="noreferrer">
<video
ref={videoRef}
muted
height="100%"
width="100%"
poster={video.poster}
src={video.url}
loop
preload="auto"
/>
</a>
</div>
);
};
ReactDOM.render(
<Video video={{ url: 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4', id: '' }} />,
root
)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>