mouseover on an img, but mouseout on a div - javascript

I have a little problems with mouseover and mouseout
I want to use mouseover when the user put his mouse in the image (id = calendrieragenda), but mouseout only when he leave the parent div (id = divagenda), but it's don't work, when the user leave his mouse from the image, it's activate the function mouseout
var divagenda = document.getElementById('divagenda');
var calendrieragenda = document.getElementById('imageagenda');
calendrieragenda.addEventListener('mouseover', function() {
document.getElementById('divagenda').className = 'popUpAgendaMouseOver';
});
divagenda.addEventListener('mouseout', function() {
document.getElementById('divagenda').className = 'popUpAgendaMouseOut';
});
#divagenda {
margin-top: 1em;
}
#imageagenda {
width: 8%;
position: relative;
right: 6%;
margin-top: 1em;
margin-bottom: 1em;
transition-duration: 0.5s;
transform: translateX(-50%);
left: 50%;
z-index: 600;
}
.popUpAgendaMouseOver {
border-radius : 1em;
border : 1px rgba(250, 250, 250, .8) solid;
background-color: #444444;
transition: 1s;
}
.popUpAgendaMouseOut {
border : none;
background-color:none;
transition: 1s;
}
<div id="divagenda">
<a href="link" title="Lien vers l'Agenda" target="_blank">
<img id="imageagenda" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRSf_HZLgiKNGwWv6V9Urtv3P2Sfo_Liw2dwOnq_oXg6-WInr_s" />
</a>
</div>
I do a jsfiddle to show you my code : https://jsfiddle.net/v7pkhymm/7/
Thank you very much and have a nice day !

The problem you're having is that your event is bubbling from the img up so the div will also receive that event.
There are a couple way to prevent this. You could add an event listener at the calendrieragenda level to stopPropagation:
calendrieragenda.addEventListener('mouseout', function(event) {
event.stopPropagation();
});
Or you could check on the divagenda event listener that the target of the event is really the div:
divagenda.addEventListener('mouseout', function(event) {
if (event.target !== this) {
return;
}
document.getElementById('divagenda').className = 'popUpAgendaMouseOut';
});
I would prefer the second method as it does not create an unnecessary event listener.

A better approach is to use mouseleave to avoid the bubble.
Suggestions
Use the classList collection to add and remove classes.
Use the already found element divagenda to avoid repeated getElementById calls.
var divagenda = document.getElementById('divagenda');
var calendrieragenda = document.getElementById('imageagenda');
calendrieragenda.addEventListener('mouseover', function() {
divagenda.classList.add('popUpAgendaMouseOver');
});
divagenda.addEventListener('mouseleave', function() {
this.classList.remove('popUpAgendaMouseOver');
this.classList.add('popUpAgendaMouseOut');
});
#divagenda {
margin-top: 1em;
}
#imageagenda {
width: 8%;
position: relative;
right: 6%;
margin-top: 1em;
margin-bottom: 1em;
transition-duration: 0.5s;
transform: translateX(-50%);
left: 50%;
z-index: 600;
}
.popUpAgendaMouseOver {
border-radius : 1em;
border : 1px rgba(250, 250, 250, .8) solid;
background-color: #444444;
transition: 1s;
}
.popUpAgendaMouseOut {
border : none;
background-color:none;
transition: 1s;
}
<div id="divagenda">
<a href="link" title="Lien vers l'Agenda" target="_blank">
<img id="imageagenda" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRSf_HZLgiKNGwWv6V9Urtv3P2Sfo_Liw2dwOnq_oXg6-WInr_s" />
</a>
</div>
Resource
mouseleave

Related

How to disable background scroll on pop-up?

I'm new to the web development world and wanted to know if there is a way to disable background scrolling.
I've tried z-index for the pop-up to display above all the elements, but some background content was getting overlapped with the pop-up.
I'm not much familiar with JS but was not able to get any help.
Below please find my code
body {
height: 200vh;
}
.bg-noscroll {
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
transition: opacity 500ms;
visibility: hidden;
opacity: 0;
}
.overlay:target {
visibility: visible;
opacity: 1;
}
.popup {
transform: translateY(-60px);
margin: 70px auto;
padding: 20px;
background: #fff;
border-radius: 5px;
width: 30%;
position: relative;
transition: all 5s ease-in-out;
}
.popup .close {
position: absolute;
top: 20px;
right: 30px;
transition: all 200ms;
font-size: 30px;
font-weight: bold;
text-decoration: none;
color: #333;
}
.content {
height: 250px;
}
.popup .content {
overflow-y: scroll;
}
#media screen and (max-width: 700px){
.popup{
width: 70%;
}
<body class="bg-noscroll bg-scroll">
<span><a class="popupBG-Disable" href="#popup">Full Recipe</a></span>
<div id="popup" class="overlay">
<div class="popup">
<h3>Foxtail Millet Porridge:</h3>
<a class="close" href="#">×</a>
<div class="content">
<span>Ingredients:<br>here are some things that you'd use to make this<br> isn't this amazing?<br>Yes, it is!<br>
this is getting loooooong<br>this will take me a while!<br>oh... yes it will<br>we're getting close<br>and we should be there <br>or not...<br>Im losing hope<br>and patience<br>with how long this is taking<br>I could really cry<br>
but we'll get there soon<br>safe and sound<br>free as pie<br>I dont know what I meant by that<br>
this is taking long mannnn<br>
</span>
Thank you for your help!
I have a live codepen with your original code so you can just copy and paste if you wish.
Using Jquery, we can enable and disable overflow using some simple code:
const modal = document.querySelector("#btn");
const body = document.querySelector("body");
const showModal = function (e) {
modal.classList.toggle("hidden");
if (!modal.classList.contains("hidden")) {
body.style.overflow = "hidden";
} else {
body.style.overflow = "hidden";
}
}; // just reversed for re-enabling scroll, as seen in the codepen
Currently, you have to make use of javascript and add or remove the scrollbar-properties or css-class using a hashchange event-listener for example:
window.addEventListener("hashchange", event => {
const newHash = new URL(event.newURL).hash,
el = document.getElementById(newHash.substr(1));
if (el && el.classList && el.classList.contains("overlay")) {
document.body.style.overflow = "hidden";
// or document.body.classList.add("bg-noscroll");
} else {
document.body.style.overflow = "";
// or document.body.classList.remove("bg-noscroll");
}
});
Starting from chromium 101 the support for the :has()-selector has been implemented (experimental flag only) and the current chromium 105 dev channel brings the :has()-selector enabled by default.
With the has()-selector it will be possible using:
body:has(.overlay:target) {
overflow: hidden;
}
Keep also mind, it may take some more time for other browsers to implement the has()-selector. Therefor the best would be to stick with the javascript method for a while.

how to transform button after hover again when muosedown and release

I've a button with transform: none; when I active that button the transform changed to transform: scale(0.9);. that's clear.
What I do? I want to change transform to 0 when hover out that button, but transform again when I hover again that button to 0.9.
Screen1: I don't want that one:
Screen2: I want that one:
My Code:
button{
width: 180px;
height: 80px;
outline: none;
border: none;
font-size: 18px;
color: white;
cursor: pointer;
font-weight: bold;
transform: none;
background-color: #3a3b3c;
}
button:active{
transform: scale(0.9);
}
<button>Filters</button>
Does this gonna make you happy? 🧐 <3 jQuery!
First we gonna check if the button is clicked or not. And if clicked, change the var so we know it's has changed.
var isclicked = false; $('button').click(function(e){ isclicked = true; });
Then the .mouseout function, because you want the change to only take place when the mouse leaves the button. If I understand your question correctly. And only when the button is clicked. Therefor that previous click check. Last, .addClass function so we can style to the desired behavior.
$('button').mouseout(function(e){ if(isclicked == true) { $('button').addClass('activated'); } });
&
button.activated:hover { transform: scale(0.9); }
Full code snippet:
var isclicked = false;
$('button').click(function(e){
isclicked = true;
});
$('button').mouseout(function(e){
if(isclicked == true) {
$('button').addClass('activated');
}
});
button{
width: 180px;
height: 80px;
outline: none;
border: none;
font-size: 18px;
color: white;
cursor: pointer;
font-weight: bold;
transform: none;
transition:all 0.2s;
background-color: #3a3b3c;
}
button:active{
transform: scale(0.9);
}
button.activated:hover{
transform: scale(0.9);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Filters</button>
So I created two functions for you, hopefully this works for you! In your button tag just add a mouseout and mousedown to call both functions.
function mouseFunction() {
document.getElementById('filters').style.transform = "scale(1)";
}
function mouse2Function() {
document.getElementById('filters').style.transform = "scale(0.9)";
}
<button onmouseout = "mouseFunction();" onmousedown = "mouse2Function();"id = "filters">Filters</button>

Mouse stuck on Input?

I have no idea how to ask this question, but here's problem:
I have this kind of search bar ^ and when you double click on it it shrinks and input is disappearing (display: none). But when it disappears
And I-beam cursor shows. So I can't click or double click on it anymore (for some reason)
I tried input.blur(); but because it's not focused it didn't work. I have no clue what to google to fixed. I tried some but there weren't any related answers.
HTML:
<div class="search-field">
<input placeholder="Search" type="text">
<img src="search.svg" title="Double Click to toggle">
<img src="grip-lines.svg" alt="||" id="drag">
</div>
I use keyframes so I will how CSS too: (Edit: I will put more about css)
.search-field {
position: absolute;
width: 385px;
width: 20%;
background-color: #FFFFFF;
top: 15px;
left: 8%;
display: flex;
align-items: center;
justify-content: space-evenly;
padding: 5px;
border-radius: 10px;
border: 1px black solid;
}
input {
height: 80%;
width: 300px;
outline: none;
transition: .3s;
border-radius: 10px;
border: 1px black solid;
padding: 3px 5px;
background-color: #E4E9F7;
}
#keyframes openSearch {
0% {
width: 77px;
}
100% {
width: 385px;
}
}
#keyframes closeSearch {
0% {
width: 385px;
}
100% {
width: 77px;
}
}
.openedSearch {
animation: openSearch 0.5s both;
}
.closedSearch {
animation: closeSearch 0.5s both;
}
JS:
let searchState = true
let toggleSearchState = () => {
searchState = !searchState
if (searchState == true) {
searchField.className = 'search-field openedSearch'
input.style.display = 'block'
} else {
searchField.className = 'search-field closedSearch'
input.style.display = 'none'
}
}
searchBtn.addEventListener('dblclick', toggleSearchState)
Since everything seems to be working fine on this fiddle. The only thing left (that I couldn't test) is the SVG images and any code you attached to them.
As the id of the pipe image is drag, I am assuming you have attached a drag event on it. Also, if the size of the image is not set you may be overlapping, covering the entire search-field when the width is set too 77px.
An easy solution would be to set the height and width of the img tag with the draggable event, so you can be sure it is not overlapping.

How to undo an addEventListener?

I want to create an effect where if I hover over a certain element a paragraph element will be gradually displayed and vice versa (If the cursor is no longer hovering on the element the paragraph should gradually fade). I've already created the effect using pure CSS, but it was a bit cumbersome and it will only work if the paragraph is a direct child of the element I'm hovering on (which made it even more cumbersome). But here's how I created using CSS:
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
overflow: hidden;
}
.FlexContainerRow {
display: flex;
flex-direction: row;
justify-content: center;
z-index: 1;
}
.FlixItem_Images {
width: 50rem;
}
#CheiftianTwo {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
#welcome {
position: absolute;
z-index: 2;
font-family: Calibri;
font-weight: bold;
font-size: 2em;
text-align: center;
transition: background-color color linear;
transition-duration: 1s;
color: transparent;
background-color: transparent;
margin-left: 13.75em;
margin-top: 6.4em;
padding: 0.2em;
border-radius: 0.4em;
}
#divForLayers {
position: absolute;
z-index: 1;
}
#divForhover {
height: 33.5em;
width: 100rem;
position: absolute;
z-index: 3;
}
#divForhover:hover #welcome {
transition: background-color color linear;
color: white;
background-color: black;
transition-duration: 1s;
}
<header>
<div id="divForhover">
<div id="divForLayers">
<div id="HeaderImagesContainer" class="FlexContainerRow">
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianOne" />
</div>
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianTwo" />
</div>
</div>
</div>
<p id="welcome">Welcome to te Cheftian Mk.2 Main Battle Tank guide!</p>
</div>
</header>
<nav></nav>
<footer></footer>
But I've just learned that you can do the same thing with JavaScript and it will be much much simpler:
addEventListner('mouseover', function(evt) {
document.body.querySelector( /*ID_of_the_element*/ ).style.property = 'value';
})
The problem is that I only know how to to display the paragraph when the user hovers on the element, and that's it. If the cursor is no longer on the element, the paragraph will still be displayed. I don't know how to undo the addEventListener. I tried to do it with removeEventListener, but apparently I have the syntax wrong. Please tell me how to do it.
Here's the version with the JavaScript:
document.querySelector("#welcome").style.visibility = "hidden";
var imgOne = document.body.querySelector("#CheiftianOne");
imgOne.addEventListener('mouseover', function(evt) {
var textBox = document.querySelector("#welcome");
textBox.style.visibility = "visible";
});
imgOne.removeEventListener('mouseover', function(evt) {
var textBox = document.querySelector("#welcome");
textBox.style.visibility = "hidden";
});
* {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
overflow: hidden;
}
.FlexContainerRow {
display: flex;
flex-direction: row;
justify-content: center;
z-index: 1;
}
.FlixItem_Images {
width: 50rem;
}
#CheiftianTwo {
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
}
#welcome {
position: absolute;
z-index: 2;
font-family: Calibri;
font-weight: bold;
font-size: 2em;
text-align: center;
transition: background-color color linear;
transition-duration: 1s;
color: white;
background-color: black;
margin-left: 13.75em;
margin-top: 6.4em;
padding: 0.2em;
border-radius: 0.4em;
}
#divForLayers {
position: absolute;
z-index: 1;
}
<header>
<div id="divForhover">
<div id="divForLayers">
<div id="HeaderImagesContainer" class="FlexContainerRow">
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianOne" />
</div>
<div>
<img src="https://www.nexusindustrialmemory.com/wp-content/uploads/2017/04/OriginalTank.jpg" class="FlixItem_Images" id="CheiftianTwo" />
</div>
</div>
</div>
<p id="welcome">Welcome to te Cheftian Mk.2 Main Battle Tank guide!</p>
</div>
</header>
<nav></nav>
<footer></footer>
Assign the event handler function to a variable, or give it a proper name. Then add and remove that.
Your removeEventListener call is failing because you're passing it a unique function.
Also, you actually don't want to undo the event listener to achieve the effect you want. Instead, listen to separate events: mouseover and mouseout. For example:
var btn = document.getElementById('btn');
var par = document.getElementById('par');
btn.addEventListener('mouseover', function (e) {
par.style.visibility = 'visible';
});
btn.addEventListener('mouseout', function (e) {
par.style.visibility = 'hidden';
});
<button id="btn">Hover over me</button>
<p id="par" style="visibility: hidden;">This shows when hovering over the button</p>
The mouseover event occurs when the mouse hovers over an element, and conversely the mouseout event occurs when the mouse leaves the element.
When you call removeEventListener, you have to pass it the same function you passed addEventListener, not a different-but-equivalent one. This will never remove a listener:
imgOne.removeEventListener('mouseover', function (evt) { /* ... */ });
...because by definition, that exact function wasn't ever added previously.
Remember the one you used when adding, and use that same one when removing.
Separately: Adding the handler and then immediately removing it doesn't make a lot of sense. Nothing can happen that will trigger the handler between the calls to addEventListener and removeEventListener in your code. (Edit: Ah, rossipedia has picked up on why you did that, and his answer tells you want to do instead.)
Thanks, everyone. I figured out how to do it without a removeEventListener. (I used two addEventListener).
Thanks, again!

JQuery click event not working properly with an <i> element

<button type="button" class="add-to-cart"><i class="material-icons">add_shopping_cart</i>cumpara</button>
<button class="added add-to-cart"><i class="material-icons check">check</i><i class="material-icons clear">clear</i>Adaugat in cos</button>
I have these two buttons with this CSS code:
.add-to-cart
{
position: relative;
overflow: hidden;
line-height: em(48);
background: complement($rodie);
border: none;
color: $gray-100;
text-transform: uppercase;
height: em(48);
width: 100%;
font-size: em(18);
display: inline-block;
transition: all 250ms ease-out;
&.clicked
{
transform: translateX(-100%);
}
&:hover
{
background: complement(darken($rodie, 10%));
}
i
{
position: absolute;
right: 0;
top: 0;
font-size: em(18);
height: em(48);
width: em(48);
line-height: em(44);
}
}
.added
{
position: absolute;
right: -100%;
top: 90%;
z-index: 22;
background: $verde-jungla;
&:hover
{
background: $verde-jungla;
}
&.clicked
{
transform: translateX(-100%);
}
.check
{
left: 0;
}
}
.clear
{
transition: all 100ms ease-in-out;
height: em(48);
width: em(48);
right: 0;
background: desaturate(red, 30%);
&:hover
{
background: desaturate(darken(red, 10%), 30%);
}
}
I want the button to respond to a click event by transitioning the second button, which has an icon and a message (that informs the user that the product has been added to the cart) attached to it. The first transition works. When I click on the button, the other one appears as it's supposed to, but when the clear "button" (the <i> with the class of clear) is pressed, it's not working.
This is the JQuery code:
$('.add-to-cart').click(function(){
$('.add-to-cart').addClass("clicked");
});
$('.clear').click(function(){
event.preventDefault();
$('.add-to-cart').removeClass("clicked");
});
Keep in mind that if I change the selected element of the second click event, the process works just fine.
Having the .clear button inside an .add-to-cart is asking for problems.
When you click .clear, at the same time you click .add-to-cart.
You did add event.preventDefault, but you don't just want to prevent the default. You also need to prevent the event from "bubbling" up.
Also, the variable event does not exist, you need to add it as the name of the first argument.
Try:
$('.clear').click(function(event){
event.stopPropagation();// Stop bubbling up
event.preventDefault();
$('.add-to-cart').removeClass("clicked");
});
But a far better solution would be to move .clear outside of the button that has .add-to-car.
<button type="button" class="add-to-cart"><i class="material-icons">add_shopping_cart</i>cumpara</button>
<button class="added add-to-cart"><i class="material-icons check">check</i><i class="material-icons clear" style=" padding: 0 10px;">clear</i>Adaugat in cos</button>
$('.add-to-cart').click(function(){
$('.add-to-cart').addClass("clicked");
});
$('.clear').click(function(event){
event.stopPropagation();
event.preventDefault();
$('.add-to-cart').removeClass("clicked");
});

Categories