前言
在本文中,你将学到如何使用react+hook的方式,实现一个移动端和PC端都能用的点击全屏功能,实现效果如下:
思路
我们的目标是通过点击实现全屏效果,那么我们就需要两个东西:
执行的时机执行的功能函数
执行的时机我们可以理解为触发方式,比如,打开页面、点击、拖拽等等等;
那么执行的功能函数,考虑到该方法的复用效果,可以添加任意时机等等等,所以用一个自定义hook方法来实现;
那么思路有了,我们来实现它吧。
实现步骤
1、封装一个简单小按钮
我们这里的触发时机是点击,所以先来封装一个小按钮,当然也可以是自动的或者别的方式等等,选择自己合适的时机即可;
所以我们这里先封装一个简单的小按钮:
import React, { useEffect, useState } from "react"
export default function FullButton() {
return (
<div>
<button onClick = {() => console.log(111)}>点击全屏</button>
</div>
)
}
在按钮点击事件这里,我们将调用对应的功能函数;
2、定义好hook的名称及暴露的函数
首先重中之重的功能函数需要暴露出去,还有一个当前的全屏状态,用于告诉使用它的组件当时是否是全屏:
import React, { useState } from "react"
export function useFullscreen() {
const [screenStatus, setScreenStatus] = useState(false); // 全屏状态
/** 全屏功能函数 */
const onFullscreen =() => {
}
return {
screenStatus,
onFullscreen,
}
}
3、在按钮组件中引用对应的值
我们在这里通过对应的路径引入进来,且将暴露出来的值逻辑给写好:
import React, { useEffect, useState } from "react";
import { useFullscreen } from "./hooks/useFullscreen";
export default function FullButton() {
const { onFullscreen, screenStatus } = useFullscreen();
return (
<div>
<button onClick = {onFullscreen}>{screenStatus? '全屏':'非全屏'}</button>
</div>
)
}
4、实现全屏功能函数
第一步是检测当前网页是否处于全屏模式或独立模式,如果未处于,则执行全屏逻辑;如果处于,则执行退出全屏逻辑,且这里要注意一下兼容性;
import React, { useState } from "react"
export function useFullscreen() {
const [screenStatus, setScreenStatus] = useState(false); // 全屏状态
/** 全屏功能函数 */
const onFullscreen =() => {
let status = !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement && !window.navigator.standalone && !document.webkitCurrentFullScreenElement
setScreenStatus(status);
if (!status) { // 退出全屏
} else { // 进入全屏
}
}
return {
screenStatus,
onFullscreen,
}
}
第二步执行全屏逻辑,执行时需要将全屏状态更改为全屏,以及还有需要注意三点:
兼容性异常友好提示非异步(火狐要求全屏请求必须在用户交互事件(如点击或按键)中同步执行)
import React, { useState } from "react";
import { Toast } from "antd-mobile";
export function useFullscreen() {
const [screenStatus, setScreenStatus] = useState(false); // 全屏状态
/** 全屏逻辑 */
const handlefullscreen = () => {
const element = document.body;
// 此方法应是同步,否则一些浏览器无法全屏
try {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
} else if (element.oRequestFullscreen) {
element.oRequestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullScreen()
} else {
Toast.show({ content: '暂不支持全屏功能' })
}
} catch (res) {
Toast.show({ content: '当前浏览器暂不支持此功能' })
}
}
/** 全屏功能函数 */
const onFullscreen =() => {
let status = !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement && !window.navigator.standalone && !document.webkitCurrentFullScreenElement
setScreenStatus(status);
if (!status) { // 退出全屏
} else { // 进入全屏
setScreenStatus(true);
handlefullscreen()
}
}
return {
screenStatus,
onFullscreen,
}
}
那么此时我们到这里已经实现了点击全屏的效果,大家可以尝试一下;
但是我们将很快发现一个问题,那就是没办法退出全屏,哎,这不行啊,所以我们第三步将写一段退出全屏逻辑;
第三步执行退出全屏逻辑,我们知道常用的退出全屏有esc按键(浏览器自带的),那么这里我们通过两种交互,esc和点击,去退出全屏,当然也要记得更改全屏状态;
import React, { useState } from "react"
import { Toast } from "antd-mobile";
export function useFullscreen() {
const [screenStatus, setScreenStatus] = useState(false); // 全屏状态
/** 全屏逻辑 */
const handlefullscreen = () => {
const element = document.body;
// 此方法不可以在異步任務中執行,否則火狐無法全屏
try {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
} else if (element.oRequestFullscreen) {
element.oRequestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullScreen()
} else {
Toast.show({ content: '暂不支持全屏功能' })
setScreenStatus(false); // 也需要更改文案
}
} catch (res) {
Toast.show({ content: '当前浏览器暂不支持此功能' })
setScreenStatus(false); // 也需要更改文案
}
}
// 退出全屏逻辑
const handleExitfullscreen = () => {
try {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.oRequestFullscreen) {
document.oCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
} else {
Toast.show({ content: '请按esc退出全屏' })
}
} catch (res) {
Toast.show({ content: '当前浏览器暂不支持此功能' })
}
}
/** 全屏功能函数 */
const onFullscreen =() => {
let status = !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement && !window.navigator.standalone && !document.webkitCurrentFullScreenElement
/*这里需要注意一下,在某些浏览器全屏会阻断渲染,所以这里用setTimeOut过渡一下*/
setTimeout(() => { /** 这里需要异步,某些浏览器的全屏中渲染会失效阻塞 */
setScreenStatus(status);
} , 100)
if (!status) { // 退出全屏
setScreenStatus(false);
handleExitfullscreen()
} else { // 进入全屏
setScreenStatus(true);
handlefullscreen()
}
}
return {
screenStatus,
onFullscreen,
}
}
那么到这里我们就已经实现了全屏和退出全屏的逻辑了,我们可以尝试一下;
总结
本文通过组件+hook的形式实现了全屏的功能,基本满足应用级项目的使用了;
如果还需要在全屏中执行对应的逻辑,可以通过在hook传参数的形式,将对应函数传进去,然后在特定的地方去调用就行,本文就不再赘述;
还有需要注意的一点是,此方法在手机端百度浏览器调用会触发分屏的效果,需要注意,希望能带给大家一点启发!!!