如何修复在Violentmonkey或Tampermonkey Chrome扩展中无法工作的'addEventListener'问题?

4
我想要在输入文本框中输入5个字符后的0.1秒内自动点击一个按钮....这段代码在浏览器控制台(开发人员工具-F12)中可以正常工作。但我希望通过Greasemonkey/Tampermonkey扩展程序,让这段代码在浏览器中永久执行。
var textbox = document.getElementById("Text");

var button = document.getElementsByClassName("btn")[0];

textbox.addEventListener("input", function() {
  var inputText = textbox.value.trim();
  if (inputText.length === 5) {
    setTimeout(function() {
      button.click();
    }, 100);
  }
});

但是这在Greasemonkey/Tampermonkey Chrome扩展中不起作用....

请看这张图片:

enter image description here

我该如何在Greasemonkey/Tampermonkey Chrome扩展中运行这段代码?


更新:

回应 Alexander Nenashev

让我解释一下我想要使用这段代码的原因。 例如,我希望在输入5位数密码后,在登录部分的每个网页上自动点击登录按钮。 而且这些元素都存在于该网站上。 我通过浏览器开发者工具的控制台(F12)导入这段代码,它可以正常工作,但是一旦页面刷新,我就必须重新导入这段代码,这正是我的问题所在。我希望这段JavaScript代码能够永久地存在于每个网站的后台。我希望它保持活动状态,并根据我的研究,Tampermonkey扩展似乎可以实现这一点,但对我来说不起作用!

enter image description here

我把你的代码放到Tampermonkey扩展程序中,但不幸的是,我得到了与之前相同的错误... 而且我们在目标网站上可以获得这些元素

1个回答

1

您的错误解释:

document.getElementById("Text"); 返回 null,因为在运行猴子脚本时页面上还没有这样的文本框。
当您在控制台中运行代码时,元素是存在的,所以您没有问题。

我相信猴子脚本在 DOMContentLoaded 之后运行。但是...
页面可能会在此之后创建元素(例如从后端加载一些 HTML 片段并插入到页面中)。所以...
您应该观察需要的元素。简单的方法是使用 setTimeout()稍后运行您的代码,希望元素已经出现。并且可能重复这个过程,在找到元素时停止。

但有一种更加优雅的方法。在我的猴子脚本中,我使用 MutationObserver

// emulate code on the page

document.querySelector('button').addEventListener('click', e => {

  e.target.remove();

  document.querySelector('.container').innerHTML = `
    <input id="Text">
    <button class="btn">Auto click me</button>
    <div class="log"></div>
  `;

  const textbox = document.querySelector('#Text');
  textbox.focus();

  document.querySelector('.btn').addEventListener('click', () => {
    document.querySelector('.log').innerHTML += `<div>${textbox.value.trim()}</div>`;
    textbox.value = '';
  });
  
});

// your code, watch for body mutations and add listeners;

let observer = new MutationObserver(addListener);

/*
  if you have more specific container where to look and 
  it's present on DOMContentLoaded - use here.
*/
observer.observe(document.body, {childList: true, subtree: true});

function addListener(){

  const textbox = document.querySelector('#Text');
  const button = document.querySelector('.btn');

  if(!textbox || !button){
    return; // not on the page yet
  }

  textbox.addEventListener('input', () => {
    textbox.value.trim().length === 5 && setTimeout(() => button.click(), 100);
  });
  
  // stop observing since you've attached the listener
  
  observer.disconnect();
  observer = null;

  // stackoverflow's console.log() mutates DOM so use it after disconnecting
  console.log('the listener has been added');

};
<button>Add elements</button>
<div class="container"></div>

更新

如果事件冒泡,您可以在document上捕获它:

// emulate code on the page

document.querySelector('button').addEventListener('click', e => {

  e.target.remove();

  document.querySelector('.container').innerHTML = `
    <input id="Text">
    <button class="btn">Auto click me</button>
    <div class="log"></div>
  `;

  const textbox = document.querySelector('#Text');
  textbox.focus();

  document.querySelector('.btn').addEventListener('click', () => {
    document.querySelector('.log').innerHTML += `<div>${textbox.value.trim()}</div>`;
    textbox.value = '';
  });
  
});

// your code, watch for inputs to change

document.addEventListener('input', e => {

  const button = document.querySelector('.btn');

  e.target.value.trim().length === 5 && setTimeout(() => button.click(), 100);

});
<button>Add elements</button>
<div class="container"></div>


我把你的代码放到Tampermonkey插件中,但不幸的是我得到了与之前相同的错误... 而且我们可以在目标网站上使用这些元素。 - Mjniyazi
@Mjniyazi,请给我一个你喜欢的网站链接,让我可以在上面测试这段代码。还有,你想要哪种文本输入方式? - Alexander Nenashev
@Mjniyazi,你可以尝试在文档中处理事件,我已经更新了答案。 - Alexander Nenashev
@Mjniyazi,你可以通过silentmantra.ru@gmail.com与我联系。另外,请检查一下我在答案中添加的一些更简单的解决方案。 - Alexander Nenashev
我使用了新的解决方案,但是之前的相同错误重复出现了。 请检查您的电子邮件。 谢谢。 - Mjniyazi
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接