onmouseover function working, but onmouseout function is not? - javascript

right now I'm trying to make an overlay div appear when another element is hovered over, and I'm doing this with the onmouseout and onmouseover properties. In the element that is originally displayed, I have an h1 with a unique item code, and an image of the item. I also have another div that is set to display: none by default, with an id that is the code corresponding to the item. I want this div to show up on hover, and disappear when the mouse is moved away.
In the HTML code, I'm specifying functions to run on mouseover and mouseout, then in the Javascript for those functions, I'm first getting the h1 and its unique item code, then selecting the hidden div with the id as the item code to show or hide. The only difference between my show and hide functions is style.display since it is either 'block' or 'none'. The show function works perfectly, and the hidden div shows up. However, when I move my mouse out, the div isn't disappearing like its supposed to. Can someone help me figure out as to why?
function showstatus(object) {
code = object.querySelector('h1').innerHTML;
document.querySelector(`#${code}`).style.display = "block";
}
function normalize(object) {
code = object.querySelector('h1').innerHTML;
document.querySelector(`#${code}`).style.display = "none";
}
{% for listing, specs in a_dict %}
<div class="list-item" onmouseover="showstatus(this)" onmouseout="normalize(this)">
<h1 class="hidden">{{listing}}</h1>
<img src="image link that I didn't include" class="item-thumbnail">
</div>
{% endfor %}

Use onmouseleave instead of onmouseover as you are using it on a div.
function showstatus(object) {
code = object.querySelector('h1').innerHTML
document.querySelector(`#${code}`).style.display="block";
}
function normalize(object) {
code = object.querySelector('h1').innerHTML
document.querySelector(`#${code}`).style.display="none";
}
<div class="list-item" onmouseover="showstatus(this)" onmouseleave="normalize(this)">
<h1 class="hidden">{{listing}}</h1>
<img src="image link that I didn't include" class="item-thumbnail">
</div>
This is an alternate method of doing so:
document.getElementById('div').onmouseover = showstatus(document.getElementById('div'))
document.getElementById('div').onmouseout = normalize(document.getElementById('div'))
function showstatus(object) {
code = object.querySelector('h1').innerHTML
document.querySelector(`#${code}`).style.display="block";
}
function normalize(object) {
code = object.querySelector('h1').innerHTML
document.querySelector(`#${code}`).style.display="none";
}
<div id="div" class="list-item">
<h1 class="hidden">{{listing}}</h1>
<img src="image link that I didn't include" class="item-thumbnail">
</div>

Related

How to show a div element on mouse hover?

I need to show a div when a list element is hovered over, sort of like a drop-down menu.
I already have a way to do this with jQuery which is what I want, but the problem is that when I move mouse away from the list (li element), the div disappears. I want to be able to move the mouse from the list element to the div and be able to interact with the elements within the div.
This would be solved with a click function but I don't want to use click because the elements on the div will contain anchor links that when click will take users down the page, therefore you can see how a click function that shows and keep the div is not a good idea, unless I can find a way to close the div when its contents (anchor links) are clicked.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
.nav-item-dropdown {
position: absolute;
/* other styles ... */
}
</style>
<div class="nav-wrap">
<ul>
<li id="nav-item1" class="nav-item-wrap">Services</li>
<li id="nav-item2" class="nav-item-wrap">Projects</li>
</ul>
</div>
<div class="nav-item-dropdown nav-item1-dropdown">
<!-- Drop-down nav contents for services (title and image) wrapped by anchor link goes here -->
</div>
<script>
$(document).ready(function() {
jQuery('#nav-item1').hover(function() {
$('.nav-item1-dropdown').toggle();
});
jQuery('#nav-item2').hover(function() {
$('.nav-item2-dropdown').toggle();
});
});
</script>
I want to be able to move the mouse from the list element (.nav-item-wrap) to the div (.nav-item-dropdown) and be able to interact with the elements within the div. I don't want the div to disappear when I move the mouse away from the list element that triggered it.
.toggle() method simply toggles the visibility of elements. In your code they do well what they are for. In your case, instead of toggle use .show() and .hide() like below. You need additional class to hide div when load.
$(document).ready(function() {
jQuery('#nav-item1').hover(function() {
$('.nav-item1-dropdown').show();
$('.nav-item2-dropdown').hide();
});
jQuery('#nav-item2').hover(function() {
$('.nav-item2-dropdown').show();
$('.nav-item1-dropdown').hide();
});
});
.nav-item-dropdown {
position: absolute;
/* other styles ... */
}
.yourClass {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav-wrap">
<ul>
<li id="nav-item1" class="nav-item-wrap">Services</li>
<li id="nav-item2" class="nav-item-wrap">Projects</li>
</ul>
</div>
<div class="nav-item-dropdown nav-item1-dropdown yourClass">
div1
<!-- Drop-down nav contents for services (title and image) wrapped by anchor link goes here -->
</div>
<div class="nav-item-dropdown nav-item2-dropdown yourClass">
div2
<!-- Drop-down nav contents for services (title and image) wrapped by anchor link goes here -->
</div>
Try this:
$(document).ready(function(){
jQuery('#nav-item1').mouseover(function() {
$('.nav-item1-dropdown').show();
});
jQuery('#nav-item2').mouseover(function() {
$('.nav-item2-dropdown').show();
});
});
I think you can use something like this for showing and hiding the div
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<div class="nav-wrap">
<ul>
<li id="nav-item1" class="nav-item-wrap">Services</li>
<li id="nav-item2" class="nav-item-wrap">Projects</li>
</ul>
</div>
<div class="nav-item-dropdown nav-item1-dropdown" style="display:none">
<p>your action goes here</p>
</div>
<script>
$(document).ready(function() {
jQuery('.nav-wrap').hover(function() {
$('.nav-item1-dropdown').show();
});
$('.nav-item1-dropdown').hide(); //use it wherever you need to hide it
});
</script>

Displaying a block on mouseover inline

I want to display a <div> block when mouse enters an element
My code so far:
<div class="dropdown">
MEN
<div class="dropdowncontent" id="ddmen" style="margin-left:100px;">
TOPWEAR <br/>
BOTTOMWEAR </br>
FOOTWEAR
</div>
</div>
JavaScript Code:
var ddm=document.getElementById("ddmen")
function ddmenin()
{
ddm.style.display="block";
}
function ddmenout()
{
ddm.style.display="none";
}
But when i hover over <a href="#men"> I cannot click on the links in the <div> with class="dropdowncontent" as the block disappears when i leave the <a href="#men">
I don't understand why this is happening since i have used onmouseover, which is valid even for child elements.
I have tried doing it using css but for some reason the following does not work (Style.css is used in above html)
STYLE.CSS
.dropdowncontent{
display:none;
}
.dropdown:hover .dropdowncontent{display:block;}
Can someone please correct my code to satisfy my needs or has any other simple alternative?
Well, your div link container is not part of a link, so when you move cursor to dropdown menu you leave the link and onmouseout listener does its job.
What you want is to hide the menu when it's not needed anymore. E.g. you clicked on the menu item or you left the menu and didn't return for some time.
To achieve this you can do the following:
Add hiding the menu to click listener on menu items
Add a function that starts some timer as soon as you leave the dropdown button or the menu (so that makes two onmouseout listeners). If you return there, you can reset the timer in onmouseover. When timer is done you can hide the menu.
It can look like this:
const $ = document.querySelector;
let menuTimeoutId;
const menu = $('#ddmen');
function stopMenuTimeoutAndShowMenu() {
if (menuTimeoutId) {
clearTimeout(menuTimeoutId);
menuTimeoutId = null;
}
menu.style.display = 'block';
}
function startMenuTimeout() {
window.menuTimeoutId = setTimeout(() => {
menu.style.display = 'none';
}, 2000); // possible timeout value
}
$('#men, #ddmen').addEventListener('onmouseover', stopMenuTimeoutAndShowMenu);
$('#men, #ddmen').addEventListener('onmouseout', startMenuTimeout);
I think you should use the onmouseover and onmouseout in your <div class="dropdown"> instead. Because, when you go to the div.dropdowncontent you probably invokes the onmouseout event. So the code will be like this:
<div class="dropdown" onmouseover="ddmenin()" onmouseout="ddmenout()">
MEN
<div class="dropdowncontent" id="ddmen" style="margin-left:100px;">
TOPWEAR <br/>
BOTTOMWEAR </br>
FOOTWEAR
</div>
</div>
See if it works ;D
You can try simple CSS changes, that can even help you :
In your Style.css file:
.dropdown .dropdowncontent {
visibility: hidden;
}
.dropdown:hover .dropdowncontent {
visibility: visible;
}

Show/ hide multiple divs with closing function

I almost give up. Can't find any solution on this so I hope you can help me. I have a script that shows/hides divs and it's working like this. If you click one button a div shows and if you press another button it switches to that div. That's working great. But I want to be able to close all divs with the last button clicked.
This is my HTML
<div class="hidden-divs-buttons">
<a class="show-div btn" target="1">Div 1</a>
<a class="show-div btn" target="2">Div 2</a>
</div>
<div class="hidden-divs">
<div id="div1" class="target-div">Content div 1</div>
<div id="div2" class="target-div">Content div 2</div>
</div>
This script works but has no closing functionality
$('.show-div').click(function() {
$('.target-div').hide();
$('#div' + $(this).attr('target')).fadeIn(1000);
});
And this is the script I want to replace the working script with. I have been trying to change it to work with closing function. I might be totally of but hopefully you guide in the right direction. I get an error that tell me "box.hasClass() isn't a function".
$('.show-div').click(function() {
var box = $('#div' + $(this).attr('target'));
$('.target-div').hide();
if(box.hasCLass('close-div')) {
box.removeClass('close-div');
$('.target-div').fadeOut(1000);
} else {
box.fadeIn(1000);
box.addClass('close-div');
}
});
Edit Id's are updated.
This is how the code became. With this code I can click on a button and show a div, click the next one to show another div. If I click the same button again it will close all divs.
$('.show-div').click(function() {
var box = $('#div' + $(this).attr('target'));
if(box.hasClass('close-div')) {
$('.target-div').removeClass('close-div');
$('.target-div').fadeOut(1000);
} else {
$('.target-div').removeClass('close-div');
$('.target-div').hide();
box.fadeIn(1000);
box.addClass('close-div');
}
});
You have typo in if(box.has[CL]ass('close-div')) {
hasClass not hasCLass
hasClass does not have a capital L - it's hasClass not hasCLass not sure if this is just a typo in the question or your real code.
Also both your divs in the hidden-divs section have the same id of div1, when they should presumably be div1 and div2. In any event it would be better to specify the full id of the div as the target instead of building it.
In addition, you are applying hide to all elements of class target-div before fading them out, which rather defeats the idea of a fadeout
<div class="hidden-divs-buttons">
<a class="show-div btn" target="div1">Div 1</a>
<a class="show-div btn" target="div2">Div 2</a>
</div>
<div class="hidden-divs">
<div id="div1" class="target-div">Content div 1</div>
<div id="div2" class="target-div">Content div 2</div>
</div>
$('.show-div').click(function() {
var box = $('#' + $(this).attr('target'));
// this makes them invisible, so fadeOut is pointless
$('.target-div').hide();
if(box.hasClass('close-div')) {
box.removeClass('close-div');
$('.target-div').fadeOut(1000);
} else {
box.fadeIn(1000);
box.addClass('close-div');
}
});

Toggle visibility for multiple divs for navigation bar

Earlier, I did an assignment where I was supposed to write code in Javascript in order to toggle visibility for the submenus each belonging to their own topmenu in a navigation bar for a webpage. The visibility should be set to hidden by default and should be shown when a topmenu is clicked on. I know how to toggle visibility for ONE submenu belonging to a topmenu, but fail to make my code work for multiple elements. With help from here, I got my code to work. However, my teacher was not pleased over the fact that I used onclick in my HTML-code. So my question is now: How do I move all functionality to javascript, and thereby not use onclick in my HTML?
Note: Of course I gave it a try myself but I cannot make the pairing between header and div work correctly... By the pairing I mean that visibility of the div with the class "left_submenu_1" should be toggled when you click the topmenu "left_top1". Thus should the visibilily of the div with the class "left_submenu_2" be toggled when you click the topmenu "left_top2".
I guess I should start something like this:
var left_headings = document.getElementsByClassName("left_top");
for(var k = 0; k < left_headings.length; k++) {
??????
}
Earlier related question: Toggle visibility for multiple divs with one function: navigation bar
HTML
<a class="left_top" onclick = "toggle('.left_submenu_1')">Opinion</a><br>
<div class="left_submenu_1" style="display: none;">
<a class="left_sub1">Leaders</a><br>
<a class="left_sub1">Debates</a><br>
</div>
<br>
<a class="left_top" onclick = "toggle('.left_submenu_2')">Economy</a><br>
<div class="left_submenu_2" style="display: none;">
<a class="left_sub2">News</a><br>
<a class="left_sub2">Your Economy</a><br>
</div>
Javascript
function toggle(qs) {
var e = document.querySelector(qs);
e.style.display = e.style.display === 'block' ? 'none' : 'block';
}
Please note: We are NOT allowed to use jQuery or to give the topmenus id:s, as the idea is to use one general function to toggle the visibility.
EDIT: Changing the html was out of the question, updated answer.
Instead of using onclick to handle the event, assign the eventhandler via javascript, like this (Note that I added IDs to the elements in order to be able to select them properly):
jsfiddle: https://jsfiddle.net/pkptn4gf/
<a class="left_top">Opinion</a><br>
<div class="left_submenu_1" style="display: none;">
<a class="left_sub1">Leaders</a><br>
<a class="left_sub1">Debates</a><br>
</div>
<br>
<a class="left_top">Economy</a><br>
<div class="left_submenu_2" style="display: none;">
<a class="left_sub2">News</a><br>
<a class="left_sub2">Your Economy</a><br>
</div>
function toggle(qs) {
var e = document.querySelector(qs);
e.style.display = e.style.display === 'block' ? 'none' : 'block';
}
var clickables = document.getElementsByClassName("left_top");
clickables[0].addEventListener("click", function(){
toggle('.left_submenu_1');
});
clickables[1].addEventListener("click", function(){
toggle('.left_submenu_2');
});

SlideToggle animation breaks with image and text

I'm trying to get a slidetoggle to work properly on a div. I have html in the following format:
<div class="root-div first-service">
<div class="title-div gradient">
<div class="title-div-left">
<p>$ServiceName</p>
</div>
<div class="title-div-right">
<p>▲</p>
</div>
</div>
<div class="description-div show minimum-height">
<div class="description-content-div">
$ServiceDescription
</div>
</div>
<div class="services-image-two">
<img src="themes/theinneryou/images/ServicesImage2.jpg" alt="Missing Image"/>
</div>
</div>
I also have javascript as follows:
$('.title-div').on('click', function () {
var arrow = $(this).find('.title-div-right');
if (proceed) {
proceed = false;
$(this).closest('.root-div').find('.services-image-two').slideToggle("slow");
$(this).closest('.root-div')
.find('.description-div')
.slideToggle("slow", function () {
$(arrow).text().trim().charCodeAt(0) == 9650 ? $(arrow).html('<p>▼</p>') : $(arrow).html('<p>▲</p>');
proceed = true;
});
}
});
The effect that I get is that the image itself plays the animation of slide and then gets hidden, then the rest of the next div which contains text only gets hidden without any animation. The image is overlapping the text div as I have it under absolute positioning. You can see the live demo at tiu.azularis.com/Services
Is there a way to make them gracefuly slide together when I click the arrow and then appear together when I click the down arrow?
I also tried moving the image div inside the description div and also tried setting .delay after first animation, but neither does the trick.
Change line 83 in Services.css:
.services-wrapper .expansion-wrap .first-service .minimum-height {
/* min-height: 20.4rem; */
height: 20.4rem;
}
min-height is messing it up.
Otherwise you have to fix your HTML + CSS for that whole section because it is not ideal.

Categories