How can I modify a CSS class using JavaScript? - javascript

I know how to apply css on a single tag (or changing class on it) but THIS IS NOT WHAT I AM ASKING!
I would like to modify an attribute within a CSS class without touching the element where the class is applied.
In other words if this is the css
.myclass {
font-size: 14px;
color: #aab5f0;
}
and this is the html
<span id="test" class="myclass"> foo bar </span>
to increase the font of the span tag I want to modify the content of the class and NOT doing something like
var fontsize = parseInt($('#test').css('font-size').replace(/[^-\d\.]/g, ''));
fontsize += 10;
$('#test').css('font-size', fontsize+'px');
I want that the class becomes
.myclass {
font-size: 18px;
color: #aab5f0;
}
Is there a way to change the actual class through Javascript?
My other solution would be to put the css in a container and refill the container each time, but I have the sensation that it is not a good idea...

I think ideally you should define a base font size on the html or body element. All of the other font sizes in your CSS should be relative to that "master" font size, like so:
Then, when you adjust the font-size of the body through jQuery.css(), the other elements will all automatically adjust their size relative to the parent.
$(body).css('font-size', '14px');
You don't have to use the body level, you could define base font-size a div or other container and use that as the parent instead.
Here is a contrived example of this in action:
$('#grow').click(function() {
$('body').css('font-size', '18px');
});
body {
font-size: 12px;
}
h3,
p {
font-size: 1.0em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Main Title</h3>
<p> Welcome to my website. </p>
<button id="grow" type="button">Grow</button>

My comment notwithstanding, look at this question: Setting CSS pseudo-class rules from JavaScript
Changing a class and "setting pseudo-class rules" are achieved in the same way.
#Box9's answer is probably the one you should actually use:
I threw together a small library for this since I do think there
are valid use cases for manipulating stylesheets in JS.

There is no need to change the class itself. To override the behaviour, simply add another class to the existing one or change it entirely. I'll show the first option:
.myclass {
font-size: 14px;
color: #aab5f0;
}
.myclass.override {
font-size: 12px;
}
And then all you need to do from javascript is to toggle the override class. This way it's also much better as all the presentation is done in CSS.

Since it's obvious you're using jQuery, please see the addClass and removeClass functions.
$('#test').removeClass('myClass').addClass('yourClass');

looking for same thing.
This was my solution
https://jsfiddle.net/sleekinteractive/0qgrz44x/2/
HTML
<p>The Ants in France stay mainly on the Plants</p>
CSS
p{
font-family:helvetica;
font-size:15px;
}
JAVASCRIPT (uses jQuery)
function overwrite_css(selector,properties){
// selector: String CSS Selector
// properties: Array of objects
var new_css = selector + '{';
for(i=0;i<properties.length;i++){
new_css += properties[i].prop + ':' + properties[i].value + ';';
}
new_css += '}';
$('body').append('<style>' + new_css + '</style>');
}
overwrite_css('p',Array({prop: 'font-size', value: '22px'}));
overwrite_css('p',Array({prop: 'font-size', value: '11px'}));
overwrite_css('p',Array({prop: 'font-size', value: '66px'}));
// ends on 66px after running all 3. comment out lines to see changes

Simply JQuery:
$('#test').attr('class','bigFont');
or native JS :
document.getElementById('test').className ='bigFont';
UPDATED
var size = [ 10 , 20 , 30 ] ;
var i =0;
$('#test').css('font-size',size[i]+'px');
i = (i+1)%size.length ;

Related

Difference between className and classList

Which one of the following should be preferred under what circumstances?
btnElement.classList.add('btn');
btnElement.className = 'btn';
Using "classList", you can add or remove a class without affecting any
others the element may have. But if you assign "className", it will
wipe out any existing classes while adding the new one (or if you
assign an empty string it will wipe out all of them).
Assigning "className" can be a convenience for cases where you are
certain no other classes will be used on the element, but I would
normally use the "classList" methods exclusively.
And "classList" also has handy "toggle" and "replace" methods.
https://teamtreehouse.com/community/difference-between-classlist-and-classname
ClassList as the name suggest is the list of classes in an element.
If you have multiple classes on an element and you want to add/remove one without altering the rest you should use classList.
classList also provides methods like toggle which are really useful.
function toggleClass(){
let txt = document.querySelector("h2");
txt.classList.toggle("changebg");
}
.font-style {
font-family: sans-serif;
}
.changebg {
background-color: lightcoral;
}
<h2 class="font-style" >Hello World!</h2>
<button onclick='toggleClass()'>Toggle Background Class</button>
Using "classList", you can add or remove a class without affecting any others the element may have. But if you assign "className", it will wipe out any existing classes while adding the new one (or if you assign an empty string it will wipe out all of them)
classList
Using classList, you can add or remove a class without affecting any other classes the element may have.
So this is helpful for adding additional classes to an element that contain other classes.
classList has some handy methods like toggle and replace.
if (clicked) {
button.classList.add('clicked');
} else {
button.classList.remove('clicked');
}
Here if the button was clicked it will add the clicked class along with other classes the element may have and it will remove only the clicked class from the element.
className
If you use className, it will wipe out any existing classes while adding the new one (or if you assign an empty string it will wipe out all of them).
Using className can be convenience when you know this element will not use any other classes.
if (clicked) {
button.className = 'clicked';
} else {
button.className = '';
}
In this case, className will wipe all the classes the element may have and add clicked class to it. The empty string('') will wipe all the classes.
Conclusion
the recommendation would be to use className whenever possible.
Use classList when you need classList methods like toggle, replace, etc.
context https://dev.to/microrony/difference-between-classlist-and-classname-45j7
You can see the changes in JavaScript to apply same difference one with use of classList and other with className .
It will be clear from 1st btn only that classList add extra name in class while className replaces the whole class (only .border is applied) .
Further are different function of classList which cannot be achieved by className and at last 4 line of code is reduced to 1 liner with use of toggle .
So you should look to your needs : Like, if you want to completely replace the class property names than use className else you can use classList property with different methods .add() .remove() .replace() .toggle() to only have changes in specific without hampering all names of class
Instruction for below snippet : Reload the snippet when you click one button so that clear differences can be seen on next btns
var classList1 = document.getElementById("part1")
var classname2 = document.getElementById("part2")
function funcAdd() {
classList1.classList.add("border");
classname2.className = "border";
}
function funcRemove() {
classList1.classList.remove("color");
classname2.style.color = "black";
}
function funcReplace() {
classList1.classList.replace("background", "background1");
classname2.style.backgroundColor = "lightgreen";
}
function funcToggle() {
classList1.classList.toggle("color1");
if (classname2.style.color == "gold") {
classname2.style.color = "blue";
} else {
classname2.style.color = "gold";
}
}
.background {
background-color: red
}
.background1 {
background-color: lightgreen
}
.color {
color: blue
}
.font {
font-size: 24px;
}
.border {
border: 10px solid black
}
.color1 {
color: gold;
}
<div id="part1" class="background color font">classList</div>
<br><br><br>
<div id="part2" class="background color font">className</div>
<br><br><br>
<button onclick="funcAdd()">Add a border class</button>
<button onclick="funcRemove()">Remove a color class</button>
<button onclick="funcReplace()">Replace a background class</button>
<button onclick="funcToggle()">Toggle a color class</button>
<br><br>
I have just known one thing difference between className and classList. className returns string within they are names of the current element and classList also returns names but as an array.

is there a simple way to replace a style by another in fullcalendar

i would like to change all the occurrence style="width: 1px;" by style="width: 41px;" in fullcalendar agendaWeek after it render,
for that i used eventAfterRender
and my code is
eventAfterRender: function(event, $el, view) {
if( 'agendaWeek' === view.name ) {
var r = new RegExp(style="width: 1px;", "g");
var txtWith = 'style="width: 41px;"';
$el.find(".fc-body").val().replace(r,
txtWith).
replace(/\</g, "<").replace(/\>/g,
">").replace(/\&/g, "&");
}
Instead of trying to change the inline style attribute, I would assign a CSS class which overrides the inline styling.
$el.addClass('wideCell');
The class .wideCell would be something like this:
.wideCell {
width: 41px !important;
}
If you absolutely want to go with the replacement strategy, I would advise to use the following regex:
function replaceInlineWidth(element) {
// When the element has no style attribute, skip it.
if (!element.hasAttribute('style')) {
return;
}
// Get the style attribute from the element
var inlineStyle = element.getAttribute('style'),
regex = /width\s?:\s?\d+px(?:;|$)/g;
// Replace the inline width declaration with 41px
inlineStyle = inlineStyle.replace(regex, 'width: 41px;');
// Set the modified style attribute back on the element.
element.setAttribute('style', inlineStyle);
}
// Create a test element.
var
element = document.createElement('div');
// Give the test element some inline style.
element.setAttribute('style', 'background-color: #000; width: 1px; margin: 1em;');
// Run the replacement method.
replaceInlineWidth(element);
// Log the inline style, the width should be 41px.
console.log(element.getAttribute('style'));
It will match things like width:1px, width :1px, and width: 1px. It also matches width: 30px. It will be a bit more resilient. If you really only want to replace width: 1px change the regex to width\s?:\s?1px(?:;|$).
to change fc-axis style,
First solution,
#Thijs idea
add to your css file,
.wideCell {
width: 41px !important;
}
go to fullcalendar.js and add wideCell to any class that contain fc-axis, EXP
'<td class="fc-axis fc-time '
become
'<td class="fc-axis fc-time wideCell '
without it i would have
fullcalendar weekview not showing correctly
but it should be like this fullcalendar weekview showing correctly
Second solution
open fullcalendar.js and change
var maxInnerWidth = 0; to var maxInnerWidth = 40;\\40 or what ever feet your need,

How to dynamically change a class css styling?

Goal
In my program I want to do both things with jquery/javascript:
Change styling of css classes dynamically
Add/remove classes to elements
Problem
To do the first thing I use $(".className").css() method, but it changes style only for those elements that already have className class, i.e. if I later add className to an element its style won't be new. How can I solve this?
Example
See it also at jsfiddle.
$("p").addClass("redclass");
$(".redclass").css("color", "darkRed");
$("span").addClass("redclass");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>I want to be red! And I am.</p>
<span>I want to be red too but I'm not :'(</span>
Result:
A more shorten format:
$("<style/>", {text: ".redclass {color: darkRed;}"}).appendTo('head');
The snippet:
$("<style/>", {text: ".redclass {color: darkRed;}"}).appendTo('head');
$("p").addClass("redclass");
$("span").addClass("redclass");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>I want to be red! And I am.</p>
<span>I want to be red too but I'm not :'(</span>
While other (working) answers have been supplied, they don't actually answer your question - namely, they don't change the specified css class, but instead override it by adding another rule later in the document.
They achieve this, basically:
Before
.someClass
{
color: red;
}
After
.someClass
{
color: red;
}
.someClass
{
color: white;
}
When in many cases, a better option would see the color attribute of the existing rule altered.
Well, as it turns out - the browser maintains a collection of style-sheets, style-sheet rules and attributes of said rules. We may prefer instead, to find the existing rule and alter it. (We would certainly prefer a method that performed error checking over the one I present!)
The first console msg comes from the 1 instance of a #coords rule.
The next three come from the 3 instances of the .that rule
function byId(id){return document.getElementById(id)}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked, false);
}
function onGoBtnClicked(evt)
{
alterExistingCSSRuleAttrib('#coords', 'background-color', 'blue');
alterExistingCSSRuleAttrib('.that', 'color', 'red');
}
// useful for HtmlCollection, NodeList, String types (array-like types)
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function alterExistingCSSRuleAttrib(selectorText, tgtAttribName, newValue)
{
var styleSheets = document.styleSheets;
forEach(styleSheets, styleSheetFunc);
function styleSheetFunc(CSSStyleSheet)
{
forEach(CSSStyleSheet.cssRules, cssRuleFunc);
}
function cssRuleFunc(rule)
{
if (selectorText.indexOf(rule.selectorText) != -1)
forEach(rule.style, cssRuleAttributeFunc);
function cssRuleAttributeFunc(attribName)
{
if (attribName == tgtAttribName)
{
rule.style[attribName] = newValue;
console.log('attribute replaced');
}
}
}
}
#coords
{
font-size: 0.75em;
width: 10em;
background-color: red;
}
.that
{
color: blue;
}
<style>.that{color: green;font-size: 3em;font-weight: bold;}</style>
<button id='goBtn'>Change css rules</button>
<div id='coords' class='that'>Test div</div>
<style>.that{color: blue;font-size: 2em;font-weight: bold;}</style>
#synthet1c has described the problem. My solution is:
$("head").append('<style></style>');
var element = $("head").children(':last');
element.html('.redclass{color: darkred;}');
What you are having issue with is that when you use the jQuery selector $('.redclass').css('color', 'darkRed') you are getting all the elements that currently have that class and using javascript to loop over the collection and set the style property.
You then set the class on the span after. Which was not included in the collection at the time of setting the color
You should set the class in your css file so it is distributed to all elements that have that class
console.log($('.redclass').length)
$("p").addClass("redclass");
console.log($('.redclass').length)
// $(".redclass").css("color", "darkRed");
$("span").addClass("redclass");
console.log($('.redclass').length)
.redclass {
color: darkRed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>I want to be red! And I am.</p>
<span>I want to be red too but I'm not :'(</span>

How to apply css to only numbers in a text inside/or any <p><p> element?

I am Using a Regional language unicode font-face in my site but the numbers are not looking good.
So I want to apply new font-style or css to numbers only..
please help
This can be done using CSS's unicode-range property which exists within #font-face.
The numbers 0 to 9 exist in Unicode within the range U+0030 to U+0039. So what you'll need to do is include a font alongside your existing font which specifically targets this range:
#font-face {
font-family: 'My Pre-Existing Font';
...
}
#font-face {
font-family: 'My New Font Which Handles Numbers Correctly';
...
unicode-range: U+30-39;
}
The result of this will be that every instance of Unicode characters U+0030 (0) through to U+0039 (9) will be displayed in the font which specifically targets that range, and every other character will be in your current font.
You can wrap all numbers in p tags with a <span class="number">:
CSS
.number {
font-family: Verdana;
}
jQuery
$('p').html(function(i, v){
return v.replace(/(\d)/g, '<span class="number">$1</span>');
});
But personally, I would go with James suggestion ;)
http://jsfiddle.net/ZzBN9/
There is no way to apply CSS to all numbers specifically. In each number tag you could add the attribute class='number' and then in the CSS you could add
.number {
font-family: arial;
}
Better with this
$('p').html(function(i, v){
return v.replace(/(\d+)/g, '<span class="number">$1</span>');
});
With + you avoid one span per complete number (span for 321), not one per each number found (span for 3 for 2 and for 1)
You can use the regex replace and detect the numbers then add the class
following code:
$('p').html(function(i,c) {
return c.replace(/\d+/g, function(v){
return "<span class='numbers'>" + v + "</span>";
});
});
.numbers
{
color:red;
font-size:30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
View 11 new out of 11 message(s) in your inbox
</p>

Apply CSS Repeatedly to Specific Words

I'm trying to apply CSS repeatedly and automatically to specific words.
For example, for the word "Twitter" I want the colour of the text to be #00ACED.
At present I am manually applying these colours around specific brand terms using span classes:
<span class="twitter">Twitter</span>
With the CSS:
.twitter {
color: #00ACED;
}
However, this is a process and I would prefer a method which completes this styling automatically. I have about 20 brand words with an associated colour styling.
Can anyone assist me with this problem. I am using WordPress if that makes any difference.
I think the most straight-forward way to do it is by using a smart jQuery highlight plugin I came across. After applying it, you'll be able to do what you're after. Below is an example, with a link to a live fiddle at the end:
HTML
<p>Some examples of how to highlight words with the jQuery Highlight plugin. First an example to demonstrate the default behavior and then others to demonstrate how to highlight the words Facebook and Twitter with their own class names. Words will be highlighted anywhere in the DOM, one needs only to be specific on where the script should look for the words. It supports case-sensitivity and other options, like in the case of YouTube.</p>
CSS
p { line-height: 30px; }
span { padding: 4px; }
.highlight { background-color: yellow; }
.facebook { background-color: #3c528f; color: white; }
.twitter { background-color: #1e9ae9; color: white; }
.youtube { background-color: #be0017; color: white; }
Highlight Plugin (needs to be loaded after jQuery and before the JavaScript below)
<script type="text/javascript" src="http://github.com/bartaz/sandbox.js/raw/master/jquery.highlight.js"></script>
JS
// default
$("body p").highlight("default");
// specify class name (not case sensitive)
$("body p").highlight("twitter", { className: 'twitter' });
$("body p").highlight("facebook", { className: 'facebook' });
// specify class name (case sensitive)
$("body p").highlight("YouTube", { className: 'youtube', caseSensitive: true });
Include this JavaScript at the bottom of the page (before the body closing tag so that you don't need to use the function below:
$(document).ready(function() {
// unnecessary if you load all your scripts at the bottom of your page
});
Fiddle for the win! :)
Something like this may work. You would have to loop through your search terms and this might not be the most effective way to do it.
function add_class (search, replacement) {
var all = document.getElementsByTagName("*");
for (var i=0, max=all.length; i < max; i++) {
var text = all[i].textContent || all[i].innerText;
if (text.indexOf(search) !== -1 && ! all[i].hasChildNodes()) {
all[i].className = all[i].className + " " + replacement;
}
}
}
var replacements = [
["Twitter","twitter"],
//
]
for (var i = replacements.length - 1; i >= 0; i--) {
add_class(replacements[i][0],replacements[i][1]);
};
Note: I didn't test this at all.
If you know minimum among of JavaScript, this JavaScript library can make your life much easier. it will convert all the letter in the string into a span tag. http://daverupert.com/2010/09/lettering-js/
For those of you interested in the answer, I've created a solution using WordPress functionality:
function replace_custom_word($text){
$replace = array(
'Twitter' => '<span class="twitter"><a title="Twitter" target="_blank" href="http://www.twitter.com/">Twitter</a></span>',
'Facebook' => '<span class="facebook"><a title="Facebook" target="_blank" href="http://www.facebook.com/">Facebook</a></span>'
);
$text = str_replace(array_keys($replace), $replace, $text);
return $text;}

Categories

Resources