How to dynamically remove a stylesheet from the current page - javascript

Is there a way to dynamically remove the current stylesheet from the page?
For example, if a page contains:
<link rel="stylesheet" type="text/css" href="http://..." />
...is there a way to later disable it with JavaScript? Extra points for using jQuery.

Well, assuming you can target it with jQuery it should be just as simple as calling remove() on the element:
$('link[rel=stylesheet]').remove();
That will remove all external stylesheets on the page. If you know part of the url then you can remove just the one you're looking for:
$('link[rel=stylesheet][href~="foo.com"]').remove();
And in Javascript
this is an example of remove all with query selector and foreach array
Array.prototype.forEach.call(document.querySelectorAll('link[rel=stylesheet]'), function(element){
try{
element.parentNode.removeChild(element);
}catch(err){}
});
//or this is similar
var elements = document.querySelectorAll('link[rel=stylesheet]');
for(var i=0;i<elements.length;i++){
elements[i].parentNode.removeChild(elements[i]);
}

If you know the ID of the stylesheet, use the following. Any other method of getting the stylesheet works as well, of course. This is straight DOM and doesn't require using any libraries.
var sheet = document.getElementById(styleSheetId);
sheet.disabled = true;
sheet.parentNode.removeChild(sheet);

I found this page whilst looking for a way to remove style sheets using jquery. I thought I'd found the right answer when I read the following
If you know part of the url then you can remove just the one you're looking for:
$('link[rel=stylesheet][href~="foo.com"]').remove();"
I liked this solution because the style sheets I wanted to remove had the same name but were in different folders. However this code did not work so I changed the operator to *= and it works perfectly:
$('link[rel=stylesheet][href*="mystyle"]').remove();
Just thought I'd share this in case it's useful for someone.

This will disable any stylesheet matching the regular expression searchRegEx provided against the URL of each stylesheet.
let searchRegEx = /example.*/;
for (var i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].href.search(searchRegEx) != -1) {
document.styleSheets[i].disabled = true;
}
}

Nobody has mentioned removing a specific stylesheet without an ID in plain Javascript:
document.querySelector('link[href$="something.css"]').remove()
("$=" to find at end of href)

This will reset your page's styling, removing all of the style-elements. Also, jQuery isn't required.
Array.prototype.forEach.call(document.querySelectorAll('style,[rel="stylesheet"],[type="text/css"]'), function(element){
try{
element.parentNode.removeChild(element)
}catch(err){}
});

This is for disable all <style> from html
// this disable all style of the website...
var cant = document.styleSheets.length
for(var i=0;i<cant;i++){
document.styleSheets[i].disabled=true;
}
//this is the same disable all stylesheets
Array.prototype.forEach.call(document.styleSheets, function(element){
try{
element.disabled = true;
}catch(err){}
});

To expand on Damien's answer, the test method (which returns true or false) would probably be a better fit than search and is slightly faster. Using this method would yield:
for (var i = 0; i < document.styleSheets.length; i++) {
if (/searchRegex/.test(document.styleSheets[i].href)) {
document.styleSheets[i].disabled = true;
}
}
If you don't care about IE support this can be cleaned up with a for...of loop
for (const styleSheet of document.styleSheets) {
if (/searchRegex/.test(styleSheet)) {
styleSheet.disabled = true;
}
}

Suppose you want to remove a class myCssClass then the most easy way to do it is element.classList.remove("myCssClass");

Related

Get all elements with `position:fixed` in an HTML page?

Reason for doing that: I'm debugging css of my webpage.. some elements appeared and they're not supposed to appear. I suspect it is the issue with element positioning.. therefore I want to find these positioned element and check one by one.
This one is using jQuery. I hope you are find with it.
var find = $('*').filter(function () {
return $(this).css('position') == 'fixed';
});
I think this one works using a pure javascript:
var elems = document.body.getElementsByTagName("*");
var len = elems.length
for (var i=0;i<len;i++) {
if (window.getComputedStyle(elems[i],null).getPropertyValue('position') == 'fixed') {
console.log(elems[i])
}
}
Here is an ES6 version that gives you an array of these elements for further processing:
let fixedElements = [...document.body.getElementsByTagName("*")].filter(
x => getComputedStyle(x, null).getPropertyValue("position") === "fixed"
);
document.querySelector('*[style="position:fixed"]')
The * item specifies all tag names. The [] indicate that you're looking for an attribute. You want your style attribute to have position:fixed.
If you aren't using jQuery, this is probably going to be your simplest option.
Warnings that apply to all answers:
This is a slow operation. On a large-enough page, this operation can take 100ms or more, which is a lot for a single operation. You shouldn't need this unless you're developing a browser extension.
Now sticky elements can act as fixed elements in some cases
Having said that, here's the shortest and most efficient version to do this:
const fixed = [].filter.call(document.all, e => getComputedStyle(e).position == 'fixed');
Here's a version that includes sticky elements, but they're not exactly equivalent, it depends on what you're looking for:
const all = [].filter.call(
document.all,
e => ['fixed', 'sticky'].includes(getComputedStyle(e).position)
);
If you're feeling modern, replace document.all with document.querySelectorAll('*'), but the former will likely work forever.
Try this:
var elements = $('*').filter(function () {
return this.style.position == 'fixed';
});
It will give you all elements having position fixed.

Select tags that starts with "x-" in jQuery

How can I select nodes that begin with a "x-" tag name, here is an hierarchy DOM tree example:
<div>
<x-tab>
<div></div>
<div>
<x-map></x-map>
</div>
</x-tab>
</div>
<x-footer></x-footer>
jQuery does not allow me to query $('x-*'), is there any way that I could achieve this?
The below is just working fine. Though I am not sure about performance as I am using regex.
$('body *').filter(function(){
return /^x-/i.test(this.nodeName);
}).each(function(){
console.log(this.nodeName);
});
Working fiddle
PS: In above sample, I am considering body tag as parent element.
UPDATE :
After checking Mohamed Meligy's post, It seems regex is faster than string manipulation in this condition. and It could become more faster (or same) if we use find. Something like this:
$('body').find('*').filter(function(){
return /^x-/i.test(this.nodeName);
}).each(function(){
console.log(this.nodeName);
});
jsperf test
UPDATE 2:
If you want to search in document then you can do the below which is fastest:
$(Array.prototype.slice.call(document.all)).filter(function () {
return /^x-/i.test(this.nodeName);
}).each(function(){
console.log(this.nodeName);
});
jsperf test
There is no native way to do this, it has worst performance, so, just do it yourself.
Example:
var results = $("div").find("*").filter(function(){
return /^x\-/i.test(this.nodeName);
});
Full example:
http://jsfiddle.net/6b8YY/3/
Notes: (Updated, see comments)
If you are wondering why I use this way for checking tag name, see:
JavaScript: case-insensitive search
and see comments as well.
Also, if you are wondering about the find method instead of adding to selector, since selectors are matched from right not from left, it may be better to separate the selector. I could also do this:
$("*", $("div")). Preferably though instead of just div add an ID or something to it so that parent match is quick.
In the comments you'll find a proof that it's not faster. This applies to very simple documents though I believe, where the cost of creating a jQuery object is higher than the cost of searching all DOM elements. In realistic page sizes though this will not be the case.
Update:
I also really like Teifi's answer. You can do it in one place and then reuse it everywhere. For example, let me mix my way with his:
// In some shared libraries location:
$.extend($.expr[':'], {
x : function(e) {
return /^x\-/i.test(this.nodeName);
}
});
// Then you can use it like:
$(function(){
// One way
var results = $("div").find(":x");
// But even nicer, you can mix with other selectors
// Say you want to get <a> tags directly inside x-* tags inside <section>
var anchors = $("section :x > a");
// Another example to show the power, say using a class name with it:
var highlightedResults = $(":x.highlight");
// Note I made the CSS class right most to be matched first for speed
});
It's the same performance hit, but more convenient API.
It might not be efficient, but consider it as a last option if you do not get any answer.
Try adding a custom attribute to these tags. What i mean is when you add a tag for eg. <x-tag>, add a custom attribute with it and assign it the same value as the tag, so the html looks like <x-tag CustAttr="x-tag">.
Now to get tags starting with x-, you can use the following jQuery code:
$("[CustAttr^=x-]")
and you will get all the tags that start with x-
custom jquery selector
jQuery(function($) {
$.extend($.expr[':'], {
X : function(e) {
return /^x-/i.test(e.tagName);
}
});
});
than, use $(":X") or $("*:X") to select your nodes.
Although this does not answer the question directly it could provide a solution, by "defining" the tags in the selector you can get all of that type?
$('x-tab, x-map, x-footer')
Workaround: if you want this thing more than once, it might be a lot more efficient to add a class based on the tag - which you only do once at the beginning, and then you filter for the tag the trivial way.
What I mean is,
function addTagMarks() {
// call when the document is ready, or when you have new tags
var prefix = "tag--"; // choose a prefix that avoids collision
var newbies = $("*").not("[class^='"+prefix+"']"); // skip what's done already
newbies.each(function() {
var tagName = $(this).prop("tagName").toLowerCase();
$(this).addClass(prefix + tagName);
});
}
After this, you can do a $("[class^='tag--x-']") or the same thing with querySelectorAll and it will be reasonably fast.
See if this works!
function getXNodes() {
var regex = /x-/, i = 0, totalnodes = [];
while (i !== document.all.length) {
if (regex.test(document.all[i].nodeName)) {
totalnodes.push(document.all[i]);
}
i++;
}
return totalnodes;
}
Demo Fiddle
var i=0;
for(i=0; i< document.all.length; i++){
if(document.all[i].nodeName.toLowerCase().indexOf('x-') !== -1){
$(document.all[i].nodeName.toLowerCase()).addClass('test');
}
}
Try this
var test = $('[x-]');
if(test)
alert('eureka!');
Basically jQuery selector works like CSS selector.
Read jQuery selector API here.

Selecting multiple, but not all HTML classes

So lets say I want to hide a div or span with CSS of a particular class.
Is there anyway to do so for the first X number of instances, or better yet, do it for all except for the last one? I imagine this would require javascript.
pseudocode I am thinking would look like this
if divname.class = "XYZ" {
select all instances -1
execute code that inserts random programmatic id into each class
execute code that hides all ids except the last one
}
Am I on the right track? Or is there any easier/better way?
If you can use jQuery and its nice pseudo-selectors, you could do something like
$('.question-summary:not(:last)')
You can test on the SO homepage.
You could do something like this,
var class_div = document.getElementsByClassName("class_name");
var i =0;
for(i=0;i<class_div.length-1;i++){
//do whatever you want with class_div[n-1] elements.
}
I am not sure how you do this with jquery but this is one possible solution for javascript.
If you were using jQuery...
$('.class_name').hide().last().show();
Here ya go - http://jsfiddle.net/uUK6G/
Set all your divs to the same class. Then use jQuery to filter out the last one.
$('.myDiv').filter(':not(:last)').hide();​
You can use the :last-child selector in CSS to do this.
http://www.w3schools.com/cssref/sel_last-child.asp
Is there anyway to do so for the first X number of instances, or
better yet, do it for all except for the last one? I imagine this
would require javascript.
You can try:
var elms = document.getElementsByClassName('XYZ'), total = elms.length;
for (var i = 0; i < total; i++){
elms[i].style.display = 'none';
}
In above loop, i will contain index of each element, you can put condition or rather range to specify which ones to delete. For example, if you wanted to hide all except for last one, you would modify it like:
for (var i = 0; i < total - 1; i++){
elms[i].style.display = 'none';
}

How can i get every "a" tag which "href" attribute contain word "youtube"?

I want to catch every a tag which href attribute contain word youtube.
I need to use jquery.
$('a[href*="youtube"]')
For more selectors, see the Selectors portion of the jQuery API.
Attribute Contains Selector:
$('a[href*="youtube"]');
You can always use "filter":
var allYoutubes = $('a').filter(function() { return /youtube/.test(this.href); });
You could use a fancier selector, but this is simple and clear and possibly faster, as the library doesn't need to do the work of figuring out what your selector means. It's a matter of taste mostly.
pretty simple...
$('a[href*="youtube"]')
http://api.jquery.com/attribute-contains-selector/
http://api.jquery.com/category/selectors/
These other answers are great; but in case you're interested it's not that difficult to do a pure JS (no jQuery) alternative
function getYouTubeLinks() {
var links = document.getElementsByTagName("a");
var ytlinks = [];
for(var i=0,l=links.length;i<l;i++){
if(links[i].href.replace("http://","").indexOf("youtube.com") === 0) {
ytlinks.push(links[i]);
}
}
return ytlinks;
}
var youtube = getYouTubeLinks();
for(var i=0,l=youtube.length;i<l;i++){
youtube[i].style.color = "pink";
}
it'd be a good idea to make sure to strip out "www." and "https://" as well.

How can I remove all CSS classes using jQuery/JavaScript?

Instead of individually calling $("#item").removeClass() for every single class an element might have, is there a single function which can be called which removes all CSS classes from the given element?
Both jQuery and raw JavaScript will work.
$("#item").removeClass();
Calling removeClass with no parameters will remove all of the item's classes.
You can also use (but it is not necessarily recommended. The correct way is the one above):
$("#item").removeAttr('class');
$("#item").attr('class', '');
$('#item')[0].className = '';
If you didn't have jQuery, then this would be pretty much your only option:
document.getElementById('item').className = '';
Hang on, doesn't removeClass() default to removing all classes if nothing specific is specified? So
$("#item").removeClass();
will do it on its own...
Just set the className attribute of the real DOM element to '' (nothing).
$('#item')[0].className = ''; // the real DOM element is at [0]
Other people have said that just calling removeClass works - I tested this with the Google jQuery Playground: http://savedbythegoog.appspot.com/?id=ag5zYXZlZGJ5dGhlZ29vZ3ISCxIJU2F2ZWRDb2RlGIS61gEM ... and it works. So you can also do it this way:
$("#item").removeClass();
Of course.
$('#item')[0].className = '';
// or
document.getElementById('item').className = '';
Remove specific classes:
$('.class').removeClass('class');
Say if element has class="class another-class".
The shortest method
$('#item').removeAttr('class').attr('class', '');
You can just try:
$(document).ready(function() {
$('body').find('#item').removeClass();
});
If you have to access that element without a class name, for example you have to add a new class name, you can do this:
$(document).ready(function() {
$('body').find('#item').removeClass().addClass('class-name');
});
I use that function in my project to remove and add classes in an HTML builder.
I like using native JavaScript to do this, believe it or not!
solution 1: className
Remove all class of all items
const items = document.querySelectorAll('item');
for (let i = 0; i < items.length; i++) {
items[i].className = '';
}
Only remove all class of the first item
const item1 = document.querySelector('item');
item1.className = '';
solution 2: classList
// remove all class of all items
const items = [...document.querySelectorAll('.item')];
for (const item of items) {
item.classList.value = '';
}
// remove all class of the first item
const items = [...document.querySelectorAll('.item')];
for (const [i, item] of items.entries()) {
if(i === 0) {
item.classList.value = '';
}
}
// or
const item = document.querySelector('.item');
item.classList.value = '';
jQuery ways (not recommended)
$("#item").removeClass();
$("#item").removeClass("class1 ... classn");
refs
https://developer.mozilla.org/en-US/docs/Web/API/Element/className
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
$('#elm').removeAttr('class');
Attribute "class" will no longer be present in "elm".
Since not all versions of jQuery are created equal, you may run into the same issue I did, which means calling $("#item").removeClass(); does not actually remove the class (probably a bug).
A more reliable method is to simply use raw JavaScript and remove the class attribute altogether.
document.getElementById("item").removeAttribute("class");
Let's use this example. Maybe you want the user of your website to know a field is valid or it needs attention by changing the background color of the field. If the user hits reset then your code should only reset the fields that have data and not bother to loop through every other field on your page.
This jQuery filter will remove the class "highlightCriteria" only for
the input or select fields that have this class.
$form.find('input,select').filter(function () {
if((!!this.value) && (!!this.name)) {
$("#"+this.id).removeClass("highlightCriteria");
}
});
Try with removeClass.
For instance:
var nameClass=document.getElementsByClassName("clase1");
console.log("after", nameClass[0]);
$(".clase1").removeClass();
var nameClass=document.getElementsByClassName("clase1");
console.log("before", nameClass[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clase1">I am a Div with class="clase1"</div>
I had a similar issue. In my case, on disabled elements was applied that aspNetDisabled class and all disabled controls had wrong colors. So, I used jQuery to remove this class on every element/control I want and everything works and looks great now.
This is my code for removing aspNetDisabled class:
$(document).ready(function () {
$("span").removeClass("aspNetDisabled");
$("select").removeClass("aspNetDisabled");
$("input").removeClass("aspNetDisabled");
});

Categories