Javascript / Greasemonkey / Userscript.js 识别元素并删除许多 类 中的一个

Javascript / Greasemonkey / Userscript.js identify element and remove one of many classes

我花了太多时间试图解决这个问题,因为 JavaScript 不是我的主要语言,也不是 jQuery 大师,我确定我需要寻求帮助.

如果生成的页面具有 DIV 由于某种奇怪的原因没有 ID、多个非标准数据标签属性标签的结构,但至少是标准样式 CLASS赋值……但是……它被分配了多个 classes.

现在,只有一种样式 classes 具有关联的代码事件,我想中性化并保留所有其他 classes 仍然分配。我在那里尝试过的(这个列表远未完成我已经尝试了很多东西):

document.getElementsByClassName('Goodclass01')[0].remove('BADCLASS');
document.querySelectorAll('[data-tag-one="["value", 
"value"]"]').remove('BADCLASS');

Various jnode calls that all fail due to claims of being unknown
A couple variations of something referred to as the "location hack" none of 
which I could get to work but may have very well have been user error.

Safewindow attempt to just replace BADCLASS javascript function all together 
but not ideal explained below.

这里有一个目标结构的例子:

<div id="main">
  <div class="main_content" data-tag-id="12345">Some stuff sits above</div>
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS" 
  data-tag-one="["value", "value"]">
</div>

在此示例中,有一个 javascript 函数会在单击上面的 href link 时触发,因为该函数与 BADCLASS 样式分配相关联。因此,通过大量搜索,我似乎应该能够通过任何最初分配的 classes 获取 DIV (因为不幸的是没有 class ID 可以使它成为非常简单),然后在页面加载时重新分配 classes 列表减去 BADCLASS。因此,当用户单击 link 时,BADCLASS 已被删除,如下所示:

<div id="main">
  <div class="main_content" data-tag-id="12345">Some stuff sits above</div>
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03" 
  data-tag-one="["value", "value"]">
</div>

我还读到,简单地使用 unsafewindow 来替换 BADCLASS javascript 函数是可能的,所以我很乐意听到你们中的一位专家帮助说明这有多容易(或困难)将会。在 BADCLASS 可能被共享函数代码的情况下,页面上的另一个元素仍然具有初始 class ,也许我们希望继续运行,这就是为什么如果它只是一个元素需要更改,我宁愿只更改这个 href div.

希望解释是有道理的,对于 Javascript 专家来说,上面可能是一个可笑的简单示例所以请原谅我,但非常感谢您的帮助,这将节省更多的麻烦! :)

编辑:这必须首先在 Chrome 浏览器中工作!

从所有元素中删除 class

如果要从所有具有 class 的元素中删除 class,只需 select 所有具有 class 的元素并删除 class 来自他们的 class 列表。

[...document.querySelectorAll('.BADCLASS')]
    .forEach(e => e.classList.remove('BADCLASS'));

const elements = [...document.querySelectorAll('.BADCLASS')];
elements.forEach(e => e.classList.remove('BADCLASS'));
console.log(elements);
<div id="main">
  <div class="main_content" data-tag-id="12345">Some stuff sits above</div>
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS" 
  data-tag-one='["value", "value"]'>link</a>
</div>

使用jQuery:

$('.BADCLASS').removeClass('BADCLASS');

const elements = $('.BADCLASS');
elements.removeClass('BADCLASS');
console.log(elements);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
  <div class="main_content" data-tag-id="12345">Some stuff sits above</div>
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS" 
  data-tag-one='["value", "value"]'>link</a>
</div>

从元素子集中删除 class

如果您只想从子集元素中删除 class,则 select 这些元素会从 class 列表中的 class 中删除。

[...document.querySelectorAll('.Goodclass01, .Goodclass02, .Goodclass03')]
    .forEach(e => e.classList.remove('BADCLASS'));

const elements = [...document.querySelectorAll('.Goodclass01, .Goodclass02, .Goodclass03')];
elements.forEach(e => e.classList.remove('BADCLASS'));
console.log(elements);
<div id="main">
  <div class="main_content" data-tag-id="12345">Some stuff sits above</div>
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS" 
  data-tag-one='["value", "value"]'>link</a>
  <a href="SOME LINK" class="BADCLASS">link</a>
</div>

使用jQuery:

$('.Goodclass01, .Goodclass02, .Goodclass03').removeClass('BADCLASS');

const elements = $('.Goodclass01, .Goodclass02, .Goodclass03');
elements.removeClass('BADCLASS');
console.log(elements);
<div id="main">
  <div class="main_content" data-tag-id="12345">Some stuff sits above</div>
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS" 
  data-tag-one='["value", "value"]'>link</a>
  <a href="SOME LINK" class="BADCLASS">link</a>
</div>

运行 文档空闲

run-at 指令的默认值为 document-idle,但如果由于某种原因已更改,则需要 document-idle,否则您需要延迟执行脚本,直到文档加载完毕。

您可以在用户脚本 header 中使用 run-at 指令,如下所示:

// @run-at     document-idle

或者将加载事件侦听器附加到 window

window.addEventListener('load', function() { /* do stuff */ }, false);

包括jQuery

如果您使用的是 jQuery 解决方案之一,则必须使用 require 用户脚本 header 指令包含 jQuery,如下所示:

// @require    https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js

您的问题提到 jQuery。您想要 jQuery 中的解决方案吗?

如果是这样,就这么简单:

$(".Goodclass01").removeClass("badclass");

解释:

jQuery 可以引用为 jQuery()$()。您可以传递的参数是:1,Selector 语句(如 CSS),以及 2,上下文(可选;默认为文档)。

通过声明 $(".Goodclass01") 你是在声明 "Give me a jQuery object with all elements that have the class Goodclass01." 然后,通过使用 removeClass() 函数,你可以不给它传递任何参数,它会删除所有 class es,或者您可以传递特定的 classes 来删除。在这种情况下,我们调用 .removeClass("badclass") 以删除不需要的 class.

现在,如果您只需要 select 特定元素,例如具有 Goodclass01 的 link,您可以这样做:

$("a.GoodClass01").removeClass("badclass");

或者,如果您想 select 任何具有良好class01,但不是良好class02 的东西,您可以这样做:

$(".Goodclass01:not(.Goodclass02)").removeClass("badclass");

jQuery 并不像看起来那么吓人。试一试!

编辑: 我还注意到您试图用特定的 属性 捕获 link。您可以对具有特定 属性 的 select 元素使用 [property] 语法。最典型的是,人们使用 $("a[href^=https]") 或类似的东西来 select 所有 a 带有以 ^= 字符串开头的 属性 href 的标签https.

根据您的情况,您可以使用以下...

$("a[data-tag-one]")

... 至 select 所有具有 属性 data-tag-one.

的 link

注意: 需要记住的一件事是,jQuery 对象不同于纯 DOM 元素。如果您有多个元素的集合,并且特别想对一个元素使用纯 JavaScript 函数,则必须使用 [0].get(0) 来引用它。一旦你这样做,你将无法再使用 jQuery 方法,直到你将它转换回 jQuery 对象。

但是,由于 jQuery 有大量方法可用于使 DOM 操作更容易,您可能可以使用这些方法完成所需的工作。

编辑: 我在下面包含了一个片段,这样您就可以看到一些 jQuery select 的人在行动。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
div#main * { background-color: #66ff66; }
div#main .BADCLASS, div#main .BADCLASS * { background-color: #ff8888 !important; }
</style>

<div id="main">
  <div class="main_content" data-tag-id="12345">Some stuff sits above</div>
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS" 
  data-tag-one='["value", "value"]'>All classes and data-tag-one</a><br />
  <a href="SOME LINK" class="Goodclass01 BADCLASS" data-tag-one='["value", "value"]'>Goodclass01 and data-tag-one</a><br />
  <a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS">All classes, no data-tag-one</a><br />
  <a href="SOME LINK" class="BADCLASS" data-tag-one='["value", "value"]'>Just BADCLASS and data-tag-one</a><br />
  <br />
  <table class="Goodclass01 BADCLASS"><tr><td>Here is a table</td></tr><tr><td>with Goodclass01 and BADCLASS</td></tr></table>
</div>
<hr>
<div id="buttons">
<a href="#" id="button1">$(".Goodclass01").removeClass("BADCLASS");</a><br />
<a href="#" id="button2">$("a.Goodclass01").removeClass("BADCLASS");</a><br />
<a href="#" id="button3">$(".Goodclass01:not(.Goodclass02)").removeClass("BADCLASS");</a><br />
<a href="#" id="button4">$("a[data-tag-one]").removeClass("BADCLASS");</a><br />
<a href="#" id="button5">Reset the HTML</a><br />
</div>

<script>
$("#button1").click(function(){
  $(".Goodclass01").removeClass("BADCLASS");
});
$("#button2").click(function(){
  $("a.Goodclass01").removeClass("BADCLASS");
});
$("#button3").click(function(){
  $(".Goodclass01:not(.Goodclass02)").removeClass("BADCLASS");
});
$("#button4").click(function(){
  $("a[data-tag-one]").removeClass("BADCLASS");
});
$("#button5").click(function(){
  var str = '<div class="main_content" data-tag-id="12345">Some stuff sits above</div><a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS" data-tag-one=\'["value", "value"]\'>All classes and data-tag-one</a><br /><a href="SOME LINK" class="Goodclass01 BADCLASS" data-tag-one=\'["value", "value"]\'>Goodclass01 and data-tag-one</a><br /><a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS">All classes, no data-tag-one</a><br /><a href="SOME LINK" class="BADCLASS" data-tag-one=\'["value", "value"]\'>Just BADCLASS and data-tag-one</a><br /><br /><table class="Goodclass01 BADCLASS"><tr><td>Here is a table</td></tr><tr><td>with Goodclass01 and BADCLASS</td></tr></table>';
  $("div#main").html(str);
});
</script>

在下面两个清晰、令人敬畏的正确答案的帮助下得到了答案,这些答案实际上是在几秒钟内出现的,而且在我 post 之后仅几分钟,所以感谢@Tiny 和@下面是达米安!

我对两者都投了赞成票,因为它们都列出了相同的正确 jQuery 答案,而且 Tiny 还提供了纯 JS。

我正在 post 给出下面的完整答案,因为如果没有其他步骤,Tamper/Greasemonkey 两者都不会产生预期的结果。

首先,Tamper/Greasemonkey默认不加载jQuery,所以很简单,只需将@require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.mi‌ n.js添加到您当前的脚本中,并且放这个。$ = this.jQuery = jQuery.noConflict(true);以避免任何版本冲突。

此外,不幸的是,在这种情况下,我不得不将我的 TamperMonkey header 更改为:

// @run-at    document-idle

连同上面提到的:

// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js

并以以下内容开始脚本:

this.$ = this.jQuery = jQuery.noConflict(true);

最后是主要的 accepted/best 答案,在这种情况下:

$('.Goodclass01').removeClass('BADCLASS');

注意:上面的 @run-at 行是必需的,因为我当前的许多(全部)Tamper/Greasemonkey 脚本实际上是默认设置的在开始时到 运行,这很重要,因为这意味着必须将像这样的函数分离到它们自己的脚本中,而不是在页面加载(空闲)后 运行。添加后,即使上面来自 Tiny 的纯 JS 答案实际上也产生了预期的结果。

作为最简单的 one-line 答案,我希望可以在 Javascript 中实现,因为它是一行代码中的许多其他语言。我过去用过它,但不知道这个特定的 removeClass 方法。