Change CSS style sheet directly - javascript

I have a unique situation here. I have several buttons in HTML:
Normally they would look like the one on the left, but when I hover my mouse on them, they will animate and look like the right one.
I also added two color pickers which change the background and foreground respectively. (Both pickers effect the whole document as well as the buttons)
// Background color changer
var allb = document.getElementsByClassName('button');
for (var i = 0; i < allb.length; i++) {
allb[i].style.backgroundColor = bgcolor;
}
// Foreground color changer
var allf = document.getElementsByClassName('button');
for (var i = 0; i < allf.length; i++) {
allf[i].style.color = focolor;
allf[i].style.borderColor = focolor;
}
If I use both color pickers, then the animation will break and nothing will change when I hover hover the buttons. I understand why - the color pickers have a persisting effect on the style.
Is there a way to directly change the CSS file, or otherwise bypass this problem?
My code
.button {
font-family: SF, Arial, Helvetica, sans-serif;
background-color: #4c56af;
border: none;
padding: 16px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 30px;
margin: 4px 2px;
transition-duration: 0.4s;
cursor: pointer;
}
.button1 {
border-radius: 10px;
font-family: SF, Arial, Helvetica, sans-serif;
background-color: rgba(255, 255, 255, 0);
color: black;
border: 4px solid #4c56af;
}
.button1:hover {
border-radius: 10px;
font-family: SF, Arial, Helvetica, sans-serif;
background-color: #4c56af;
color: white;
}
Each button would look roughly like this:
<button type="button" onclick=func() class="button button1">Play</button>

You can modify the list of rules contained in a stylesheet. You can do that by means of StyleSheetList and CSSStyleSheet interfaces.
Select the stylesheet in question:
const styleSheet = document.styleSheets[0] // Use the index for the stylesheet whose rules you want to modify
Insert the rules using the insertRule() method:
const bgcolor = "green";
const focolor = "yellow";
styleSheet.insertRule(`
button {
background-color: ${bgcolor};
color: ${focolor};
border-color: ${focolor};
}
`, styleSheet.cssRules.length);
styleSheet.insertRule(`
button:hover {
background-color: ${focolor};
color: ${bgcolor};
}
`, styleSheet.cssRules.length);
If you need, you can remove those rules afterwards through the deleteRule() method.

This is a workaround.
Write your CSS animation code as a separate class, like this:
.button--animated {
border-radius: 10px;
font-family: SF, Arial, Helvetica, sans-serif;
background-color: #4c56af;
color: white !important;
}
Then use themouseenter event on all button elements for adding the transition class to it, and use the 'mouseleave' for removing it:
buttonElement.addEventListener("mouseenter", function() {
element.classList.add('button--animated')
});
buttonElement.addEventListener("mouseleave", function() {
element.classList.remove('button--animated')
});
If it doesn't work, add !important to the button--animated class's CSS. it's not ideal but may get the work done.

Related

Remove CSS with JavaScript or jQuery

I have a style tag in my project, which is generated automatically. I want to remove some of the styles of this tag that interfere with other classes
this is my CSS and style tag:
<style id="style-inline-inline-css">
#et-boc .et-l div {
text-align: inherit;
margin: 0;
padding: 0;
border: none;
outline: 0;
vertical-align: baseline;
background: transparent;
letter-spacing: normal;
color: inherit;
box-shadow: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
text-shadow: inherit;
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
transition: none;
}
#et-boc .et-l img {
max-width: 100%;
height: auto;
}
</style>
I want to remove this two CSS #et-boc .et-l img and #et-boc .et-l div with JavaScript or jQuery and other ways, Due to the structure of the project and the automatic generation of the codes, I cannot delete them on the back-end side. The only way in the front-end is to prevent them from being applied to the site elements
I'm not sure this would be the best approach for your exact goal. Anyway, I took the chance to craft a demo that shows how to access the stylesheets from JavaScript and how to remove a specific CSS rule.
For reference:
https://developer.mozilla.org/en-US/docs/Web/API/CSSRule
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/cssRules
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/deleteRule
This demo shows how a CSS rule can be found and deleted from a given style element (fetched by ID) using its selector as a key:
document.addEventListener('DOMContentLoaded',()=>{
const styleElement = document.getElementById('style-inline-inline-css');
const stylesheet = styleElement.sheet;
removeCssRuleMatchingSelector(stylesheet, '#et-boc .et-l div');
});
function removeCssRuleMatchingSelector(stylesheet, selector){
const cssRules = stylesheet.cssRules;
let foundRule = null;
let foundRuleIndex = -1;
for(let i=0; i<cssRules.length; i++){
if (cssRules[i].selectorText == selector){
foundRule = cssRules[i];
foundRuleIndex = i;
break;
}
}
if (foundRule !== null){
stylesheet.deleteRule( foundRuleIndex );
}
}
<style id="style-inline-inline-css">
/*css rule to delete*/
#et-boc .et-l div {
background: green;
}
/*css rule to remain unchanged*/
.test{
background: red;
}
</style>
<div id="et-boc">
<div class="et-l">
<div>If the rule was not deleted, this paragraph would be styled with bg green</div>
</div>
</div>
<div class="test">TEST</div>

.style.color don't change the color of an element in JavaScript

I would like to add Dark Mode to my site, so I created an HTML file with the css (in "white mode") and then i added a button (with the attribute onclick="enableDarkMode()") and defined the function like this:
function enableDarkMode() {
if (document.body.style === "background-color: black;") {
// disable dark mode
} else {
document.body.style = "background-color: black;"
Array.from(document.getElementsByTagName("a")).forEach(e => {
e.style.color = "white"
});
document.getElementsByTagName("h1")[0].style.color = "white"
document.getElementsByTagName("img")[0].style = "box-shadow: 0px 4px 6px 2px #404040;"
}
}
when i run everything and i click the Enable Dark Mode it just changes the background and it doesn't turn the text color in white even if they have the attribute style = "color: white;"
here's the full code: https://codepen.io/anonhexo/pen/WNGmevq
Your problem is that you are overriding the color of this <a> by using !important in your css.
If you inspect the element, and click on computed, you can see where the color is coming from. If you toggle dark mode you can see that white is there, but it has a line through it. The one that doesn't have the line through it is the one that is being used.
It seems to work fine if you remove !important from the css (both instances)
As a general rule of thumb, try not to use important as much as you can as you can get problems like this. In some situations it is neccessary, but not many.
function enableDarkMode() {
if (document.body.style === "background-color: black;") {
// disable dark mode
} else {
document.body.style = "background-color: black;"
Array.from(document.getElementsByTagName("a")).forEach(e => {
e.style.setProperty("color", "white", "important");
});
document.getElementsByTagName("h1")[0].style.color = "white !important"
document.getElementsByTagName("img")[0].style = "box-shadow: 0px 4px 6px 2px #404040;"
}
}
.dark-mode {
position: absolute;
top: 0;
right: 0;
font-size: 13px;
}
.about {
margin-bottom: 80px;
}
.text-center {
text-align: center;
}
.profile-pic {
box-shadow: 0px 4px 6px 2px lightgrey;
border-radius: 50%;
}
img {
vertical-align: middle;
}
img {
border: 0;
}
h1,
h2,
h3,
h4,
h5,
a {
color: #4A4E69 !important;
font-weight: 300;
font-family: 'Open Sans', sans-serif;
}
a:hover {
transition-duration: 0.5s;
color: #d1d3e2 !important;
}
a:not(:hover) {
transition-duration: 0.5s;
color: #4A4E69 !important;
}
.h1,
h1 {
font-size: 36px;
}
<html>
<head>
<title>AnonHexo</title>
<a class="dark-mode" style="text-decoration:none" onclick="enableDarkMode()">Enable Dark Mode</a>
</head>
<body>
<section class="about">
<div class="text-center" style="margin-top:100px"> <img
src="https://avatars1.githubusercontent.com/u/61375258?v=4" width="200" class="profile-pic">
<h1>AnonHexo, Italy</h1>
<div class="socialLinks">
GitHub,
<a href="https://www.stackoverflow.com/users/13221104/anonhexo?" style="text-decoration:none"
target="_blank">Stack Overflow</a>,
Codepen,
<br>
<a href="https://www.youtube.com/channel/UCnnqMGII7LHvvn1LUiU55eg" style="text-decoration:none"
target="_blank">YouTube</a>,
<a href="https://www.instagram.com/jacky.trave" style="text-decoration:none"
target="_blank">Instagram</a>,
Reddit,
Twitch
</div>
<!-- <h5>Young 12 y/o back-end developer.</h5>
<div class="text-center" style="margin:20px"> </div> -->
</div>
</section>
<button onclick="enableDarkMode()">
enable dark mode
</button>
</body>
</html>
your css for the a elements override the new command you give.
your css contains:
a:not(:hover) {
transition-duration: 0.5s;
color: #4A4E69 !important;
}
if you want the all the a elements to be white you should do:
e.style.setProperty("color", "white", "important");
h1 tag color is set to #4A4E69 !important;.
You should set !important to override this.
Refer to setProperty()
document.getElementsByTagName("h1")[0].style.setProperty("color", "white", "important")

Trying to make two functions requiring same value but in two input types (div and text)

I am trying to combine two functions into one in an interface. I have looked up div to input pages and yet to find the right answer.
The first function is used to construct a formula which translates it into a string format that is acceptable to another service.
The second function allows me to use an #mention type jQuery which triggers a list to select from as I type when I add a # symbol in the text.
The problem I have is that the first function only works with a form input "text" and the second function only works if I make the input a div with contenteditable="true".
I have tried to make either function work with the properties of the other and its just no good.
What I think I want is a way of copying the value of the text box into the form input box when I click on Refresh Console button.
Additionally, I only want to show one of them, the one I type in. So that means I want to use the form input field but have it hidden.
Here's my code that has two independently working functions. Where it says "type an at sign here" type an # and you will see the options. The input box which says "24 + 6 / 10 * 100" is controlling a function where the results are available in the console as 24|6|add|10|divide|100|multiply which is the expected result.
What I want to do is create a formula in the div text box like #net_value + #tax_value which are selectable at each point you add an at sign.
EDIT I have corrected some fundamental issues with the HTML but still have the same issue with a new one, box displays an extra box that I cannot get rid of no matter what I do.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/jquery#3.4.1/dist/jquery.min.js">
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/ichord/At.js#master/dist/css/jquery.atwho.min.css">
<script src="https://cdn.jsdelivr.net/gh/ichord/At.js#master/dist/js/jquery.atwho.min.js"></script>
<link rel="stylesheet" href="dynamic_table.css">
<title>BODMAS Translation</title><br>
<h1>BODMAS Translation</h1><br><br>
<input type = "text" id="f_input" name="formula" value="24 + 6 / 10 * 100">
<br><br>
<button onclick="myFunction()">Refresh Console</button><br><br>
<div id="enter_formula" class="text_input" contenteditable="true">Type an at sign here </div><br>
<script>
function myFunction() {
var operators = {
'*': 'multiply',
'/': 'divide',
'+': 'add',
'-': 'subtract'
},
string = document.getElementById("f_input").value,
result = string.replace(/\s+([^\s]+)\s+([^\s]+)/g, (_, o, v) => `|${v}|${operators[o]}`);
console.log(result);
};
</script>
<script>
$('#enter_formula').atwho({
at: "#",
data: ['input.net_value', 'input.tax_value', 'output.description']
});
</script>
</html>
Also including the css dynamic_table.css
table {
padding-inline: 15px;
padding-left: 10px;
border-color: rgb(182, 204, 243);
border-collapse: collapse;
border-style: hidden;
border-bottom: indianred;
font-family: Arial, Helvetica, sans-serif;
font-size: medium;
table-layout: fixed;
}
t1 {
font-family: Arial, Helvetica, sans-serif;
font-size: larger;
font-weight: bold;
}
thead {
font-family: Arial, Helvetica, sans-serif;
font-size: small;
background-color: rgb(182, 204, 243);
}
input {
width: 600px;
height: 30px;
padding: 5px;
}
div {
font-family: Arial, Helvetica, sans-serif;
font-size: small;
max-width: 600px;
height: 40px;
padding: 5px;
border: 1px solid rgb(170, 175, 163);
vertical-align: middle;
}
tbody {
font-size: small;
text-align: center;
}
.notfirst:hover {background-color: #f5f5f5;}
td {
height: 30px;
vertical-align: middle;
column-span: 2;
padding-left: 10px;
padding-right: 10px;
}
button {
border-radius: 8px;
height: 40px;
width: 100px;
background-color: rgb(50, 192, 197);
}

Hide DIV without ID based on DIV style

Can I hide DIV based on its style ?
I have this div which I need to hide:
<div style="font-family: helvetica, sans-serif; text-align: center; text-transform: uppercase; font-size: 9px; letter-spacing: 2px; font-weight: bold; padding: 3px 0px 5px !important; color: rgb(170, 170, 170) !important; clear: both;">...</div>
Can anyone give me an example please.
DIV is loading from another site so I don't have direct control to use "display:none".
You can use CSS attribute selectors to hide that div element base on the style attribute.
For instance:
div[style^="font-family: helvetica"] {
display: none;
}
Or look for a particular style:
div[style*="color: rgb(170, 170, 170)"] {
display: none;
}
WORKING DEMO.
var style = "font-family: helvetica, sans-serif; text-align: center; text-transform: uppercase; font-size: 9px; letter-spacing: 2px; font-weight: bold; padding: 3px 0px 5px !important; color: rgb(170, 170, 170) !important; clear: both;";
var elems = document.getElementsByTagName('div');
for (var i = 0; i < elems.length; i++) {
if(elems[i].getAttribute('style') == style) {
elems[i].style.display = 'none';
}
}
Example: http://jsfiddle.net/W3DLy/
This will filter/hide based off the letter-spacing attribute:
$('div').filter(function() {
return $(this).css('letter-spacing') == '2px';
}).hide();
Fiddle
select from the available divs based on
$('div').filter(function () {
return $(this).css('font-size') == '9px';
}).css('display', 'none');
or some other aspect of the style that you think is unique to these divs, then set display style to none
Just to hide the div you can use "display: none"

Adding more childs to a script

I have a cool script that works with two buttons. I need to add THREE more buttons as options for a total of FIVE altogether.
Does the whole script have to be re-written or could I just add more DIV classes? Not sure how to approch. Working for days on this...
Here is my link: http://jsfiddle.net/9cr4F/9/
HTML:
<div id="r6">
<div class="bx bx1">6</div>
<div id="sp"></div>
<div class="bx bx2">Gender</div>
<div id="sp"></div>
<div id="bxGender">
<input type="button" class="gnM" >
<div id="sp"></div>
<input type="button" class="gnF">
<div id="sp"></div>
<input class="req-string gender" id="gender" name="gender"></div>
</div>
CSS:
#r6 {
font-family: Verdana, Arial, Helvetica, sans-serif;
}
.bx {
height:60px;
line-height:60px;
float:left;
font-size:105%;
margin-top:15px;
color: #000;
background-color: #E8E8E8
}
.bx1 {
width:60px;
text-align:center
}
.bx2 {
width:175px;
padding-left:20px
}
#sp {
width: 15px;
height:60px;
float:left;
}
.gnM {
width:137px;
height: 60px;
background:#E8E8E8 url('http://www.41q.org/admin/img/male.png') 0px 0px no-repeat;
margin-top:0px;
padding: 0;
border: 0;
margin-left: 0px;
float: left;
outline: none;
text-align:center;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 105%;
font-style:normal;
color:#03F;
}
.gnF {
width:137px;
height: 60px;
background:#E8E8E8 url('http://www.41q.org/admin/img/female.png') 0px 0px no-repeat;
margin-top:0px;
padding: 0;
border: 0;
margin-left: 0px;
float: left;
outline: none;
text-align:center;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 105%;
font-style:normal;
color:#03F;
}
#r6 #bxGender .button-toggle-on {
background-position: 0 -120px
}
#bxGender {
width:486px;
height:60px;
float:left;
margin-top:15px
}
#r6:hover div.bx, #r6:hover input {background-color: #A9A9A9; cursor:pointer}
#r6:hover .gnM, #r6:hover .gnF {background-position: 0 -60px; cursor:pointer}
jQuery:
$(function() {
var $buttons = $("input[type='button']");
$buttons.click(function() {
$(this).parent().siblings('.bx, #bxGender .gender').css({'background':'#2F2F2F','color':'#fff'});
$buttons.not(this).removeClass('button-toggle-on');
$(this).toggleClass('button-toggle-on').attr('style','');
var varval = '';
if ($(this).hasClass('button-toggle-on')) {
varval = $(this).hasClass('gnF') ? 'Female' : 'Male';
$(this).siblings('input[type="button"]').css('background-position','0 -180px');
}
else {
$(this).siblings('input[type="button"]').attr('style','');
$(this).parent().siblings('.bx').attr('style','');
}
$("#gender").val(varval);
});
});
First thing you need is a markup to validate, at the moment it is not, IDs in a document must be UNIQUE so when you do
<div id="sp"></div>
you should do
<div class="sp"></div>
and try to get the clone nicely nested, even if it copies badly in here sometimes it helps to even have just few spaces here and there :)
In your CSS don't repeat the same properties if it applies to multiple elements, for example I restructured your gnF and gnM class, so all the properties are together and only the background image property is seperate.
.gnM,
.gnF,
.gnA {
background:#E8E8E8 0px 0px no-repeat;
text-indent:-10000px;
width:137px;
height: 60px;
margin-top:0px;
padding: 0;
border: 0;
margin-left: 0px;
float: left;
outline: none;
text-align:center;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 105%;
font-style:normal;
color:#03F;
}
.gnA {
background-image:url('http://www.41q.org/admin/img/alien.png');
}
.gnM {
background-image:url('http://www.41q.org/admin/img/male.png');
}
.gnF {
background-image:url('http://www.41q.org/admin/img/female.png');
}
You can simplify the jquery side by using the value attribute on your button, if you set a text-indent then the text wont show, and then you can simply retrieve the value using $(this).val();
$(function() {
var $buttons = $("input[type='button']"),
varval;
$buttons.click(function() {
// this should be done using a class to keep the js cleaner
$(this).parent().siblings('.bx, #bxGender .gender').css({
'background': '#2F2F2F',
'color': '#fff'
});
$buttons.removeClass('button-toggle-on');
$(this).addClass('button-toggle-on');
$("#gender").val($(this).val());
});
});​
This gives you a lot more flexibility as you can have as many button as you want but if you are building a form with multiple rows, as it seems, I would suggest also using a class for the input that contains the result and modify the value assignment so that it grabs the closest result input and update that, so that way it works for all rows.
Here is the modified fiddle http://jsfiddle.net/9cr4F/14/ - the third buttons styling is screwed of course but I'm sure it gives you what you need :)
Edited: Optimized CSS a bit more
Edited 2: Optimized the jquery code and move the background positioning to the class button-toggle-on as it is on when the background position need to be applied.

Categories