【问题标题】:Simple userscript causing other page elements to stop working [duplicate]简单的用户脚本导致其他页面元素停止工作[重复]
【发布时间】:2020-08-26 10:19:48
【问题描述】:

所以我一直在尝试学习一些 javascript,并且一直在研究一个非常(非常)基本的用户脚本,它只是更改站点(不是我控制其源代码的站点)上链接的文本颜色。问题是,当脚本运行时,它改变了链接文本的颜色,链接仍然有效,但附近的一些功能元素完全停止工作(搜索栏预览、搜索按钮、配置文件下拉列表)。 我的脚本体无非是:

document.body.innerHTML= document.body.innerHTML.replace(/Advanced\n\s{1,}Search/,"\<span style\=\"color\: \#2898FF\"\> Advanced Search \<\/span\>");

我还尝试将脚本作为书签运行,以防用户脚本的运行方式/与之关联的元数据有任何问题,但不,同样的情况。 真的很感激一些帮助^^

【问题讨论】:

    标签: javascript html css bookmarklet tampermonkey


    【解决方案1】:

    当您这样做时,页面上的所有元素都会重新创建,因此页面上大多数 JavaScript 事件侦听器的更改将不再起作用:

    document.getElementById('click').onclick = () => {
      console.log('Click!');
    };
    
    document.getElementById('replace').onclick = () => {
      console.log('Replace!');
      
      document.body.innerHTML= document.body.innerHTML.replace(
        /Advanced\n\s{1,}Search/,
        '\<span style\=\"color\: \#2898FF\"\> Advanced Search \<\/span\>'
      );
    };
    .as-console-wrapper {
      max-height: 45px !important;
    }
    <h1>
      Advanced
      Search
    </h1>
    
    <button id="click">Click me!</button>
    <button id="replace">Replace HTML</button>

    相反,找到您要更新的确切元素并更改它们的一些属性:

    const h1 = document.querySelector('h1');
    
    document.getElementById('click').onclick = () => {
      console.log('Click!');
    };
    
    document.getElementById('replace').onclick = () => {
      console.log('Replace!');
      
      h1.textContent = 'Advanced Search';
      h1.style.color = ['red', 'yellow', 'green', 'cyan', 'blue', 'magenta'][Math.round(Math.random() * 5)];
    };
    .as-console-wrapper {
      max-height: 45px !important;
    }
    <h1>
      Advanced
      Search
    </h1>
    
    <button id="click">Click me!</button>
    <button id="replace">Replace HTML</button>

    【讨论】:

    • 啊,谢谢。这就说得通了。有没有办法在脚本运行的同时阻止它?例如“重新加载”其他脚本,或者在其他所有脚本都加载时加载这个? (目前,一旦页面“空闲”,它就会运行)我也很欣赏代码,但我只是为了我自己对网站美学的满意而尝试改变它^^,所以一个按钮可能会有点破坏目的。
    • 我知道,该按钮只是为了演示替换 .innerHTML 后事件停止工作。我认为没有一种简单的方法可以做到这一点,你最好尝试找到你想要更改的特定元素并更新它们。无论如何,一个可能的解决方案可能是使用带有"run_at": "document_start 的Chrome 扩展来注入您的代码。也许您可以尝试这里提到的一些替代方案:stackoverflow.com/questions/19191679/…
    • 啊,给您带来的误会深表歉意。找到特定元素并更新它们是什么意思?我的意思是我可以使用检查元素来调整它,但遗憾的是这只适用于该站点的实例。另外我担心 document start 似乎根本没有运行脚本(不知道为什么),所以这就是我一直在使用 document idle 的原因。
    • 我的意思是像示例中那样使用document.getElementById()document.querySelector()document.querySelectorAll()... 或类似的东西来获取对单个元素的引用并更新其属性.但是,是的,如果您使用这样的选择器,则需要针对特定​​站点。
    • 抱歉,document_start 的 DOM 还没有准备好,所以它不适合 DOM 操作。在document_start 之后直接出现的是document_end,在这一步,DOM 应该准备好了,根据the docs,所以你可以尝试一下。
    猜你喜欢
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多