列出未附加的文档元素

List unattached document elements

我正在尝试为 Chrome 创建一个扩展,以使用全局热键控制播放。我遇到过这样的问题:某处 <audio/> 元素没有附加到 DOM。这些元素是可听的,但我无法使用 document.querySelector('audio') 获取它们(因为它仅迭代附加的 DOM 元素)。

使用 DevTools 我可以看到这些元素:

> queryObjects(HTMLAudioElement)
< undefined
  (3) [audio, audio, audio]

但是不可能在 DevTools 之外使用这个函数(它甚至没有 return 结果 - 这个函数只是将结果打印到控制台)。

我正在寻找一种方法来从我的扩展程序的 content_script(或背景)中获取独立的音频元素。

我试过:

  1. document.getElementsByTagName('audio')
  2. document.querySelectorAll('audio')
  3. document.evaluate('//audio', ...
  4. document.createNodeIterator(document.body, NodeFilter.SHOW_ALL, ...
  5. 重新定义 HTMLAudioElementdocument.createElement 的构造函数(失败:扩展有自己的 window 和链接的 document
  6. 监听 'play''pause' 事件 - 它们不会冒泡

还有其他想法吗?也许有一些特定于扩展的功能?

感谢@wOxxOm

我遵循了我的想法 #5:重新定义 HTMLAudioElement Audiodocument.createElement

的构造函数

inject.js:

var instances = [];

document.createElement = (function () {
    var _createElement = document.createElement;
    return function createElement() {
        var result = _createElement.apply(document, Array.prototype.slice.call(arguments, 0));
        if (result.tagName === 'AUDIO') {
            instances.push(result);
        }
        return result;
    };
})();

window.Audio = (function () {
    var _Audio = window.Audio;
    function Audio() {
        var result = new _Audio();
        instances.push(result);
        return result;
    };
    Audio.prototype = Object.create(_Audio);
    Audio.prototype.constructor = Audio;
    return Audio;
})();

// further code (dom-event-based communication, misc functions etc)...

content.js:

var injected = document.createElement('script');
injected.src = chrome.extension.getURL('inject.js');
(document.head || document.documentElement).appendChild(injected);

manifest.json:

{
      "manifest_version": 2
    , "content_scripts": [{
          "matches": ["<all_urls>"]
        , "js": ["content.js"]
        , "run_at": "document_start" // <-- important
        , "all_frames": true
    }]
    , "web_accessible_resources": [
        "inject.js"
    ]

    // ...
}

将所有实例存储在一个数组中是有害的,但这是我看到的唯一方法:WeakSet 是不可迭代的。