其他 浏览器 F5 刷新和点链接刷新有什么区别呢?

maxchen · 2018年03月25日 · 最后由 Peter 回复于 2018年03月29日 · 8342 次阅读

在调试 video.js 的过程中,注意到一个问题,比如说我首页里有个视频,用 videojs 播放,打开首页时正常显示,F5 刷新后也能正常显示,但是如果在首页时再点击一次首页,突然发现 videojs 播放器不能显示了,视频也没能显示,按 F5 刷新后又变好了。我打开浏览器的调试窗口,也注意另外一个问题,比如说我首页里有两张照片没加载出来,会显示两个错误,点击首页链接重刷新,发现错误是递增的,例如变成 4 个、6 个、、、,但是一按 F5 刷新,错误数又变成了两个,请问这是为什么呢?如下图所示:

------------------------------点击首页链接重刷新后如下------------------------------------:

用了 Turbolinks 吗?

Rei 回复

嗯,用了,保持下面这个不变

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

把文档看完 https://github.com/turbolinks/turbolinks

或者删除 Turbolinks。

Rei 回复

想保持使用 Turborlinks,看了文档,又找了几篇文章研究下,其中一篇是@lyfi2003的文章https://yafeilee.me/blogs/88 按照我自己的理解,目前有一个解决方案就是把 video.js 的源代码加载到 body 底部而不是 head 中,但是视频播放器显示出来有个先出来原生播放器再变成 video.js 播放器的问题,不是我想要的一出来就是以 video.js 的播放器显示出视频的效果,目前我只理解到这一步,请问您有比较好的解决思路吗?

maxchen 展示一下自己的第一个 Rails 作品 - clwy.cn 提及了此话题。 03月27日 00:46
maxchen 回复

关键是要理解 Turbolinks 环境下整个页面是个持久进程,DOMContentLoaded 事件不会触发(影响到需要什么时候创建对象和绑定),已创建的对象和事件绑定不会被清除(除非失去引用被 GC)。

把你的播放器初始化代码和位置贴出来看看?

Rei 回复

播放器初始化代码放在一个单独的文件 videojs-init.js 中,代码如下:

// video-js 相关
window.HELP_IMPROVE_VIDEOJS = false;
$(document).on("turbolinks:load", function() {
  videojs_init();
});
function videojs_init() {
  var options = {
    playbackRates:[0.5, 1, 1.5],
    techOrder: ["html5", "flash", "other supported tech"]
  };
  var videos = document.getElementsByTagName('video');
  for(i=0; i<videos.length; i++) {
    var video = videos[i];
    video.volume = 0.5;
    if(video.className.indexOf('video-js') > -1 && video.id.length > 0) {
      var player = videojs(video.id, options, function onPlayerReady() {
        videojs.log('Your player is ready!');
        // In this context, `this` is the player that was created by Video.js.
        // this.play();
        // How about an event listener?
        this.on('ended', function() {
          videojs.log('Awww...over so soon?!');
         });
        }
      );
    }
  }
}

然后在 application.html.erb 头部如下:

<head>
  <title><%= full_title(yield(:title)) %></title>
  <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
  <%= favicon_link_tag image_path("website/favicon.ico") %>
  <%= csrf_meta_tags %>

  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  <!-- bootcss font-awesome.css-->
  <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
  <%= render 'layouts/shim' %>
</head>

您问的是这些吗?😅

Rei 回复

按照文档我发现加

<meta name="turbolinks-cache-control" content="no-cache">

没用,加下面这个

<meta name="turbolinks-visit-control" content="reload">

虽然有用,但是加了之后和没用 Turbolinks 也一样了😅 ,我也没确定具体只有哪些页面才需要视频,有可能哪里都有可能要用到视频,所以在全局模板中试了这个。

maxchen 回复

代码开源吗?我得看其它代码的行为。

Rei 回复

存在 gitlab.com 上了,没存成开源的。我今天看到了这个帖子https://ruby-china.org/topics/35298 ,发现他也用到了 Turbolinks 和 video.js,就问了他怎么解决,他刚刚告诉了我他的解决方案,效果还不错,原理弄不懂,关键是这个 video.dispose(),查了 video.js 的文档,上面写到

Turn off all event polyfills, clear the Techs AudioTrackList, VideoTrackList, and TextTrackList, and dispose of this Tech.

结合 Turbolinks 的原理,是把什么清理掉、、、有点一知半解、、、

maxchen 回复

看了下 video.js 的代码,它在页面加载完就自动执行了初始化,然后创建了全局对象 Player 保存每个播放器的引用。这意味着会和 Turbolinks 的事件冲突,并且每次换页都要清理 Player 引用。

所以解决方法大概就是这楼那样 https://ruby-china.org/topics/35298#reply-340107 ,换页前清理 Player,换页后遍历创建 Player。

这个库自作主张初始化,是我会换一个。

👍此评论尽显大神风范!

Rei 回复

😂换做你会换成哪个库?我这不之前也是网上浏览了好多,最后才确定用 video.js,被您这么一说还真得再研究研究有没有好的替代品…阿里云的视频点播那里貌似有个前端的播放器,是否值得研究下呢…

maxchen 回复

搜了下感觉这个不错,但我没用过 https://plyr.io/

Rei 回复

这个问题算是暂时解决了,太感谢您这么耐心仔细地为我解答,感谢咱们 ruby 社区!感谢 ruby 社区的朋友们!😊

Rei 回复

嗯嗯 我研究研究下这个😊 谢谢@Rei

17 楼 已删除
Peter 回复

😅 什么意思?

maxchen 回复

因为回复很有帮助,建议加精

需要 登录 后方可回复, 如果你还没有账号请 注册新账号