admin管理员组

文章数量:1403461

I've spent far too many hours trying to figure this out and as JavaScript is not my primary language and not yet a jQuery guru I've determined I need to ask for help.

In a case where a generated page has a structure where it has a DIV for some odd reason no ID, multiple non-standard data tag attribute tags, but at least standard style CLASS assignment....however...it has been assigned MULTIPLE classes.

Now, just one of those style classes is such that it has a code event associated that I want to neuter and leave all other classes still assigned. What I've tried there (this list is far from plete I have tried many things):

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.

Here is an example of the kind of structure of the target:

<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>

In this example there is a javascript function that fires upon clicking the href link above due to the function being associated with BADCLASS style assignment. So, from lots of searching it seemed like I should be able to grab that DIV by any of the initially assigned classes (since there is unfortunately not a class ID which would make it very easy) but then reassign the list of classes back minus the BADCLASS at page load time. So, by the time the user clicks the link, the BADCLASS has been removed to look like this:

<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>

I also read that simply using unsafewindow to replace the BADCLASS javascript function could be possible, so I am open to hearing one of you gurus help with how easy (or hard) that would be. In a case where BADCLASS could be shared function code perhaps called by another element on the page still having that initial class that perhaps we desire to continue to function which is why if it is only a single element that needs to be altered, I would rather just change this one href div.

Hope the explanation makes sense and what is probably a laughable simple example above for the Javascript gurus so forgive me but your help is greatly appreciated and will save more hair pulling! :)

EDIT: This must work above all in Chrome browser!

I've spent far too many hours trying to figure this out and as JavaScript is not my primary language and not yet a jQuery guru I've determined I need to ask for help.

In a case where a generated page has a structure where it has a DIV for some odd reason no ID, multiple non-standard data tag attribute tags, but at least standard style CLASS assignment....however...it has been assigned MULTIPLE classes.

Now, just one of those style classes is such that it has a code event associated that I want to neuter and leave all other classes still assigned. What I've tried there (this list is far from plete I have tried many things):

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.

Here is an example of the kind of structure of the target:

<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>

In this example there is a javascript function that fires upon clicking the href link above due to the function being associated with BADCLASS style assignment. So, from lots of searching it seemed like I should be able to grab that DIV by any of the initially assigned classes (since there is unfortunately not a class ID which would make it very easy) but then reassign the list of classes back minus the BADCLASS at page load time. So, by the time the user clicks the link, the BADCLASS has been removed to look like this:

<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>

I also read that simply using unsafewindow to replace the BADCLASS javascript function could be possible, so I am open to hearing one of you gurus help with how easy (or hard) that would be. In a case where BADCLASS could be shared function code perhaps called by another element on the page still having that initial class that perhaps we desire to continue to function which is why if it is only a single element that needs to be altered, I would rather just change this one href div.

Hope the explanation makes sense and what is probably a laughable simple example above for the Javascript gurus so forgive me but your help is greatly appreciated and will save more hair pulling! :)

EDIT: This must work above all in Chrome browser!

Share Improve this question edited Feb 18, 2017 at 19:30 Collin Chaffin asked Feb 18, 2017 at 19:20 Collin ChaffinCollin Chaffin 9429 silver badges15 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

Remove the class from all elements

If you want to remove the class from all elements that have the class, simply select all of the elements with that class and remove the class from their class lists.

[...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>

Using jQuery:

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

const elements = $('.BADCLASS');
elements.removeClass('BADCLASS');
console.log(elements);
<script src="https://ajax.googleapis./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>

Remove the class from a subset of elements

If you only want to remove the class from a subset elements, select those elements then from the class from their class lists.

[...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>

Using 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

The default for the run-at directive is document-idle, but if for some reason that has been changed, either it needs to be document-idle, or you need to otherwise delay execution of the script until the document has loaded.

You could use the run-at directive in the userscript header like so:

// @run-at     document-idle

Or attach a load event listener to the window

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

Include jQuery

If you're using one of the jQuery solutions, you will have to include jQuery using the require userscript header directive like so:

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

Got it with the help of both of the clear, awesome correct answers below that literally came in within seconds of each other and only a few min after my post, so thanks to both @Tiny and @Damian below!

I'm upvoting both as they both listed the same correct jQuery answers, and Tiny also provided the pure JS.

I am posting the full answer below because without the other steps, with Tamper/Greasemonkey neither will produce the desired results.

First, Tamper/Greasemonkey do not load jQuery by default, so it is just easy as add @require http://ajax.googleapis./ajax/libs/jquery/1.6.2/jquery.mi‌​n.js to your current script and also put this.$ = this.jQuery = jQuery.noConflict(true); to avoid any versioning conflicts.

Also, in this case unfortunately I HAD to change my TamperMonkey header to:

// @run-at    document-idle

along with the above mentioned:

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

and begin the script with:

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

and finally the primary accepted/best answer in this case of:

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

NOTE: The above @run-at line is required, and since so many (all) of my current Tamper/Greasemonkey scripts are actually set by default to run at START, this is of importance as it means functions like this must be separated to their own scripts to run instead AFTER the page loads (idle). Once this is added, even the above pure JS answer from Tiny did in fact produce the desired result.

As the simplest one-line answer that I was hoping was possible in Javascript, as it is so many other languages in a single line of code. I've used it in the past, but was not aware of this particular removeClass method.

Your question mentions jQuery. Did you want a solution in jQuery?

If so, it's as easy as:

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

Explanation:

jQuery can be referenced as jQuery() or $(). The parameters you can pass are: 1, a Selector statement (like CSS), and 2, context (optional; default is document).

By stating $(".Goodclass01") you are stating, "Give me a jQuery object with all elements that have the class Goodclass01." Then, by using the removeClass() function, you can either pass it no parameters and it would remove all classes, or you can pass it specific classes to remove. In this case, we call .removeClass("badclass") in order to remove the undesired class.

Now, if you need to select only specific elements, such as links that have Goodclass01, you can do:

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

Or, if you want to select anything that has Goodclass01, but NOT Goodclass02, you can do:

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

jQuery is not as intimidating as it looks. Give it a shot!

Edit: I also noticed you were trying to capture a link with maybe a specific property. You can use the [property] syntax to select elements that have a specific property. Most typically, people use $("a[href^=https]") or something to that effect to select all a tags with the property href that begins with ^= the string https.

You could, in your case, use the following...

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

... to select all links that have the property data-tag-one.

Note: One thing to keep in mind is that, a jQuery object is different than a pure DOM element. If you have a collection of multiple elements and want to use a pure JavaScript function on one element in particular, you would have to reference it with either [0] or .get(0). Once you do that, you will no longer be able to use jQuery methods until you convert it back to a jQuery object.

But, since jQuery has a whole slew of methods to use to make DOM manipulation easier, you can probably acplish what you need to using those methods.

Edit: I've included a snippet below so you can see some of the jQuery selectors in action.

<script src="https://ajax.googleapis./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>

本文标签: jqueryJavascriptGreasemonkeyUserscriptjs identify element and remove one of many classesStack Overflow