I am currently building a layout where I have several 'triggers' inside a <nav><ul><li><a> element - each display a <div> which effectively sits 'behind' (z-index).
I need the divs (#showme and #showmetoo) to stay visible even if the user moves the mouse from the respective trigger (.thetrigger, .thenextrigger) - as the divs will contain content/links.
Additionally, when the user moves from one trigger to the next the displayed div should change.
<header>
<nav>
<ul>
<li><a class="thetrigger">Show Me That Thing</a></li>
<li><a class="thenexttrigger">Show Me That Thing</a></li>
</ul>
</nav>
<div id="showme">Yay, this thing</div>
<div id="showmetoo">and this thing</div>
</header>
CSS
header {
width: 100%;
height: 300px;
position: relative;
background: red;
z-index: 1;
}
nav {
position: absolute;
top: 10px;
left: 30px;
z-index: 3;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
nav ul li {
float: left;
padding: 30px;
}
.thetrigger, .thenexttrigger {
color: white;
}
#showme {
display: none;
background: blue;
color: white;
position: absolute;
top: 0;
left: 0;
height: 300px;
width: 100%;
z-index: 2;
}
#showmetoo {
display: none;
background: green;
color: white;
position: absolute;
top: 0;
left: 0;
height: 300px;
width: 100%;
z-index: 2;
}
jQuery
$(document).ready(function() {
$('.thetrigger').hover(function() {
$('#showme').fadeIn();
}, function() {
$('#showme').fadeOut();
});
$('.thenexttrigger').hover(function() {
$('#showmetoo').fadeIn();
}, function() {
$('#showmetoo').fadeOut();
});
});
http://jsfiddle.net/richardblyth/24bcs/
Demo
It sounds like you want the div to remain until the next trigger is hovered over.
You can use a lot less jQuery if you use a class for the triggers, and find their respective divs using data. With this you can add as many triggers + corresponding divs as you like without having to write more jQuery.
HTML
<header>
<nav>
<ul>
<li><a class="trigger" data-show="pane1">Show Me That Thing</a></li>
<li><a class="trigger" data-show="pane2">Show Me That Thing</a></li>
</ul>
</nav>
<div class="pane" data-show="pane1" id="showme">Yay, this thing</div>
<div class="pane" data-show="pane2" id="showmetoo">and this thing</div>
</header>
jQuery
$(function(){
$('.trigger').on('mouseover', function(){
// show the desired pane and hide its siblings
$('.pane[data-show="' + $(this).data('show') + '"]').fadeIn().siblings('.pane').fadeOut();
});
});
I think what you actually want, if I understand you question, is to hide the other #showme element when you hover into the trigger element associated with the #showmetoo element.
Like this:
$(document).ready(function() {
$('.thetrigger').hover(function() {
$('#showme').fadeIn();
$('#showmetoo').fadeOut();
});
$('.thenexttrigger').hover(function() {
$('#showmetoo').fadeIn();
$('#showme').fadeOut();
});
});
http://jsfiddle.net/4N26S/
Related
Say a menu is triggered when a button is clicked, now
1_ For canceling it, the user has to be able to click anywhere on the page (not only on the same button),
2_ Everything else on the page must still remain selectable throughout this process.
Here's what I've tried:
$(".dad").click(function() {
$(".son").show();
$(".mask").show();
});
$(".mask").click(function() {
$(".son").hide();
$(".mask").hide();
});
.dad {
background: greenyellow;
width: 20px;
height: 20px;
margin-top: 100px;
z-index: 2;
}
.son {
position: relative;
left: 20px;
bottom: 100px;
width: 100px;
height: 100px;
display: none;
background: tomato;
z-index: 2;
}
p {
z-index: 2;
}
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: none;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js "></script>
<p>This is a paragraph</p>
<div class="dad">
<div class="son"></div>
</div>
<div class="uncle"></div>
<div class="mask"></div>
This code satisfies the first condition(the ".son" hides when anywhere on the page is clicked), but the second condition isn't met. Because when the ".son" is visible, the paragraph is not immediately selectable, unless the user does another click. Although this seems like a minor problem, sometimes it can become a little annoying, thus is a requirement. (I've also tried other ways. E.g. CSS "pointer-events: none" on the mask, but it has a different purpose, because it also cancels click events). So how could it be done? Thanks in advance.
Note: This is not solely a CSS question, I embrace any Javascript or Jquery answers too should they give easier/better solutions.
Hope it helpful...
$(".dad").click(function() {
$(".son").show();
});
$(document).click(function (e) {
var container = $(".dad");
if(!container.is(e.target) &&
container.has(e.target).length === 0) {
$(".son").hide();
}
});
.dad {
background: greenyellow;
width: 20px;
height: 20px;
margin-top: 100px;
z-index: 2;
}
.son {
position: relative;
left: 20px;
bottom: 100px;
width: 100px;
height: 100px;
display: none;
background: tomato;
z-index: 2;
}
p {
z-index: 2;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js "></script>
<p>This is a paragraph</p>
<div class="dad">
<div class="son"></div>
</div>
<div class="uncle"></div>
In a scenario like this one, I want to be able to click the background div (red) through the top div, whilst still being able to click the top div's children (blue and green).
function bgclick() {
console.log('Background Is Clicked!');
}
function topclick() {
console.log('Top Is Clicked!');
}
#background {
background-color: #f33;
width: 250px;
height: 250px;
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
#top {
width: 250px;
height: 250px;
position: fixed;
top: 0;
left: 0;
}
.children {
width: 50px;
height: 50px;
position: relative;
}
<div id="background" onclick="bgclick()"></div>
<div id="top">
<div class="children" onclick="topclick()" style="background-color:#3f3"></div>
<div class="children" onclick="topclick()" style="background-color:#33f"></div>
</div>
I have played around with pointer-events: none. This will only make one clickable and the other not. How can I make it so I can click the red one and get a message, along with the blue and green ones?
To make parent div unclickable but children clickable only use pointer-events.
pointer-events
The element is never the target of pointer events; however, pointer
events may target its descendant elements if those descendants have
pointer-events set to some other value. In these circumstances,
pointer events will trigger event listeners on this parent element as
appropriate on their way to/from the descendant during the event
capture/bubble phases.
More about how it works here pointer-events
.parent {
pointer-events: none;
}
.child {
pointer-events: auto;
}
You have to change the markup by nesting the #top container into the #background container.
And then simply pass the event to the topclick method and add event.stopPropagation() to it to make sure just the div on the very top gets clicked.
See the modified code:
function bgclick() {
console.log('Background Is Clicked!')
}
function topclick(event) {
event.stopPropagation();
console.log('Top Is Clicked!')
}
#background {
background-color: #f33;
width: 250px;
height: 250px;
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
#top {
width: 250px;
height: 250px;
position: fixed;
top: 0;
left: 0;
}
.children {
width: 50px;
height: 50px;
position: relative;
}
<div id="background" onclick="bgclick()">
<div id="top">
<div class="children" onclick="topclick(event)" style="background-color:#3f3"> </div>
<div class="children" onclick="topclick(event)" style="background-color:#33f"> </div>
</div>
</div>
I've found a easy way to get around this problem (op).
pointer-events:none; makes it so the mouse won't interact with the element. By default, pointer-events is inherited, so just set the children as pointer-events:auto;.
function bgclick() {
console.log('Background Is Clicked!');
}
function topclick() {
console.log('Top Is Clicked!');
}
#background {
background-color: #f33;
width: 250px;
height: 250px;
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
#top {
width: 250px;
height: 250px;
position: fixed;
top: 0;
left: 0;
pointer-events: none;
}
.children {
width: 50px;
height: 50px;
position: relative;
pointer-events: auto;
}
<div id="background" onclick="bgclick()"></div>
<div id="top">
<div class="children" onclick="topclick()" style="background-color:#3f3"></div>
<div class="children" onclick="topclick()" style="background-color:#33f"></div>
</div>
I have a problem with jQuery, I made a button to open/close the menu and it's work. But I want to allow the click of anywhere on the body to close the menu. So when we click outside the .burger I want to close the menu.
So I made this:
edit : this is my all code for menu
var count = 0;
function menu(){
$('.burger').click(function(){
if (count==0) {
$('.navigation').css({'display':'block', 'opacity':'1'});
count=1;
}else{
$('.navigation').css({'display':'none', 'opacity':'0'});
count=0;
}
});
}
menu();
if(count == 1){
$("body *:not(.burger)").click(function(event){
$('.navigation').css({'display':'none', 'opacity':'0'});
count=0;
});
}
But when I click on .burger, it shows the alert.
Like this, my menu appear and desappear when i click on .burger, but nothing work when I click outside of .burger
You're selecting all body tags that don't match div.burger. This will simply select the body tag (As it doesn't match div.burger).
To match all elements in body, that don't have the tag .burger, Try this instead:
$("body *:not(.burger)").click(function(){alert('ok');
$('.nav').css({"display":"none"});
});
Likewise, if you want to match ONLY DIVS that don't have the class .burger, use div:not(.burger) (You shouldn't even need body here, as a div should not appear outside of the <body> tag):
$("body *:not(.burger)").click(function(){
alert('matched body *:not(.burger)');
});
$("div:not(.burger)").click(function(){
alert('matched div:not(.burger)');
});
div
{
width: 50px;
height: 50px;
float: left;
background-color: orange;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="burger">Burger</div>
<div>Not a burger</div>
Instead of putting a binding on everything that is not the burger, I would use a delegate event binding that filters out events that bubble up.
$('.burger').on('click', function(e){
e.stopPropagation();
$('#menu').toggleClass('hide');
});
$(document.body).on('click', ':not(.burger)', function(e){
$('#menu').addClass('hide');
});
.burger {
display: inline-block;
background-color:lightblue;
}
.hide {
opacity: 0;
}
body {
background-color: gray;
min-width: 1920px;
min-height: 1080px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="burger">Burger icon</div>
<ul id="menu" class="hide">
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
</ul>
</div>
With function .not() you can accomplish that.
$(".body *").not("div.burger").click(function(){
$('.nav').css({"display":"none"});
});
.burger {
width: 200px;
height: 200px;
background-color: rgba(255,255,255, 1);
position: absolute;
top: 25px;
left: 30px;
z-index: 9999;
}
.body {
width: 100%;
height: 100%;
}
.nav {
width: 100%;
height: 100%;
background-color: rgba(0,0,0, .2);
position: absolute;
top: 0;
left: 0;
z-index: 999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="body">
<div class='burger'>
Burger div (Click and nothing happend)
</div>
<br><br><br>
<div class="nav">
Click this overlay div to hide it!
</div>
</div>
Hope it helps!
I have a short piece of JS which is supposed to show and hide the secondary navigation of a site. If a user clicks Menu Item A it shall show, they click it again and it hides and if Menu Item A is open and they click Menu Item B then it closes A and opens B in its place.
The first part of this works, I can click a single menu item and it will open and close, if however I click a different menu item whilst one is open then it shall close (as expected), open (as expected) and then close again. It's as if the event is being fired twice.
Here is my JS snippet.
$(document).ready(function() {
$('.NavButton').click(function(event) {
handleSecondaryNavigation(event.target.alt);
});
});
function handleSecondaryNavigation(MenuItem) {
if ($('#ul' + MenuItem).is(':visible')) {
// Menu item visible, hide it
$('#SecondaryNavigation').animate({
width: 'toggle'
}, 350, function() {
$('#ul' + MenuItem).hide();
});
} else if ($('#SecondaryNavigation').is(':visible')) {
// Clicked different menu item, hide then show (swap)
$('#SecondaryNavigation').animate({
width: 'toggle'
}, 350, function() {
$('#SecondaryNavigation ul').hide(function() {
handleSecondaryNavigation(MenuItem);
});
});
} else {
// Menu not visible, show it
$('#ul' + MenuItem).show(function() {
$('#SecondaryNavigation').animate({
width: 'toggle'
}, 350);
});
}
}
#MainNavigation {
background: #F1F1F1;
position: fixed;
top: 0px;
left: 0px;
bottom: 0px;
}
#MainNavigation .NavButton {
width: 20px;
display: block;
padding: 15px 20px;
cursor: pointer;
}
#SecondaryNavigation {
position: fixed;
top: 0px;
left: 60px;
bottom: 0px;
background: #DADADA;
width: 200px;
display: none;
box-shadow: 2px 0px 5px #686868;
}
#SecondaryNavigation ul {
display: none;
margin: 0px 10px;
}
#SecondaryNavigation ul li {
display: block;
padding: 10px;
border-bottom: 1px solid #CBCBCB;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="MainNavigation">
<img class="NavButton" alt="A" />
<img class="NavButton" alt="B" />
</nav>
<nav id="SecondaryNavigation">
<ul id="ulA">
<li>Lorem</li>
<li>Ipsum</li>
</ul>
<ul id="ulB">
<li>Lorem</li>
<li>Ipsum</li>
</ul>
</nav>
Swapping out the handleSecondaryNavigation(MenuItem) bit and hard coding the action installed of recursively also does not work.
Any ideas? I'm sure it's probably something silly...
Thanks
I have solved your issue and please find the working fiddle
This event listener is triggered twice each time for each ul element
$('#SecondaryNavigation ul').hide(function() {
console.log("hide trug");
handleSecondaryNavigation(MenuItem);
});
change this to
$('#SecondaryNavigation ul').hide(function() {
});
handleSecondaryNavigation(MenuItem);
I have updated the fiddle as well
Hope this helps
I am trying to create some options that are hidden unless the user goes with the mouse in a specific area. Let's take an example: Google+ profile page:
When you go with the mouse cursor on the picture, the button appears.
Here is what I tried:
var $button = $("#button");
$("#profile-picture").on("mouseover", function() {
$button.show();
}).on("mouseout", function() {
$button.hide();
});
#profile-picture {
width: 150px;
height: 100px;
}
#button {
position: absolute;
display: none;
width: 30px;
height: 30px;
top: 45px;
left: 70px;
opacity: 0.75;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="http://datastore01.rediff.com/h450-w670/thumb/69586A645B6D2A2E3131/ckez1n08svw8f3en.D.0.Sidharth-Malhotra-Student-of-the-Year-Photo.jpg" id="profile-picture">
<img src="http://img3.wikia.nocookie.net/__cb20090227194712/java/images/0/0e/Camera_icon.gif" id="button" />
The problem is that when I go with the cursor over the #button, it flickers. What can I do?
The easiest method is placing them both in the same div, and then using mouseover/out for that div. Example: http://jsfiddle.net/1g24mhhz/
HTML:
<div id="profile-picture">
<img src="http://datastore01.rediff.com/h450-w670/thumb/69586A645B6D2A2E3131/ckez1n08svw8f3en.D.0.Sidharth-Malhotra-Student-of-the-Year-Photo.jpg" class="profile">
<img src="http://img3.wikia.nocookie.net/__cb20090227194712/java/images/0/0e/Camera_icon.gif" id="button" />
</div>
CSS edits:
#profile-picture .profile {
width: 150px;
height: 100px;
}
EDIT: You should probably not use an ID for the div, since you probably have multiple profiles on a page. This was just to show it with the code you had already used.
A simple css approach. You can have a click event on the button :)
$('#button').on('click', function() {
alert('I am clickable');
});
#profile-picture,
.hover-wrap {
width: 150px;
height: 100px;
}
#button {
position: absolute;
display: none;
width: 30px;
height: 30px;
top: 0px;
left: 0px;
bottom: 0;
right: 0;
margin: auto;
opacity: 0.75;
cursor: pointer;
}
.hover-wrap {
position: relative;
}
.hover-wrap:hover #button {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="hover-wrap">
<img src="http://datastore01.rediff.com/h450-w670/thumb/69586A645B6D2A2E3131/ckez1n08svw8f3en.D.0.Sidharth-Malhotra-Student-of-the-Year-Photo.jpg" id="profile-picture">
<img src="http://img3.wikia.nocookie.net/__cb20090227194712/java/images/0/0e/Camera_icon.gif" id="button" />
</div>
You can use CSS:hover properties to show/hide the button, no Javascript needed.
The trick is a sibling selector:
#profile-picture:hover + #button, #button:hover{
display:block;
}
Try this:
http://jsfiddle.net/6s9200ab/