首页 > 解决方案 > 列出未附加的文档元素

问题描述

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

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

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

但是在 DevTools 之外使用这个函数是不可能的(它甚至不返回结果——这个函数只是将结果打印到控制台)。

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

我试过了:

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

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

标签: javascriptdomgoogle-chrome-extensiongetelementsbytagname

解决方案


感谢@wOxxOm

我遵循了我的想法#5:重新定义and的构造函数HTMLAudioElement Audiodocument.createElement

注入.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)...

内容.js:

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

清单.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不可迭代。


推荐阅读