Revert text-styling (class) back to it's original CSS - javascript

I have a span like this and styled as:
<span class="spoiler" onclick="reveal()"> I am a sentence.</span>
.spoiler {
background-color:#000000;
}
.spoiler:hover{
background-color:transparent;
}
Then I have some JS that modifies to permanently reveal the hidden text (truncated to show relevant part only):
if ... {
sentence.style.color = "#f00";
sentence.style.backgroundColor = "transparent";
} else {
sentence.style.color = "#000";
sentence.style.backgroundColor = "#000000";
}
The problem is in the else. Once I click to revert back to the spoiler style, I can no longer hover over the text to reveal the sentence (as I could pre-click).
How to achieve this?

Instead of set style on span in 'if' add some class on it, and remove this class in 'else'. Or just remove style attribute in else.

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.

Append two different types of div's to a single container

I have two different div with classes called "red" and "blue". By default these are hidden. I want to clone and display them into a single container called "cont". Red button appends red div's blue button appends blue div's.
function redCreator(word){
var red =document.getElementsByClassName('red')[redPos];
redPos++;
var redClone = red.cloneNode(true);
document.getElementById('cont').appendChild(redClone);
item.style.display = 'inline';
item.innerHTML=word;
}
function blueCreator(word){
//same as red
}
Right now the red divs appear separately from blue div. Ignoring the time and order I clicked them
red1|red2|red3|blue1|blue2
How do I allow the divs to display in the order I clicked them? Regardless of the class.
red1|blue1|red2|blue2|blue3
One solution I came up with was to use a common class name and add the red/blue class later.
function redCreator(word){
var item =document.getElementsByClassName('input-item')[itemPos];
itemPos++;
var itemClone = item.cloneNode(true);
itemClone.className += " red";
document.getElementById('cont').appendChild(itemClone);
item.style.display = 'inline';
item.innerHTML=word;
}
However this doesn't work as expected. CSS is messed up
In Case you are looking for a pure JS solution :
HTML :
<div class="red input">red</div>
<div class="blue input">blue</div>
<div id="cont">
</div>
<button onclick="redCreator('red');">RED</button>
<button onclick="blueCreator('blue');">blue</button>
CSS
.input {
display: none;
padding:10px;
}
.red {
background:red;
}
.blue {
background:blue;
}
JS:
function redCreator(word){
var red =document.getElementsByClassName('red')[0];
console.log(red);
var redClone = red.cloneNode(true);
document.getElementById('cont').appendChild(redClone);
redClone.style.display = 'inline-block';
redClone.innerHTML=word;
}
function blueCreator(word){
var blue =document.getElementsByClassName('blue')[0];
var blueClone = blue.cloneNode(true);
document.getElementById('cont').appendChild(blueClone);
blueClone.style.display = 'inline-block';
blueClone.innerHTML=word;
}
Just add some lines to get the numbering and you will be fine.
Happy coding.
So using jQuery (the fiddle is using 1.9.1 - but it should be forward compatible) I have put together a fiddle:
https://jsfiddle.net/27oa1pb7/
In this - it takes contents of hidden divs and appending them in the order you click them into the "cont" container ... using CSS, you could change the display of the divs, etc. It uses a very basic chain of jQuery commands:
...
$("#reddiv").clone().show().appendTo( "#cont" )
...
This code is what I came up with using your description, as there is no HTML or CSS example stating exactly what you may need.
Hope this helps!
Happy coding!

Toggling Background Color on Click with Javascript

I am working on a class project and need to be able to toggle the background color of a transparent png on click. I have been working through a number of examples from the site, but I can't get it working. I am a total novice at Javascript and haven't had luck trying to plug in jQuery code either.
Here is the targeted section:
<div class="expenseIcon"><a href="#">
<img src="images/mortgage.png"></a><br/>
<p>Rent or Mortgage</p>
</div>
On clicking the linked image, the goal is for the background on the image to change to green. Clicking it again would change it back to the default, white. Here's the CSS I'd like to toggle on/off with click.
.colorToggle {
background: #A6D785;
}
I had tried adding class="iconLink" to the href and class="iconBox" to the image with the following Javascript adapted from another post, but it didn't work.
var obj = {};
$(document).ready(function () {
$(".iconLink").click(function () {
var text = $(this).find(".iconBox");
obj.var1 = text;
//alert(obj.var1);
//return false;
$('.iconBox').removeClass('colorToggle');
$(this).addClass('colorToggle')
});
});
Any advice would be greatly appreciated!
Let's break down what is happening with your current code when you click the link.
var obj = {};
$(document).ready(function () {
$(".iconLink").click(function () {
var text = $(this).find(".iconBox");
obj.var1 = text;
$('.iconBox').removeClass('colorToggle');
$(this).addClass('colorToggle')
});
});
JQuery finds all elements with the classname "iconBox". In your case, this is the img element. The reference to that element is then saved in "obj.var1". You do not end up doing anything with this reference, so these two lines can be removed.
All elements with the class "iconBox" have the class "colorToggle" removed. Your img element didn't have this class on it, so nothing happens.
The class "colorToggle" is added to the anchor element. Yes! Now the element wrapping the img has a background color.
Unfortunately, clicking the anchor tag again won't do anything, since the anchor tag will already have the "colorToggle" class and all we would be doing would be trying to add it again. Hmm. Let's try changing addClass to toggleClass. Here's our new code:
$(document).ready(function () {
$(".iconLink").click(function () {
$(this).toggleClass('colorToggle');
}
});
Also, note that because we're working with the anchor element, the p element won't be affected by this change. If you want the entire div to change background colors, use this line instead:
$(".expenseIcon").toggleClass('colorToggle');
Using the given markup:
<!-- to toggle the bg-color onClick of anchor tag -->
<div class="expenseIcon">
<a href="#">
<img src="images/mortgage.png">
</a>
<br/>
<p>Rent or Mortgage</p>
</div>
since the question asks for javascript, heres an option for updating the background-color of an element using the built-in js.style method
//get a handle on the link
//only one element w/ className 'expenseIcon'
//first child of 'expenseIcon' is the anchor tag
var link = document.getElementsByClassName('expenseIcon')[0].children[0];
//get a handle on the image
var image = link.children[0];
//listen for click on link & call bgUpdate()
link.addEventListener('click', bgUpdate, false);
function bgUpdate() {
if(image.style.backgroundColor === 'lightgoldenrodyellow'){
image.style.backgroundColor = 'aliceblue';
} else if (image.style.backgroundColor === 'aliceblue') {
image.style.backgroundColor = 'lightgoldenrodyellow';
}
else console.log('image bgColor: ' + image.style.backgroundColor);
}
a similar example
css
.expenseIcon{
background: red;
}
.colorToggle {
background: blue;
}
jquery
$(".expenseIcon").click(function () {
$('.expenseIcon').toggleClass('colorToggle');
});
By default, the div will have expenseIcon background. ToggleClass will toggle the div class with colorToggle so will override the previous color.
You don't need an hyperlink tag A to manage clicks, just put it on the DIV.

:hover not working on <li> after backgroundColor change

I have managed to get a <ul> to switch display on and off with only a few lines of vanilla JavaScript code but I've run into an issue.
I gave the <li> that switches it on/off a :hover value (gray in this case). I'm keeping the same color on the <li> as the <ul> is collapsed. When the <ul> display is turned off though, I return it to the same value as it had had previously but the :hover value no longer works. Any solutions to this?
This is my JavaScript:
function expandIt(obj) {
obj.nextSibling.style.display = "block";
obj.style.backgroundColor = "gray";};
function reduceIt(obj) {
obj.style.display = "none";
obj.previousSibling.style.backgroundColor = "white";};
This is the HTML:
<ul>
<li onclick="expandIt(this)">ITEM</li>
<ul onclick="reduceIt(this)">
<li>subitem</li>
</ul>
</ul>
You could get this working with the !important modifier in your css. Something like this:
ul li:hover {
background-color:#ccc !important;
}
This overrides inline styles
hover versus inline style
The solution would be to add or a remove a class name with the styling you want. Due to css specificity, anything directly placed in style is going to take precedence over the defined rule inside of your css hover definition. The result is that your hover is never going to register the change of background color.
issues with siblings
Another issue with your code is that nextSibling and previousSibling are going to examine text nodes as well as elements. The trick there is going to be to ensure you are looking at an actual element and not a text node.
Something like this approach will ensure you end up with an element (.nodeType == 1)
function expandIt(obj) {
var next = obj.nextSibling;
while(next && next.nodeType != 1)next = next.nextSibling;
next.style.display = "block";
obj.style.backgroundColor = "gray";
};
function reduceIt(obj) {
obj.style.display = "none";
var prev = obj.previousSibling;
while(prev && prev.nodeType != 1)prev = prev.previousSibling;
prev.style.backgroundColor = "white";
};
Here is a demo of that concept: http://jsfiddle.net/Yu97H/
Now, even with that working example, it is possible to click so that gray is set as the background, but have hover broken. A simple rule such as ul li:hover { background-color: blue; } will exhibit that behavior.
Here is a demo of that behavior: http://jsfiddle.net/Yu97H/1/

How to write hoverHandler in JavaScript to change color of an element when hovering?

function hoverHandler(e)
{
if(event.target.getAttribute("id") != "hovering")
{
event.target.setAttribute("id", "hovering");
}
}
This is the code I have, I also have a CSS that sets the color when id is hovering.
The problem:
1) As I am hovering, the color does not get reset back to previous color when I leave the element
Can't you just use Css to solve the problem?
Something like
.element:hover
{
background-color: #FF0000;
}
where element is the class name
try adding, and make sure your checking for onmouseout as well
<script>
function hoverHandler(e)
{
if(e.id=="red") // hovering
{
e.id="blue";
}else {
e.id="red";
}
}
</script>
<span onmouseover="hoverHandler(this)" onmouseout="hoverHandler(this)">test</span>
or an inline event handlers could be
<style>#startStyle {color:lime} #red {color:red}#blue{color:blue}</style>
<span onmouseover="this.id='red'" onmouseout="this.id=''">test</span>
onmouseout would default back to the base style if any; or
<span onmouseover="this.id='red'" onmouseout="this.id='startStyle'">test</span>

Categories

Resources