列出未附加的文档元素

时间:2018-07-19 18:53:29

标签: javascript dom google-chrome-extension getelementsbytagname

我正在尝试为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. 重新定义HTMLAudioElementdocument.createElement的构造函数(失败:扩展名具有自己的window并链接了document
  6. 收听'play''pause'事件-它们不会冒泡

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

1 个答案:

答案 0 :(得分:0)

感谢@wOxxOm

我遵循了我的想法#5:重新定义 import { typeDefs, resolvers } from "./graphql-schema"; import { ApolloServer, gql, makeExecutableSchema } from "apollo-server"; import { v1 as neo4j } from "neo4j-driver"; import { augmentSchema } from "neo4j-graphql-js"; import dotenv from "dotenv"; dotenv.config(); const schema = makeExecutableSchema({ typeDefs, resolvers }); // augmentSchema will add autogenerated mutations based on types in schema const augmentedSchema = augmentSchema(schema); const driver = neo4j.driver( process.env.NEO4J_URI || "bolt://localhost:7687", neo4j.auth.basic( process.env.NEO4J_USER || "neo4j", process.env.NEO4J_PASSWORD || "neo4j" ) ); if (driver){ console.log("Database Connected") } else{ console.log("Database Connection Error") } const server = new ApolloServer({ // using augmentedSchema (executable GraphQLSchemaObject) instead of typeDefs and resolvers //typeDefs, //resolvers, context: { driver }, // remove schema and uncomment typeDefs and resolvers above to use original (unaugmented) schema schema: augmentedSchema }); server.listen(process.env.GRAPHQL_LISTEN_PORT, '0.0.0.0').then(({ url }) => { console.log(`GraphQL API ready at ${url}`); }); HTMLAudioElementAudio

的构造函数

inject.js:

document.createElement

content.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)...

manifest.json:

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

将所有实例存储在一个数组中是有害的,但这是我看到的唯一方法:{ "manifest_version": 2 , "content_scripts": [{ "matches": ["<all_urls>"] , "js": ["content.js"] , "run_at": "document_start" // <-- important , "all_frames": true }] , "web_accessible_resources": [ "inject.js" ] // ... } 是不可迭代的。