Changing background color with addClass in jQuery - javascript

I am learning jQuery, and I've written a simple script that is intended to add (or remove) a class when a mouse enters (or leaves) a div. The new class adds a different height and is also supposed to change the background color and opacity of the entered div.
Here's the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Testing jQuery</title>
<style type="text/css">
div {
width: 400px;
height: 300px;
margin: 20px;
float: left;
}
#one {
background-color: red;
}
#two {
background-color: green;
}
#three {
background-color: blue;
}
.change {
height: 150px;
background-color: rgba(0,0,0,0.4);
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
<script type="text/javascript">
$(document).ready(function () {
$("div").mouseenter(function () {
$(this).addClass("change");
});
$("div").mouseleave(function () {
$(this).removeClass("change");
});
});
</script>
</body>
</html>
While the height changes, there's no effect on the background-color property. Why is that so?
I've checked out the .mouseenter(), .mouseleave() and the .addClass() API documentation, but couldn't find anything specific to this problem.

Your javaScript code is 100% fine. The problem is in CSS You have written. Selection by id #one is more important than classname .one, so when you apply some #rules and .rules to the emenet at the same time, browser will chose the first ones as more important. If You can, try not to use #id selectors at all in css and leave it for javaScript usage.
css:
.one {
background-color: red;
}
.two {
background-color: green;
}
.three {
background-color: blue;
}
html:
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
demo: https://jsfiddle.net/cz8v1gy4/

Edited answer after a re-read:
You're running in to CSS specificity issues. IDs are more specific than classes, which means that your background color is going to stay the color of the ID and not the class. This is one reason why it's (often) recommended to not use IDs in CSS.
If you change everything over to classes it will work how you're expecting:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Testing jQuery</title>
<style type="text/css">
div {
width: 400px;
height: 300px;
margin: 20px;
float: left;
}
.one {
background-color: red;
}
.two {
background-color: green;
}
.three {
background-color: blue;
}
.change {
height: 150px;
background-color: rgba(0,0,0,0.4);
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<script type="text/javascript">
$(document).ready(function () {
$("div").mouseenter(function () {
$(this).addClass("change");
});
$("div").mouseleave(function () {
$(this).removeClass("change");
});
});
</script>
</body>
</html>

Try utilizing css selectors #one:hover, #two:hover, #three:hover , :hover pseudo-class, transition . See also Specificity
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Testing jQuery</title>
<style type="text/css">
div {
width: 400px;
height: 300px;
margin: 20px;
float: left;
}
#one {
background-color: red;
}
#two {
background-color: green;
}
#three {
background-color: blue;
}
#one:hover, #two:hover, #three:hover {
height: 150px;
background-color:rgba(0,0,0,0.4);
transition: height 1000ms, background-color 1000ms;
}
</style>
</head>
<body>
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
</body>
</html>

There are some good answers here and explanations why it's not working, but it looks like no one has answered how to do what it seems like your intent was.
Which was to add the two background colors together to get a darker color on hover. You can get around it changing it to a grey by adding something else in.
For example:
.change {
height: 150px;
background-image: linear-gradient(to right, rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%)!important;
}
This puts a solid color gradient in as the background image which layers on top of the background color.
Like This JSFiddle

When you hover over div#one it becomes div#one.changed. Now with regard to background color you have two competing values:
#one {
background-color: red;
}
And:
.change {
background-color: rgba(0,0,0,0.4);
}
The first one wins, because it is more specific.
To get around this use
.change {
height: 150px;
background-color: rgba(0,0,0,0.4)!important;
}

Related

Toggle class of multiple ids (javascript)

I have 2 elements that each have different background colors and upon click, I'd like to make them change to a different color.
Here is code that works if the elements do not already have background-color:
html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<style media="screen">
.buttons {
width: 150px;
height: 50px;
border: solid 2px #999;
text-align: center;
color: black;
cursor: pointer;
}
background-color: red;
}
</style>
</head>
<body>
<div id="buttonGallery">
<div id="button_1" class="buttons">
<p>button_1</p>
</div>
<div id="button_2" class="buttons">
<p>button_2</p>
</div>
</div>
<script type="text/javascript">
$("#button_1").click(function() {
$('#button_1').toggleClass('selected');
});
$("#button_2").click(function() {
$('#button_2').toggleClass('selected');
});
</script>
</body>
</html>
However, if I give each id a background-color, they do not change color upon click:
<style media="screen">
.buttons {
width: 150px;
height: 50px;
border: solid 2px #999;
text-align: center;
color: black;
cursor: pointer;
}
#button_1 {
background-color: blue;
}
#button_2 {
background-color: green;
}
.selected {
background-color: red;
}
Also is there a way to write one function that turns each element red upon click? (Rather than write a function for each button. I will eventually have 8 buttons.) Thank you! Any help would be really appreciated!
First of all the .selected the class will apply each time but due to the selector priority it will be overwritten by .button. So there are tones of ways to fix it.
You can use !important keyword (not recommended at all)
.selected {
background-color: red !important;
}
NOTE: You should avoid as much as you can from using !important keyboard, but in your particular case this is the best way to do it, but I highly recommend changing your styling method and use the pseudo-class selector for your main classes instead. just like this:
.buttons:first-of-type {
background-color: blue;
}
.buttons:nth-of-type(2) {
background-color: green;
}
/* and so on */
And use a specific method for your selected class something like this:
.buttons.selected {
background-color: red;
}
Or
You can use a straight forward but repetitive approach. So make your .selected class selector something like this:
#button_1.selected, #button_2.selected /* and so on */ {
background-color: red;
}
Also for simplifying your js code you can do as follows:
$('.buttons').click(function () {
$(this).toggleClass("selected"); // $(this) keyword will refer to the clicked button, each time attribute with class buttons got clicked.
});
I think your problem is CSS Specificity.
The ID selector (#) will have a higher specificity than the class selector (.)
Try changing
.selected {
background-color: red;
}
to
#button_1.selected, #button_2.selected {
background-color: red;
}
If you want add ".selected" class for each button So you can try this one
I hope this will help you a lot.
$("button").each(function(){
$(this).on("click", function(){
$(this).toggleClass('.selected');
});
});
Just add background-color: red !important;
EDIT
you can use this like one function as requested.
$('.buttons').click(function(e) {
e.stopPropagation();
$(this).toggleClass('selected');
});
$("#button_1").click(function() {
$('#button_1').toggleClass('selected');
});
$("#button_2").click(function() {
$('#button_2').toggleClass('selected');
});
.buttons {
width: 150px;
height: 50px;
border: solid 2px #999;
text-align: center;
color: black;
cursor: pointer;
}
#button_1 {
background-color: blue;
}
#button_2 {
background-color: green;
}
.selected {
background-color: red !important;
}
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<style media="screen">
.buttons {
width: 150px;
height: 50px;
border: solid 2px #999;
text-align: center;
color: black;
cursor: pointer;
}
background-color: red;
}
</style>
</head>
<body>
<div id="buttonGallery">
<div id="button_1" class="buttons">
<p>button_1</p>
</div>
<div id="button_2" class="buttons">
<p>button_2</p>
</div>
</div>
</body>
Here is the pure JS method.
You'll want to use querySelectorAll('.buttons').
const buttons = document.querySelectorAll('.buttons')
This will make a node list of all objects with the class .buttons.
Then you'll want to apply an event listener to each button by using forEach.
buttons.forEach(button=>{
button.addEventListener('click', ()=>{})
Then you can write a function for when a button is clicked.
const buttons = document.querySelectorAll('.buttons');
buttons.forEach(button=>{
button.addEventListener('click', ()=>{
button.classList.toggle('selected')
})
})
This will update automatically as you add elements with a class of buttons.
And then as others mentioned, add !important to the .selected class background-color property.

Mobile devices touch event with css

I have made a simple card system with mobile.
When I use below code, touch event detect very well.
html, body {
margin: 0;
padding: 0;
}
.card1 {
height: 200px;
width: 200px;
background-color: green;
}
.card1:active {
background-color: blue;
}
<html>
<body ontouchstart="">
<div class="wrap">
<div class="card1"></div>
</div>
</body>
</html>
Not only in mobile devices but also works fine in the desktop.
But after detach the finger from the screen, it return to original state.
My goal is if I click touch the box, box will be changed to background-color: blue; and do not have to return background-color: green;
Is there any solution here?
Thanks.
It can be achieved by applying background color on click event using js
$('.card1').click(function() {
$('.card1').css({
'background-color': 'blue',
});
});
html, body {
margin: 0;
padding: 0;
}
.card1 {
height: 200px;
width: 200px;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body ontouchstart="">
<div class="wrap">
<div class="card1"></div>
</div>
</body>
</html>

How to make progress bar move slowly by JavaScript

As I am increasing its width by 10%, it will apply suddenly, I want it to have some smooth movement.
var counter=0;
function moveBy10(x){
var width =10;
var bar = document.getElementById('bar');
counter++;
if(counter*x < 101){
bar.style.width = counter*x +'%';
}
}
#barHolder {
background-color: black;
width: 100%;
height: 80px;
}
#bar {
background-color: red;
width:5%;
height: 80px;
}
#by10 {
background-color: grey;
height: 40px;
width: 100px;
border-radius: 5px;
margin-top: 10px;
padding-top: 10px;
text-align: center;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<title>Progress bar</title>
<link rel="stylesheet" type="text/css" href="bar.css">
<script type="text/javascript" src="bar.js"></script>
</head>
<body>
<!--- progress bar container -->
<div id="barHolder">
<div id="bar"></div>
</div>
<div type="button" id="by10" onclick="moveBy10(10)">Move 10%</div>
</body>
</html>
By adding to the desired element the property transition (in your case #bar), we can achieve the smoothing effect you seek for with CSS. That will result in a smoother experience, than accomplishing the same effect with Javascript.
transition: width 2s;
(Adds a smoothing of 2s for the transition of width)
CSS transitions allows you to change property values smoothly (from one value to another), over a given duration.
Learn more about transitions.
But to fully answer the question to achieve the same results with JavaScript (only) i would use a timeout to step to small intervals of the real step (If we wanted to transition by 10% for 1 second i'd split it to 0.1 per 1%)
But i strongly advice to use the best technology for each solution and not try to achieve something with a specific technology without a really good reason.
I don't understand your question, because you do not this, but I understand you need this
var counter=0;
function moveBy10(x){
var width =10;
var bar = document.getElementById('bar');
counter++;
if(counter*x < 101){
bar.style.width = counter*x +'%';
}
}
#barHolder {
background-color: black;
width: 100%;
height: 80px;
}
#bar {
background-color: red;
width:5%;
height: 80px;
transition: width 2s; /* Add this */
}
#by10 {
background-color: grey;
height: 40px;
width: 100px;
border-radius: 5px;
margin-top: 10px;
padding-top: 10px;
text-align: center;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<title>Progress bar</title>
<link rel="stylesheet" type="text/css" href="bar.css">
<script type="text/javascript" src="bar.js"></script>
</head>
<body>
<!--- progress bar container -->
<div id="barHolder">
<div id="bar"></div>
</div>
<div type="button" id="by10" onclick="moveBy10(10)">Move 10%</div>
</body>
</html>

moving element on top of another element on a button click [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I have two elements and a button. I'm trying to make the first element to be completely on top of the other element when the button is clicked.
$("#clickme").click(function(){
$("#frist_element").appendTo("#second_element")
})
div{
background-color: red;
width: 30px;
height:30px;
margin: 20px;
border-radius: 50%;
}
#second_element{
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first_element"></div>
<div id="second_element"></div>
<button id="clickme">Click Me</button>
when the button is clicked the red circle should move(animate to move) to the yellow circle and the green circle should not be visible
Update:
here is a gif that shows exactly what im looking for gif
Done, I just add position relative to the first div and took the top position of the second and added to the first div using the animation funtion . After that the first goes to on the second div.
$("#clickme").click(function(){
var secondDivPosition=$("#second_element").position();
var firstDivPosition=$("#first_element").position();
var topSecond =secondDivPosition.top.toString()+'px';
var topFirst =firstDivPosition.top.toString()+'px';
if(firstDivPosition.top==secondDivPosition.top)
{
$("#first_element").animate({"top":"0px"},300, function() {});
$("#second_element").css({"visibility":"initial"});
}else
{
$("#first_element").animate({"top":topSecond},300, function() {
$("#second_element").css({"visibility":"hidden"});
});
}
});
div{
background-color: red;
width: 30px;
height:30px;
margin: 20px;
border-radius: 50%;
}
#first_element{
position: relative;
}
#second_element{
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first_element"></div>
<div id="second_element"></div>
<button id="clickme">Click Me</button>
You can add an attribute with a flag and use the functions before and after.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
div{
background-color: red;
width: 30px;
height:30px;
margin: 20px;
border-radius: 50%;
}
#second_element{
background-color: green;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#clickme").click(function(){
if($(this).attr('data-click-state') == 1) {
$(this).attr('data-click-state', 0)
$("#first_element").before($("#second_element"))
} else {
$(this).attr('data-click-state', 1)
$("#first_element").after($("#second_element"))
};
});
});
</script>
</head>
<body>
<div id="first_element"></div>
<div id="second_element"></div>
<button id="clickme">Click Me</button>
</body>
</html>
I think that the css transform property might come handy for you. Also added a transition delay to look nicer. Is this what you were looking for?
$("#clickme").click(function(){
$("#second").css("transform","translateY(-50px)");
$("#first").css("transform","translateY(50px)");
});
div{
display: block;
width: 50px;
height: 50px;
border-radius: 50%;
transition: all 0.4s;
}
#first {
background-color: red;
}
#second {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first"></div>
<div id="second"></div>
<button id="clickme">Click Me</button>
You need to have a container to detect which is the current status
then just capture the divs and then play with them
hope it helps
$("#clickme").click(function(){
var first= $("#first_element");
var second= $("#second_element");
if(!$('.container').hasClass('red-green')){
$('.container').addClass('red-green');
$("#first_element").remove();
$("#second_element").after(first);
}else {
$('.container').removeClass('red-green');
$("#second_element").remove();
$("#first_element").after(second);
}
})
#first_element{
background-color: red;
width: 30px;
height:30px;
margin: 20px;
border-radius: 50%;
display: block;
}
#second_element{
background-color: green;
width: 30px;
height:30px;
margin: 20px;
border-radius: 50%;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="first_element"></div>
<div id="second_element"></div>
</div>
<button id="clickme">Click Me</button>

How to expand an HTML webpage when collapsing an accordion panel?

In my webpage I have accordion panels which collapse and close. I have set the page height to be specific. However, I want it to be specific from the start, but be able to expand when I open and close the panel, so that I don't have to set the page too be so long with no content. Any ideas about how I go about doing this?
This is only an example I used, which is the reason for the small height currently.
My Current Code:
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta charset = "utf-8">
<title>London Tour Guide</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<script src="jquery.js"></script>
<style>
div.container { position: absolute; top: 10px; left: 400px; width: 720px; height: 1300px;
background-color: white; }
div.content {
width: 700px; height: 120px;
background-color: lightblue; padding: 5px; }
button.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
div.panel.show {
display: block;
}
</style>
</head>
<body>
<div class="container">
<div class = "content">
<button class="accordion">Panel</button>
<div class="panel">
Hello
</div>
<button class="accordion">Panel 2</button>
<div class="panel">
Hello
</div>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
</script>
</div>
</body>
</html>
If I understand correctly,
you're looking for min-height:1300px instead of height:1300px on div.container
The most robust way without the use of Javascript is to get rid of explicitly setting the height of your containers in CSS - that way the height is automatically going to conform to the total height of your child elements.
If your container is not absolutely positioned, I believe Vlad is Glad's answer with using the CSS property, min-height, will apply.
If your container must be absolutely positioned, you could grab the height of the expanded panel through jQuery in your onClick handler, and add/subtract the height to your container.

Categories

Resources