I have multiple hoverable divs which change when being hovered... When i get off them with the mouse they return to their normal position. I would like for them to stay hovered unless another div with the same class gets hovered. So one should stay hovered. Sort of like being able to select only one div but with hovering
I tried everything that is in my knowledge
<html>
<head>
<style media="screen">
.hoverable:hover {
background-color: red;
}
.hoverable {
width: 100px;
height: 100px;
background-color: blue;
transition-duration: 1s;
}
</style>
</head>
<body>
<div class="hoverable">
lorem
</div>
<div class="hoverable">
Lorem
</div>
<div class="hoverable">
Lorem
</div>
<div class="hoverable">
Lorem
</div>
</body>
</html>
hope you are looking for something like this
$("div.hoverable").hover(function() {
$("div.hoverable").removeClass("hovered");
$(this).addClass("hovered");
})
div.hoverable {
height: 30px;
width: 300px;
background-color: #ccc;
border: 1px solid #666;
margin: 5px;
}
div.hovered {
color: red;
background-color:yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hoverable">
1
</div>
<div class="hoverable">
2
</div>
<div class="hoverable">
3
</div>
<div class="hoverable">
4
</div>
There are a few ways you could accomplish this. The easiest that comes to mind is to not use the browser hover style but apply a class dynamically only on mouseenter:
let lastHovered = null;
const onHover = (event) => {
if (lastHovered != null) {
lastHovered.classList.remove('hovered');
}
event.target.classList.add('hovered');
lastHovered = event.target;
}
for (const div of document.getElementsByClassName('hoverable')) {
div.onmouseenter = onHover;
}
Here's an example: https://codepen.io/minism/pen/PooRKqx
I wouldn't use the :hover pseudo-class. Instead, define a class and toggle it with the mouseover event.
var elArray = document.querySelectorAll('.hoverme');
elArray.forEach(function(el) {
el.addEventListener('mouseover', function() {
elArray.forEach(function(el) {
el.classList.remove('hovered');
});
this.classList.add('hovered');
});
});
Working example: https://codepen.io/peiche/pen/wvvmqGZ
Related
My goal is to have text change onmouseover from "hello" (without a link) to "Google" and provide an 'href' on the resulting "Google" text, and then revert to "hello" onmouseout without a link.
The code below works in changing the text from "hello" to "Google" but,
the link on "Google" does not work (even though I can right-click on "Google" and open the link on another tab)
the text does not change back to "hello" onmouseout.
Thanks for your help in advance!
Here is my code:
<style>
.container {
margin-top: 6vw;
margin-left: 40%;
margin-right: 40%;
}
</style>
<div class="container">
<h1>
<div class="hello" id="hello1" onmouseover="changeText()" onmouseout="changeText(this,'Hello.')">Hello.</div>
</h1>
</div>
<script>
function changeText() {
if (document.getElementById("hello1")) {
a = document.getElementById("hello1")
a.innerHTML = 'Google'
}
}
</script>
try this way onmouseout="this.innerHTML='Hello.';"
function changeText() {
if (document.getElementById("hello1")) {
a = document.getElementById("hello1")
a.innerHTML = 'Google'
}
}
.container {
margin-top: 6vw;
margin-left: 40%;
margin-right: 40%;
}
<div class="container">
<h1>
<div class="hello" id="hello1" onmouseover="changeText()" onmouseout="this.innerHTML='Hello.';">Hello.</div>
</h1>
</div>
By changing a class of a parent tag, any and all child tags can be affected via CSS. Having the HTML ready when the page loads and then hiding it is better than constantly creating and destroying HTML for trivial effects.
The events "mouseenter" and "mouselrave" are handled by a property event handler and an event listener. Either one is sufficient, but avoid using attribute event handlers:
<div onmouselame="lameAttributeEventHandler()">...</div>
Details are commented in the example below
// Reference the <header>
const hdr = document.querySelector('.title');
/* This is a property event handler
// Whenever the mouse enters within the borders of
// the <header>:
// '.google' class is added
// '.hello' class is removed
*/
hdr.onmouseenter = function(event) {
this.classList.add('google');
this.classList.remove('hello');
};
/* This is an even listener
// Whenever the mouse exits the <header> the
// opposite behavior of the previous handler
// happens
*/
hdr.addEventListener("mouseleave", function(event) {
this.classList.add('hello');
this.classList.remove('google');
});
.title {
height: 50px;
margin-top: 3vh;
border: 3px solid black;
text-align: center;
}
h1 {
margin: auto 0;
}
.hello span {
display: inline-block;
}
.hello a {
display: none;
}
.google a {
display: inline-block;
}
.google span {
display: none;
}
<header class="title hello">
<h1>
<span>Hello</span>
Google
</h1>
</header>
You can try this, May it help u to solve the problem
<!DOCTYPE html>
<head>
<title>change text on mouse over and change back on mouse out
</title>
<style>
#box {
float: left;
width: 150px;
height: 150px;
margin-left: 20px;
margin-top: 20px;
padding: 15px;
border: 5px solid black;
}
</style>
</head>
<html>
<body>
<div id="box" onmouseover="changeText('Yes, this is Onmouseover Text')" onmouseout="changeback('any thing')" >
<div id="text-display" >
any thing
</div>
</div>
<script type="text/javascript">
function changeText(text)
{
var display = document.getElementById('text-display');
display.innerHTML = "";
display.innerHTML = text;
}
function changeback(text)
{
var display = document.getElementById('text-display');
display.innerHTML = "";
display.innerHTML = text;
}
</script>
</body>
</html>
Given example is working fine but red color is showing under Box2 only.
How to make sure if box1 is clicked then red should show below Box1,
if Box2 is clicked box should show below box 2.
CODEPEN
function hideshowmenu() {
var element = document.getElementsByClassName("box");
element[0].classList.toggle("bg-red");
}
.bg-red {
margin-top: 10px;
background-color: red;
height: 20px;
}
<div class="mainmenu " onclick="hideshowmenu()">BOX1</div>
<div id="box" class="box"></div>
<div class="mainmenu " onclick="hideshowmenu()">BOX2</div>
<div id="box" class="box"></div>
only one red should show at one time.
First, the box-id is duplicated, not allowed in HTML. Next, using Event Delegation makes your life easier. If you want the class of div.box after a clicked div.mainmenu element to be bg-red, the next snippet may be an idea (note: creates 100 div.mainmenu elements after the handler is assigned).
document.addEventListener(`click`, handle);
createSomeBoxes();
function handle(evt) {
if (evt.target.classList.contains(`mainmenu`)) {
//^ act only on div.mainmenu
const currentBox = document.querySelector(`.bg-red`);
currentBox && currentBox.classList.remove(`bg-red`);
return currentBox && currentBox.previousElementSibling === evt.target
? true : evt.target.nextElementSibling.classList.add(`bg-red`);
}
}
// for demo
function createSomeBoxes() {
let nBoxes = 0;
while(nBoxes++ < 100) {
document.body.insertAdjacentHTML(`beforeend`,
`<div class="mainmenu">BOX ${nBoxes}</div>
<div class="box"></div>`);
}
}
body {
margin: 2rem;
font: 12px/15px verdana, arial;
}
.mainmenu {
cursor: pointer;
}
.bg-red {
margin-top: 2px;
background-color: red;
height: 20px;
width: 20vw;
}
You only trigger [0]
I would delegate
I also removed ID since IDs need to be unique
const container = document.getElementById("container");
const boxes = container.querySelectorAll(".box")
container.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("mainmenu")) {
const thisBox = tgt.nextElementSibling;
boxes.forEach(box => {
if (box != thisBox) box.classList.remove("bg-red");
})
thisBox.classList.toggle("bg-red");
}
})
.bg-red {
margin-top: 10px;
background-color: red;
height: 20px;
}
<div id="container">
<div class="mainmenu">BOX1</div>
<div class="box"></div>
<div class="mainmenu">BOX2</div>
<div class="box"></div>
</div>
First remove the id's, you dont need them (and theyre not unique so they arent valid anyways).
Then youll need to iterate trough all your .mainmenu items and bin a click to hide all boxes and open the one right besides the item you clicked.
document.querySelectorAll(".mainmenu").forEach(function(menuElement) {
menuElement.addEventListener("click", function() {
document.querySelectorAll(".box").forEach(function(boxElement) {
boxElement.classList.remove("bg-red");
});
this.nextElementSibling.classList.toggle("bg-red");
});
});
.bg-red {
margin-top: 10px;
background-color: red;
height: 20px;
}
<div class="mainmenu">BOX1</div>
<div class="box"></div>
<div class="mainmenu">BOX2</div>
<div class="box"></div>
<div class="mainmenu">BOX3</div>
<div class="box"></div>
<div class="mainmenu">BOX4</div>
<div class="box"></div>
<div class="mainmenu">BOX5</div>
<div class="box"></div>
<div class="mainmenu">BOX6</div>
<div class="box"></div>
<div class="mainmenu">BOX7</div>
<div class="box"></div>
You should use event object to get a target node, and then append div with the class after it. The after function will move the div each time.
<div class="mainmenu" onClick="hideshowmenu(event)">BOX1</div>
<div class="mainmenu" onClick="hideshowmenu(event)">BOX2</div>
const redBox = document.createElement('div');
redBox.classList.add('bg-red');
function hideshowmenu(event) {
const elem = event.target;
elem.after(redBox)
}
https://jsfiddle.net/hj0rgkfp/
Essentially, I have multiple divs with the same class name (so like:
<div class = "tile"></div>
<div class = "tile"></div>
<div class = "tile"></div>
<div class = "tile"></div>
...
And I want to animate them in a way that the first div (for example) changes opacity to 0. However, if I just do
$('.tile').animate({opacity: 0});
or
$('.tile').velocity({opacity: 0});
They all change opacity to 0 at the same time. Is there a way to animate single tiles or queue their animations so the first changes, then the second, then the third, etc.?
You can achieve it by recursively applying the animation to the next DOM as below:
HTML
<div class = "tile"></div>
<div class = "tile"></div>
<div class = "tile"></div>
<div class = "tile"></div>
<style>
.tile {
width: 100px;
height: 100px;
background: yellow;
border: 1px solid blue;
}
</style>
JS
var counter = 0;
function makeTransparent($target) {
$target.eq(counter).animate({opacity: 0}, function(){
counter++;
if (counter < $target.length) {
makeTransparent($target);
}
});
}
makeTransparent($('.tile'));
Here is the live example: https://jsfiddle.net/uzf67L8c/
In case you were wondering about an only-jQuery method:
$('.tile').each(function(){
var $this = $(this),
$next = $this.prev();
$this.queue(function(){
$this.fadeOut(1500, function(){
$this.next().dequeue();
});
});
}).first().dequeue();
.tile {
width: 100px;
height: 100px;
background: yellow;
border: 1px solid blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
I have a click event binded to the body element but I don't want it to fire for when the user clicks on certain elements, that being when the element has an attribute of data-dropdown-target, however what I have tried isn't working, it always fires.
CodePen: http://codepen.io/anon/pen/ORQkrb
HTML:
<body>
<div class="foo">foo</div>
<div class="bar" data-dropdown-target="something">bar</div>
<div class="moo">moo</div>
</body>
CSS:
.foo, .bar, .moo {
padding: 10px;
margin: 5px;
}
.foo {
background-color: gray;
}
.bar {
background-color: teal;
}
.moo {
background-color: green;
}
JS:
$('body').not('[data-dropdown-target]').on('click', function(e) {
console.log('Hi!');
});
I assume this is because it is trying to remove body elements that have this attribute, rather than it's children - correct?
How do I go about stopping it from firing on children elements that have this attribute - do I have to loop through everything, as I would like to avoid that because of performance reasons, especially since it's on the body.
Actually your code try to bind event click on every <body> without data-dropdown-target attribute.
This could solve your problem :
$('body').on('click', function(e) {
if($(e.target).data('dropdown-target') || $(e.target).parents('[data-dropdown-target]').length !== 0) return false;
console.log('Hi!');
});
.foo, .bar, .moo {
padding: 10px;
margin: 5px;
}
.foo {
background-color: gray;
}
.bar {
background-color: teal;
}
.moo {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="foo">foo</div>
<div class="bar" data-dropdown-target="something">bar</div>
<div data-dropdown-target="something">
<div class="moo">moo</div>
</div>
</body>
The not selector just remove the body element if it has [data-dropdown-target] attribute.
Remove elements from the set of matched elements.
$('body').on('click', function(e) {
console.log('Hi!');
});
$('[data-dropdown-target]').on('click',function(e){
return false;
});
Let me explain it in a few words.
I have a menu with different colored buttons. For example When I mouseover/click button A (=blue e.g.) I want the bgcolor of the div also turning blue.
When I mouseover/click button B (=green) I want the bgcolor of the div also turning green.
Is there a possibility to this with a simple script?
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("button").hover(function () {
$(this).parents("navigatie").css("background-color", $(this).css("background-color"));
},
function () {
$(this).parents("navigatie").css("background-color", "white");
});
});
</script>
</head>
<body>
<div id="container">
<?php include("header.php");?>
<div id="navigatie">
<center>
<button class="A">Button A</button>
<button class="B">Button B</button>
</center>
</div>
<div id="tekst">
BLABLABLA
</div>
</div>
</body>
</html>
/* CSS */
navigatie {
width:100%;
height:100%;
transition:all 0.4s ease;
}
button {
width:75px;
height:50px;
border-style:none;
top: 20px;
position: relative;
color:white;
border: solid 1px white;
}
.A {
background-color:blue;
}
.B {
width: 200px;
height: 100px;
background-color:limegreen;
}
Use this for start you can enhance this with your own coding logic.
$('input:button').each(function() {
var color = $(this).attr("data-color");
$(this).css("background-color", color);
});
$('input:button').click(function() {
var color = $(this).attr("data-color")
$('#wrapper').css("background-color", color);
});
#wrapper {
padding: 50px;
background-color: #d0e4fe;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<input type="button" name="color" data-color="red" value="Red">
<input type="button" name="color" data-color="green" value="Green">
<input type="button" name="color" data-color="purple" value="Purple">
<input type="button" name="color" data-color="#d0e4fe" value="Default">
</div>
This is how I would do it:
$("button").hover(function () {
$(this).parents("div").css("background-color", $(this).css("background-color"));
},
function () {
$(this).parents("div").css("background-color", "white");
});
Here is the JSFiddle demo
Full code after fix as per what you provided in your edit:
<html>
<head>
<style>
navigatie {
width:100%;
height:100%;
transition:all 0.4s ease;
}
button {
width:75px;
height:50px;
border-style:none;
top: 20px;
position: relative;
color:white;
border: solid 1px white;
}
.A {
background-color:blue;
}
.B {
width: 200px;
height: 100px;
background-color:limegreen;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("button").hover(function () {
$(this).parents("#navigatie").css("background-color", $(this).css("background-color"));
},
function () {
$(this).parents("#navigatie").css("background-color", "white");
});
});
</script>
</head>
<body>
<div id="container">
<?php include("header.php");?>
<div id="navigatie">
<center>
<button class="A">Button A</button>
<button class="B">Button B</button>
</center>
</div>
<div id="tekst">
BLABLABLA
</div>
</div>
</body>
</html>
Try using jquery:
$("#[id]").hover(function({
$("#[id]").css({"[propertyname]":"[value]","[propertyname]":"[value]",...});
/*
Fill the brackets with the correct ids / classes and property names and values.
If you want to change the background on a click then replace .hover with .click
*/
If anyone finds something I did wrong or if there is a better way to do it, please correct me or let me know! I'm always open to better ideas! :)
If you're going to use CSS, there's only two ways of changing the style of an element through the state of another:
The targeted element must either be a child of the element receiving a state change, or a direct sibling (right underneath).
Using CSS's "+" selector, you can affect the next sibling element.
In your case this could be used to achieve this effect:
https://jsfiddle.net/Lrptjoh9/
The action occurs here:
.a .button:hover + .bg {
background: red;
}
.b .button:hover + .bg {
background: blue;
}
Although this requires the button and background elements to be siblings.
Vanilla JavaScript:
var btn = document.getElementById('btnA');
btn.addEventListener('click', function(e) {
var event = e || window.event,
target = event.target,
parent = target.parentNode,
color = parent.style.backgroundColor;
if(color === 'blue') {
parent.style.backgroundColor = 'white';
} else {
parent.style.backgroundColor = 'blue';
}
});
btn.addEventListener('mouseover', function(e) {
var event = e || window.event,
target = event.target,
parent = target.parentNode;
parent.style.backgroundColor = 'blue';
});
btn.addEventListener('mouseout', function(e) {
var event = e || window.event,
target = event.target,
parent = target.parentNode;
parent.style.backgroundColor = 'white';
});
.container{
position: relative;
width: 200px;
height: 100px;
text-align: center;
}
.container button{
position: relative;
top: 50%;
transform: translateY(-50%);
}
<div class='container'>
<button id="btnA">Button A</button>
</div>