html获取可见窗口大小

为了获取网页可见区域的高度,不同终端滚动元素指向 html 中 dom 是不一样的。
PC 端:document.scrollingElement = document.documentElement
Mobile 端:document.scrollingElement = document.body

兼容性

浏览器窗口视图

屏幕大小

1
2
3
4
5
6
window.screen.height:屏幕分辨率的高(屏幕的高度 )
window.screen.width:屏幕分辨率的宽 (屏幕的宽度 )
window.screen.availHeight:屏幕可用工作区的高
window.screen.availWidth:屏幕可用工作区的高
window.screenTop:浏览器窗口距离电脑屏幕上边界的距离
window.screenLeft:浏览器窗口距离电脑屏幕左边界的距离

window 大小

1
2
3
4
window. innerWidth :浏览器可视区域的内宽度,包含滚动条
window.innerHeight:浏览器可视区域的内高度,包含滚动条
window.outerWidth:浏览器宽度
window.outerHeight:浏览器高度

滚动偏移量

1
2
3
4
5
6
window.pageYOffset:需要网页存在滚动条才可以,存在竖向滚动条时,网页正文向下滚动一段距离n px,该值即为n
window.pageXOffset:同理,无滚动条值为0
document.body.scrollTop:网页下滑的距离(与上一对值相同,滚动条位置)
document.body.scrollLeft:网页左滑的距离
document.documentElement.scrollTop:与上一对值相同(与上一对都是获得滚动条位置,但是存在兼容问题)
document.documentElement.scrollLeft:兼容处理方案

兼容问题,具体与 html 文件头的<DOCTYPE…>有关
var srollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;

可见区域大小

1
2
3
4
document.body.clientWidth:获取可视区域的宽(可以进行页面展示的,不包含边线,例如body{border:10px solid red;})
documment.body.clientHeight:获取可视区域的高(可以进行页面展示的)
document.documentElement.clientWidth:页面可视宽度,但是不包含滚动条组件的十几px像素
document.documentElement.clientHeight:可视区域高度, 实际上就是 元素,只不过显示的是可见的部分,即浏览器窗口大小(网页无滚动条时与window.innerHeight同值)

滚动元素大小

1
2
3
4
document.documentElement.scrollWidth:获取网页正文全文宽(包括滚动部分)
document.documentElement.scrollHeight:获取网页正文全文高(包括滚动部分)
document.body.scrollWidth:与上一对值相同
document.body.scrollHeight:与上一对值相同

vuex常用注意事项

  • getter会缓存结果,不需要缓存,需要把getter变为函数

    1
    2
    3
    4
    5
    getters: {
    getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
    }
    }

    每次调用为

    1
    store.getters.getTodoById(1)

    这样通过函数触发,不会缓存每次结果

  • dispatch和commit区别
    dispatch为异步执行,会返回promise
    commit为同步执行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    actions: {
    async actionA ({ commit }) {
    commit('gotData', await getData())
    },
    async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
    }
    }

    store.dispatch('actionA').then(() => {
    // ...
    })

    一个 store.dispatch 在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行。

h5实现视频自动播放

最近项目中,需要用到网页视频自动播放功能,PC端没有问题,移动端无法自动播放。针对这个场景和网上资料查阅,分析各个方案优缺点,方便其他相似需求开发人员。

video标签说明

  • src: 设置显示视频路径
  • controls: 显示控制栏
  • loop: 控制视频循环播放
  • autoplay: 自动播放
  • muted: 设置静音播放
  • playsinline: 不全屏播放

PC端自动播放

1
2
3
4
5
6
7
8
<video id="video"
x5-video-player-type="h5" controls autoplay
controlsList="nofullscreen" playsinline
style="width: 100%; height:300px">
<source src="/video/test.mp4" type="video/mp4">
<source src="/video/test.webm" type="video/webm">
<p>Your browser doesn't support HTML5 video. Here is</p>
</video>

通过指定autoplay属性,即可实现自动播放

移动端自动播放分析

为了避免浪费流量和电池功耗损失,移动端浏览器禁止了自动播放功能,需要用户主动点击才会播放。

youtubo视频网站自动播放

针对视频访问量大网站,浏览器厂商有个白名单机制,放入白名单的域名,就能自动播放。参考链接https://blog.google/products/chrome/improving-autoplay-chrome/

设置autoplay、muted和playsinline

对video标签进行如下设置:

1
2
3
4
5
6
<video id="video" muted autoplay playsinline 
style="width: 100%; height:300px">
<source src="/video/test.mp4" type="video/mp4">
<source src="/video/test.webm" type="video/webm">
<p>Your browser doesn't support HTML5 video. Here is</p>
</video>

各个浏览器厂商表现不一样,具体如下:

平台/浏览器 自带 微信
iOS >= 10.0(关闭低功耗开关)
iOS < 10.0
Android
华为
PC

微信App自动播放(不点击播放器按钮)

在微信App中,h5通过集成微信sdk,并监听SDK初始化桥事件,然后开启播放器播放。设置如下:

  1. 设置SDK
1
2
3
4
5
6
7
8
9
10
11
<script src="//res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
window.wxInited = false
document.addEventListener('WeixinJSBridgeReady', e => {
const video = document.getElementById('video')
if (video) {
video.play()
video.pause()
}
}, false)
</script>
  1. 设置video标签
1
2
3
4
5
6
7
<video id="video" x5-video-player-type="h5"
controls controlsList="nofullscreen"
playsinline style="width: 100%; height:0px">
<source src="/video/test.mp4" type="video/mp4">
<source src="/video/test.webm" type="video/webm">
<p>Your browser doesn't support HTML5 video. Here is</p>
</video>

通过上述设置,播放器处于可播放状态,后续非人工触发play或pause操作,都可以操作播放器。

各个浏览器厂商表现一致,具体如下:

平台/浏览器 自带 微信
iOS
Android
华为
PC

人工触发事件(不点击播放器按钮)

除了点击播放器的播放或暂停按钮,可以触发播放操作。用户主动点击(click)事件或滑动(touchstart、touchmove、touchend)事件,可以触发播放器播放操作。设置如下:

1
2
3
4
5
6
7
8
document.addEventListener('click', function () {
const video = document.getElementById('video')
if (video) {
video.play()
}
},
{ capture: true, passive: true }
)

各个浏览器厂商表现一致,具体如下:

平台/浏览器 自带 微信
iOS
Android
华为
PC

非视频降级方案

根据上述的分析,每种方案都有些不足,并不能解决所有平台和浏览器的问题。针对静音的视频环境,可以把视频转化为图片,按照一定的周期播放图片,这样所有的平台都支持。

这里参考了「张鑫旭大佬」的方案,实现原理如下:

  1. 图片DOM对象预加载,放在内存中;
  2. 播放开始,页面append当前图片DOM,同时移除上一帧DOM图片(如果有),保证页面中仅有一个图片序列元素; 对,很简单,没什么高超的技巧,但就是这种实现策略,对页面的开销是最小的,最终运行体验是最好的。
1
2
3
4
5
6
7
8
<div class="page" style="background-image: url(&quot;https://website.didiglobal.com/dist/img/homepage1-app.fb9b0c10.jpg&quot;);">
<div class="home-video-wrap">
<div class="video-app-container">
<img src="https://website.didiglobal.com/dist/img/合成 1_00315.68c3cb63.jpg">
</div>
<div class="mask-whole"></div>
</div>
</div>

图片轮播demo,参考滴滴移动官网

视频转为图片

方案如下:

  1. 电脑打开premiere cc 2017,导入视频编辑好。 img
  2. 编辑好视频后,按导出快捷键Ctrl+M调出导出页面,然后格式选择JPEG格式。 img

3.点击输出名称选择保存路径。

img

4.设置好格式和保存路径后,点击底部的导出,等待图片的导出就可以了。 img

移动端自动播放兼容方案

自动播放需要满足几个条件所有移动端手机都可以自动播放:

  1. 必须要有用户点击事件touch
  2. 接收点击事件的标签和video标签不能是父子关系(就是body接收的点击事件调用video的play方法,播放器也是不会播放视频的
  3. 接收点击时候后,立即执行play()方法,网络请求后调用play()方法可能会无效

因此,页面初始化话的时候写一个video标签,这个video标签在可见区域之外,video标签和需要点击事件控件不是父子关系,当用户点击播放按钮时,立刻调用play()方法。设置video标签的样式到可见区域内,通过z-index控制层级关系,就能实现自动播放。

根据上述方案分析,选择合适自己的使用场景,同时做好兼容,如

  1. 当不支持自动播放时,通过文案提示或手势引导,提示用户点击播放

参考说明

PC端、移动端Video自动播放兼容完美解决方案(IOS、安卓、微信端)
移动端视频 video 的 Android 兼容,去除播放控件、全屏等