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

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

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

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

用了 Turbolinks 吗?

Rei #0 回复

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

<%= 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 #2 回复

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

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

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

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

Rei #5 回复

播放器初始化代码放在一个单独的文件 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 #5 回复

按照文档我发现加

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

没用,加下面这个

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

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

maxchen #6 回复

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

Rei #8 回复

存在 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 #9 回复

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

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

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

👍此评论尽显大神风范!

Rei #10 回复

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

maxchen #12 回复

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

Rei #10 回复

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

Rei #13 回复

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

16 楼 已删除
Peter #17 回复

😅 什么意思?

maxchen #18 回复

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

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