Reputation: 139
I am writing a small plugin that lets the user easily add transitions in javascript without jquery:
HTML:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Snippety</title>
<script src="snip.js" type="text/javascript"></script>
<link rel="stylesheet" href="snip.css" type="text/css" />
</head>
<body>
<script>
transition(
transSelector = '.snip',
transTime = '5s',
transDelay = 0000,
transFunc = 'transTo("background-color:red!important;")'
);
</script>
<div class="snip" id="snip">buhhug</div>
</body>
</html>
Js Plugin:
function transition(transSelector,transTime,transDelay,transFunc) {
document.styleSheets[0].insertRule(''+transSelector+' {transition:'+transTime+';-webkit-transition:'+transTime+';}');
setTimeout(transFunc, transDelay)
}
function transTo(rule) {
document.styleSheets[0].insertRule(''+transSelector+' {'+rule+'}');
}
CSS:
.snip {
background-color: green;
}
The problem is that, when the color is changed to red in javascript, I need to add !important
to change .snip
tobackground-color:red;
, but it only works once.
Is there any way to delete the background-color:green;
in the css stylesheet, or override without having to put the !important
in it? (I aim to change the color more than once).
I have tried .addRule
instead of .insertRule
, but I think I am barking up the wrong tree.
Upvotes: 1
Views: 281
Reputation: 1587
insertRule
has a second param that indicates where you want to insert the rule. If that param is 0
, then it inserts it into the top of the stylesheet. Which would put it before all other rules, which would mean the original rule is actually coming after the first. Try document.styleSheets[0].insertRule(''+transSelector+' {'+rule+'}', 1);
.
See https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule.
EDIT to answer second question:
This probably belongs as a different question, but I'll try and help you out. I'm sure this is just a subset of your code so it's hard to know exactly what you are looking to do here. But here are a couple of issues.
The first is that you are calling the transition
function and supplying variable names as well as values. In some languages, you can use "named parameters" like that, but in JS it doesn't do what you want it to do. What you are actually doing is creating a global variable called transSelector
, then setting it to '.snip'
. Same for the rest of the variables. Those values do get passed along to the transition
function. Then, you call transition
again, but now you are overwriting the same globals with new values. By the time transTo
is called, transSelector
doesn't mean what it used to mean, and it gets all messed up. Get rid of the global variables and only pass the values.
That causes a different problem, which is that transTo
doesn't know what transSelector
is anymore since it isn't a global. Also, there is potential for abuse because you are passing a string to setTimeout
which is just another form of eval(). Instead, you can just turn that into an anonymous function, and the same parameters will be available to it.
So the new plugin would look like this:
function transition(transSelector,transTime,transDelay,transRule) {
document.styleSheets[0].insertRule(''+transSelector+' {transition:'+transTime+';-webkit-transition:'+transTime+';}', 1);
setTimeout(function () {
document.styleSheets[0].insertRule(''+transSelector+' {'+transRule+'}', 1);
}, transDelay)
}
And you would call it like this:
transition('.snip', '5s', 0000, 'background-color:red !important;');
If you need more help with the plugin, I would suggest creating a separate question, as that will likely need to be more in-depth than we want to get editing a question about insertRule
.
Upvotes: 2