如何在H5页面实现横屏主动切换功能。
注意是主动切换横屏,而非是检测横竖屏。
目前尝试了两种方案,一种是通过旋转根节点,同时交换根节点宽高,并通过定位来实现布局中心点的偏移来实现样式上的横屏切换。但是这种方案遇到了一个问题,因为项目中引入了vant组件库,横屏后会导致组件库的一些样式计算出现问题,例如气泡弹出框,横屏后的弹出框的位置计算错误。同时一些选择器,还是需要竖屏下的上下操作才能滑动。以下是实现的一个简单的html示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>横屏切换示例</title>
<link rel="stylesheet" href="https://unpkg.com/vant@2.12/lib/index.css" />
</head>
<style>
#app {
transition: all 0.2s;
}
.landscape {
width: 100vh;
height: 100vw;
position: absolute;
top: calc((100vh - 100vw) / 2);
left: calc(-1 * (100vh - 100vw) / 2);
transform: rotate(90deg);
transform-origin: 50% 50%;
}
.my-swipe .van-swipe-item {
color: #fff;
font-size: 20px;
line-height: 150px;
text-align: center;
background-color: #39a9ed;
}
</style>
<body>
<div id="app">
<van-button type="primary" id="toggleFullscreen" @click="switchDirection">
{{ direction === directionObj.portrait ? "切换为横屏" : "切换为竖屏" }}
</van-button>
<van-popover
v-model="showPopover"
placement="bottom"
trigger="click"
:actions="actions"
get-container="#app"
id="popoverBtn"
>
<!-- :offset="[-112,-112]" -->
<template #reference>
<van-button type="primary">打开popover</van-button>
</template>
</van-popover>
<van-button type="primary" @click="openDialog">打开dialog</van-button>
<van-button type="primary" @click="showPopup = true">打开Popup</van-button>
<van-tabs>
<van-tab title="标签 1">内容 1</van-tab>
<van-tab title="标签 2">内容 2</van-tab>
<van-tab title="标签 3">内容 3</van-tab>
<van-tab title="标签 4">内容 4</van-tab>
</van-tabs>
<van-button type="primary" @click="previewImg">预览图片</van-button>
<div class="content">
<p>点击按钮切换横竖屏模式。</p>
</div>
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
<van-popup v-model="showPopup" position="bottom">
<van-picker title="标题" show-toolbar :columns="columns" />
</van-popup>
</div>
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/vant@2.12/lib/vant.min.js"></script>
<script>
const directionObj = {
portrait: "portrait", // 竖屏
landscape: "landscape", // 横屏
};
new Vue({
el: "#app",
data: () => {
return {
directionObj: directionObj,
direction: "portrait",
showPopover: false,
// 通过 actions 属性来定义菜单选项
actions: [{ text: "选项一" }, { text: "选项二" }, { text: "选项三" }],
showPopup: false,
columns: ["杭州", "宁波", "温州", "绍兴", "湖州", "嘉兴", "金华", "衢州"],
};
},
watch: {
direction(newValue) {
const appDom = document.getElementById("app");
if (newValue === directionObj.portrait) {
appDom.classList.remove(directionObj.landscape);
appDom.classList.add(directionObj.portrait);
} else {
appDom.classList.remove(directionObj.portrait);
appDom.classList.add(directionObj.landscape);
}
},
},
methods: {
switchDirection() {
if (this.direction === directionObj.portrait) {
this.direction = directionObj.landscape;
} else {
this.direction = directionObj.portrait;
}
},
openDialog() {
window.vant.Dialog.confirm({
title: "标题",
message: "弹窗内容",
getContainer: "#app",
}).then(() => {
console.log("ok");
});
},
previewImg() {
window.vant.ImagePreview({
images: [
"https://img01.yzcdn.cn/vant/apple-1.jpg",
"https://img01.yzcdn.cn/vant/apple-2.jpg",
],
startPosition: 0,
});
},
},
});
</script>
</body>
</html>
另外一种也是先通过样式旋转根节点,来实现横屏,然后在用户手动横屏后通过检测设备方向API来取消样式,使页面自然的横屏展示,但是如果用户设置了锁定屏幕,则也有一定的问题。
思路
通过旋转根节点实现横屏:
检测设备方向:
处理屏幕锁定:
兼容性处理:
代码实现
HTML 和 CSS
总结