How do I override a (css) metaclass property using a GreaseMonkey script? - javascript

My goal here is to make a script which will remove spoiler styling from /r/avatar.
By playing around with the "inspect element" element feature of Firefox I've managed to find the code in one of the CSS sheets which makes spoilered titles transparent. It looks like this
html:not([lang="ns"]) .thing.over18 a.title{
opacity:0.0
}
I've been searching for a way to override this attribute from greasemonkey, but I'm not sure how. I'm new to javascript: I've been trying to make use of
document.getElementsByClassName('.thing.over18')
to try and grab the elements with the (meta?)class attached to them, but no matter how I play with the class name I cant get it to select the right elements (I have an inkling that I'm not using the right function now).
There was actually a script on userscripts.org which did something similar (unspoiler /r/pokemon), but it seems that userscripts has been down so I cant look at its source.

There is no such thing as a "metaclass" in CSS or HTML. .thing is a class selector. .over18 is another class selector. You just have two class selectors.
getElementsByClassName only accepts a single class name.
document.getElementsByClassName('thing')
document.getElementsByClassName('over18')
If you want to use a selector, then use querySelector (for a single element) or querySelectorAll (for a NodeList).
document.querySelectorAll(".thing.over18");

Related

Is there a way to apply css to part of the element?

I am looking for a way to apply new CSS to only part of the element.
For example. The original HTML looks like
<p>123456</p>
I want to make only 456 into bold.
Of course, I can do it by adding another tag into 456 like
<p>123<b>456</b></p>
But in my application, I do want not to change the original DOM structure. By adding a new tag, I changed the DOM structure.
To do that, I am thinking of adding new custom attribute to the existing tag like
<p data-wms="e-3">123456</p>
Here data-wms means that there are special part and e-3 means that from index 3 character (it is 4 here) to the end will have a special attribute (like bold in this example)
Now I have all the information about where to change inside the element.
But still, how can I do that with javascript without adding a tag, without changing dom.
Thanks
You can use the span element to do so, it's made specifically to handle inline styling while mantaining the overall structure.
An example would be:
<p>123<span class="bold-highlight">456</span></p>
Thanks to everyone's advice, I researched more, especially about nth-letter.
Though nth-letter is exactly what I want, I found that it is still just proposal, not implemented in any browser.
Thus, there is no way to applying different css letter by letter in one text element without embracing each letter with span tag at this moment (2021-March). I hope that there will be nth-letter in the near future.
I think that I have to re-design my project...
if it's a static page and you want to change a style for specific text in a specific tag like the following case
<p>11111</p>
<p>22222</p>
<p>33333</p>
<p>44444</p>
let's say you want just style the third element, you can change it by the following code using jQuery for sure you can use JavaScript but jQuery will help you to make your code shorter
$( "p:nth-child(3)" ).css("color","#f00");

Best practice in finding a DOM element

I want to toggle(hide/show) an element when a button is being pressed. I have two ways as to implement this:
Find the element according to its class name, e.g $('.my-content')
Find the element according to its relevant DOM position towards the button, e.g. $('#my-button').parent().next().next().next()
However, none of the above seems to me very reliable since in case someone changes the HTML code, the above approaches should not work. Is there something more reliable I am missing?
If it's a specific element, supply it with an Id value and use that
to find it.
If it's a TYPE of element, use a class name.
Other than that, there's no real conventions. Just try and make sure that somebody reading your code understands what is going on.
A very good practice is to decouple HTML, CSS and JS.
When binding javascript to DOM elements you should use javascript selectors.
Basically classes with some custom prefix (like js-) which will be used only for javascript purposes (not css style).
So whenever the DOM tree structure or the CSS class names are changed, you can still have your working JS selector
HTML
<div class="my-content js-toggle-element"></div>
JS
$('.js-toggle-element')
CSS
.my-content{ ... }
Plus, using Javascript Selectors:
makes HTML highly readable: you can easily find out what will happen to that element with that js class
allows you to easily apply/disapply that behaviour also to other elements in the future, simply by adding/removing that class in your HTML and without affecting CSS at all
<div class="my-content js-toggle-element"></div>
...
<div class="another-content-to-toggle js-toggle-element"></div>
Using jQuery will be much easiest way. Like this -
$( ".target" ).toggle();
The matched elements will be revealed or hidden immediately, with no animation, by changing the CSS display property. If the element is initially displayed, it will be hidden; if hidden, it will be shown.
Reference - jQuery Toggle
If the class or the position of the element in DOM is changing then you can try
selecting it with the inner text
$("button:contains('buttontextgoeshere')")

Replace part of innerHTML without reloading embedded videos

I have a div with id #test that contains lots of html, including some youtube-embeds etc.
Somewhere in this div there is this text: "[test]"
I need to replace that text with "(works!)".
The normal way of doing this would of course be:
document.getElementById("test").innerHTML = document.getElementById("test").replace("[test]","(works!)");
But the problem is that if i do that the youtube-embeds will reload, which is not acceptable.
Is there a way to do this?
You will have to target the specific elements rather than the parent block. Since the DOM is changing the videos are repainted to the DOM.
Maybe TextNode (textContent) will help you, MSDN documentation IE9, other browsers also should support it
Change your page so that
[test]
becomes
<span id="replace-me">[test]</span>
now use the following js to find and change it
document.getElementById('replace-me').text = '(works!)';
If you need to change more than one place, then use a class instead of an id and use document.getElementsByClassName and iterate over the returned elements and change them one by one.
Alternatively, you can use jQuery and do it even simpler like this:
$('#replace-me').text('(works!)');
Now for this single replacement using jQuery is probably overkill, but if you need to change multiple places (by class name), jQuery would definitely come in handy :)

Why is my Jquery Tooltip not working?

I am not getting a tooltip to work and I think the problem is with my selector.
I had selected a plugin that is located here: http://flowplayer.org/tools/tooltip/index.html
It says that you can use the title attribute of an element as the selector. I am wanting to select menu items and attach a tooltip to each one (to describe the menu links). It seemed that the easiest way to do this is to use the title attribute. I only need to fit about 10 or less words in each tooltip. Before describing what could be the problem, let me also mention a couple things.
I have on the page a JQuery accordion too, from the jqueryui.com site. That link to the jqueryui is placed after the call to the jquery tools from http://flowplayer.org/tools/tooltip/index.html. I thought this was the jquery ui at first but jqueryui doesn't have a tooltip - though they have a dialog box that is similar but I don't need the header, just room for a few words.
So, let's see where I could have went wrong.
A) The call to the jquery tools comes before the call to the jqueryui. When that was reversed, my accordion didn't work.
B) The plugin documentation says that there is a class .tooltip which is available by default and the code also let me set the class for the tooltip to tooltip. It is definitely not getting any of the styling that I setup for the tooltip. I'm not sure how to confirm that this tooltip class exists because it only shows up when the tooltip appears.
C) My selector. At first I tried a CSS Descendant selector, just like I would in CSS. I even added a containing div with id of tooltip.
1)First selector: $('#tooltip a[title]), to get the a tags that have a title attribute. That was described in the documentation, though to me it seems like you would want to "trigger" on the anchor tag, not it's title attribute
2) Second attempt with descendant selectors $(".art-hmenu a.tt[title]") - I have inside the tag that has a class of art-hmenu an anchor tag with class tt and I want the title attribute. - didn't work.
3) lastly, I tried using ("#tooltip").find('a[title]') - thinking this would find the anchor tag with title attribute.
The documentation page says that this code will take advantage of the element's title attribute:
$("img[title]").tooltip();
That might put a tooltip on every img tag, wouldn't it? My first example above is similar in using ("#tooltip a:[title]") which doesn't work.
Maybe the title shouldn't be on the anchor tag but instead on the li tag.
I could use some help figuring this out - wherever the problem might lay, which I think is how I am making my selection.
Thanks,
Bruce
your looking for an attribute so use the $('#tooltip a').attr("title") instead.
It sounds like you are over-complicating this.
Give the link, phrase, input, button the class of "trigger" and a title. Tools will handle everything else. You can style the tooltip with a .tooltip class. You position the tooltip with the offset and position settings. If you want to get crazy with styling you can layout: or open the plugin source code and wrap html around the Append(title).

Change name of a html class

I use a website, which shows information i have no use for, so i tried to hide some of it with Stylish, an addon for Chrome to insert custom CSS.
I will try to explain better.
<div class="splitscreenleft"> <div id="toplevel"
<div class="splitscreenleft"> <div id="coursesection"
I want to hide one of those. Everything above splitscreenleft is the same on both. So the only difference is the div id below.
I must somehow hide one of the two classes based on the name of the div below it i think.
Any solutions to this problem?
You should be able to do this either via CSS or JavaScript.
You probably don't even need to search the children out. You can probably just pick the first or second one that appears on the page and style that. To do via CSS, use the first-of-type selector - http://www.w3.org/TR/css3-selectors/#first-of-type-pseudo
div.splitscreenleft:first-of-type { display: none; }
To do this via JavaScript, you can find the parent object and then hide it:
document.getElementById("toplevel").parentNode.style.display = 'none';
You should be able to do it similarly in jQuery:
$(".splitscreenleft:has(#toplevel)").hide();​
This can be accomplish by CSS, using structural pseudo-classes alone:
.parentClassName .className :nth-child(n) { display: none; }
Where n is the element you want to select. In your case you have two elements with the same class. To hide the first one, just replace n with 1, or 2 to hide the second one. You get the idea.
If you can't get access to jQuery with JS (haven't tried in chrome), you could always say
$('#topLevel').parent().hide();
the code below can change the class you defined in style sheet.
document.getElementById("testPara").className = "yourclass";

Categories

Resources