如何阻止浏览器预加载<video>标签?

时间:2016-06-19 07:20:17

标签: javascript userscripts

我为Chrome编写了一个用户脚本扩展程序,以防止在页面加载时自动下载视频和音频标记

这是代码:

var videoTags = document.getElementsByTagName("Video");
var i;
for(i=0; i<videoTags.length; i++)
{
    videoTags[i].setAttribute("preload", "none");
    videoTags[i].removeAttribute("autoplay");
}

var audioTags = document.getElementsByTagName("audio");
var i;
for(i=0; i<audioTags.length; i++)
{
    audioTags[i].setAttribute("preload", "none");
    audioTags[i].removeAttribute("autoplay");
}

这是manifest.json文件:

   {
      "content_scripts": [ {
      "exclude_globs": [  ],
      "exclude_matches": [  ],
      "include_globs": [ "*" ],
      "js": [ "script.js" ],
      "matches": [ "http://*/*", "https://*/*" ],
      "run_at": "document_start"
   } ],
      "converted_from_user_script": true,
      "description": "",
      "key": "an2xaeZJluPfnpmcsHPXI4aajQPL1cBm5C2kKjaQwXA=",
      "name": "test.user.js",
      "version": "1.0"
  }

问题是我的脚本片刻后会运行,直到那时浏览器(Chrome)会下载部分视频/音频文件。

4 个答案:

答案 0 :(得分:3)

检查您的想法是否真的发生了。这应该是不可能的,因为"run_at": "document_start""run_at": "document_end"都应该在加载任何内容之前运行代码。

来自 developer.chrome.com 中的文档:

  

对于“document_start”,文件是在来自css的任何文件之后注入的,但是在构造任何其他DOM或运行任何其他脚本之前。

     

在“document_end”的情况下,文件在DOM完成后立即注入,但在加载像图像和帧之类的子资源之前。

此外,由于您的代码在document_start中运行,document.getElementsByTagName("Video")应该会失败,因为还没有构建DOM。

尝试调试代码(首先检查控制台中的错误)。另外,请在此处详细了解"run_at"属性:https://developer.chrome.com/extensions/content_scripts#run_at

答案 1 :(得分:3)

尝试存储<audio><video> src值,然后从src<audio>元素中移除<video>属性以设置preload },autoplay属性;使用DOMContentLoaded事件

  

初始HTML文档时会触发DOMContentLoaded事件   已经完全加载和解析,无需等待   样式表,图像和子帧以完成加载。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script>
    var sources = [];
    document.addEventListener("DOMContentLoaded", function(event) {
      var media = document.querySelectorAll("audio, video");
      [].forEach.call(media, function(el) {
        if (el.src) {
          sources.push(el.src);
          el.removeAttribute("src");
        }
        var src = el.querySelectorAll("source");
        if (src.length) {
          [].forEach.call(src, function(source) {
            sources.push(source.src);
            source.removeAttribute("src");
          });
        };
      });
      console.log(sources);
    });
  </script>
</head>
<body style="height:270px">
  <video src="http://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm" controls></video>
 <audio controls>
    <source src="https://upload.wikimedia.org/wikipedia/commons/6/6e/Micronesia_National_Anthem.ogg" type="video/ogg" />
  </audio>
</body>
</html>

修改,更新

  

你能用用户脚本测试吗?

利用content_scripts"run_at": "document_start" manifest.json将预期结果作为铬,铬扩展返回;也就是说,src<audio><video>元素的<source>属性应从document中删除。

的manifest.json

{
  "manifest_version": 2,
  "name": "blockmedia",
  "description": "remove src from audio, video elements",
  "version": "1.0",
  "permissions": ["<all_urls>"],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["script.js"],
      "run_at": "document_start"
    }
  ]
}

的script.js

var sources = [];
document.addEventListener("DOMContentLoaded", function(event) {
  var media = document.querySelectorAll("audio, video");
  [].forEach.call(media, function(el) {
    if (el.src) {
      sources.push(el.src);
      el.removeAttribute("src");
    }
    var src = el.querySelectorAll("source");
    if (src.length) {
      [].forEach.call(src, function(source) {
        sources.push(source.src);
        source.removeAttribute("src");
      });
    };
  });
 console.log(sources);
});

答案 2 :(得分:3)

一个似乎有效的脏解决方案是,一旦您确定它在文档启动时运行,就会使用您的用户脚本中的MutationObserver

这个TamperMonkey脚本对我有用:

// ==UserScript==
// @name         Block videos preloading
// @include      *
// @run-at document-start
// ==/UserScript==

(function() {
  'use strict';
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      var nodes = mutation.addedNodes;
      for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].nodeName == "VIDEO") {
          nodes[i].setAttribute('preload', 'none');
          nodes[i].removeAttribute('autoplay');
        }
      }
    })
  });
  observer.observe(document.documentElement, {
    childList: true,
    subtree: true
  });

})();

如果您不希望其他视频元素随后被脚本插入,您可能需要在observer.disconnect()上致电DOMContentLoaded

答案 3 :(得分:1)

您正在与Chrome解析器预加载器竞争。

即使您在文档启动时使用Mutation Observer或上面建议的其他技术注入内容脚本,您仍然无法在浏览器预加载器之前操作HTML。

阅读这篇帮助我的文章。

https://andydavies.me/blog/2013/10/22/how-the-browser-pre-loader-makes-pages-load-faster/

要实现您的目标,您需要使用Chrome webRequest API来阻止请求。

https://developer.chrome.com/extensions/webRequest

您需要根据媒体类型过滤请求,然后在标题中搜索要阻止的文件类型。