我刚刚开始了一个Rails 5项目,在主页上我应该有一个视频横幅,静音,循环自动播放。我正在使用Turbolinks 5而且我不知道我是否可以保留它。
当我第一次加载主页时,一切正常。但是当我转到任何其他页面时,主页视频的声音开始播放。如果我回到家里,声音会再次开始,超过先前开始的声音。
所以我有多个同时播放静音视频的声音实例。
起初很有趣,5秒后噩梦。
我已经看到了这个问题:https://github.com/turbolinks/turbolinks/issues/177,它仍然是开放的,在评论中没有实际的解决方案。
显然这不是新的,这篇文章https://www.ruby-forum.com/topic/6803782似乎在2015年谈论同样的问题。这家伙谈到禁用Turbolinks导致该页面的链接。我不能这样做,因为我的问题在主页上。
答案 0 :(得分:0)
这是由于Turbolinks缓存了主页DOM的副本。即使视频不可见,它仍然存在于缓存中,因此可以播放。 (但是,我不确定为什么不将其静音-此可能是浏览器错误:/)
我认为,默认情况下,Turbolinks可以处理此问题,但是与此同时,有两个选择:
要防止Turbolinks缓存主页的副本,可以禁用该页面的缓存。例如,您可以在布局的<head>
中添加以下内容:
<% if @turbolinks_cache_control %>
<meta name="turbolinks-cache-control" content="<%= @turbolinks_cache_control %>">
<% end %>
然后在您的主页视图中:
<% @turbolinks_cache_control = 'no-cache' %>
缺点是,当访问者重新访问主页时,您会错过性能收益。
autoplay
元素或者,您可以跟踪autoplay
元素,在缓存页面之前删除autoplay
属性,然后在呈现页面之前重新添加它。与Persisting Elements Across Page Loads类似,此解决方案要求autoplay
元素具有唯一的ID。
在应用程序JavaScript中包含以下内容:
;(function () {
var each = Array.prototype.forEach
var autoplayIds = []
document.addEventListener('turbolinks:before-cache', function () {
var autoplayElements = document.querySelectorAll('[autoplay]')
each.call(autoplayElements, function (element) {
if (!element.id) throw 'autoplay elements need an ID attribute'
autoplayIds.push(element.id)
element.removeAttribute('autoplay')
})
})
document.addEventListener('turbolinks:before-render', function (event) {
autoplayIds = autoplayIds.reduce(function (ids, id) {
var autoplay = event.data.newBody.querySelector('#' + id)
if (autoplay) autoplay.setAttribute('autoplay', true)
else ids.push(id)
return ids
}, [])
})
})()
此脚本在页被缓存之前获取所有autoplay
元素,将每个ID存储在autoplayIds
中,然后删除autoplay
属性。当页面将要呈现时,它将遍历存储的ID,并检查新主体是否包含具有匹配ID的元素。如果是这样,它将重新添加autoplay
属性,否则它将ID推送到新的autoplayIds
数组。这样可以确保autoplayIds
仅包含尚未重新呈现的ID。