在每个页面上停止视频和音频自动播放
很少有事比打开一个标签页就被声音轰炸更糟。浏览器的自动播放策略有帮助,但静音的视频仍在动,背景音频仍会溜进来。一条 JustZix 规则在它开始的瞬间把这一切都关掉。
策略
不要试图预测哪个元素会自动播放,而是去回应。每个媒体元素在开始时都会触发一个 play 事件。在捕获模式下监听那个事件,如果播放不是你启动的,就暂停它。
document.addEventListener('play', function (e) {
var m = e.target;
if (m && (m.tagName === 'VIDEO' || m.tagName === 'AUDIO')) {
m.pause();
}
}, true);
这很粗暴:它暂停一切,包括你点击的视频。下面的完整配方加了一个允许列表,让你自己的点击仍然有效。
暂停自动播放但保持点击有效
诀窍是每当用户与页面交互时记录一个时间戳。如果一个 play 事件在远离任何交互时触发,它就是自动播放,会被暂停。
(function () {
var lastInteraction = 0;
['pointerdown', 'keydown', 'touchstart'].forEach(function (evt) {
document.addEventListener(evt, function () {
lastInteraction = Date.now();
}, true);
});
document.addEventListener('play', function (e) {
var m = e.target;
if (!m || (m.tagName !== 'VIDEO' && m.tagName !== 'AUDIO')) { return; }
var sinceClick = Date.now() - lastInteraction;
if (sinceClick > 800) {
m.pause();
m.autoplay = false;
}
}, true);
})();
800 毫秒的窗口足够宽裕,能把一次点击算作有意的,同时仍然捕获在页面加载时开始的媒体。设置 autoplay = false 阻止元素重试。
把静音作为兜底
有些播放器很执着,会循环重启播放。与其打一场无尽的暂停之战,不如先静音,让页面至少安静下来,然后再暂停。
document.addEventListener('play', function (e) {
var m = e.target;
if (m && (m.tagName === 'VIDEO' || m.tagName === 'AUDIO')) {
m.muted = true;
m.volume = 0;
m.pause();
}
}, true);
静音加上零音量同时覆盖了简单的 muted 标志和直接读取 volume 的播放器。
让新媒体默认静音
你也可以主动出击。这条规则在任何媒体元素一出现时就把它静音,趁它还没机会发出声音。它与上面的暂停逻辑搭配得很好。
(function () {
function mute(m) {
m.muted = true;
m.setAttribute('muted', '');
}
document.querySelectorAll('video, audio').forEach(mute);
new MutationObserver(function (records) {
records.forEach(function (rec) {
rec.addedNodes.forEach(function (n) {
if (n.nodeType !== 1) { return; }
if (n.tagName === 'VIDEO' || n.tagName === 'AUDIO') { mute(n); }
else if (n.querySelectorAll) {
n.querySelectorAll('video, audio').forEach(mute);
}
});
});
}).observe(document.documentElement, { childList: true, subtree: true });
})();
需要留意的事
- 如果你信任的某个网站总是自动播放你想看的内容,就在弹窗里为那里禁用规则。
- 个人网站上的背景音乐播放器也会被捕获;用更窄的 URL 模式把它们加入白名单。
- 捕获标志(
true)是必不可少的,因为play事件不冒泡。
在我们的现成示例里取一个现成版本,或者下载 JustZix。一旦页面安静下来,你可能想要真正的控件回来——参见为每个视频强制原生控件。
为这篇文章评分
暂无评分 — 成为第一个。