How create a transparent layer without restrict 'click', 'hover' and 'select' events? - javascript

In current Github website, there is a toggle ability to show/hide the profile menu. on the following screen-shot, there is a transparent layer with full width and height behind the menu and if for example I click on "Explore", my first click will trigger the onclick event on the transparent layer and it only will hide the menu and transparent layer itself. Then I need to click again on "Explore" to make action.
but in current stackoverflow website, there is similar toggle ability without above limitation and when the menu is open, I can act like a normal webpage without any limitation to Select, Hover and click.
In both of websites when you click around, the menu will close, but I could not find any transparent layer in stackoverflow and I am not sure these are using the similar way.
As I know there is several ways to solve these problems:
Simulate a click by using x,y
It is not the correct answer, because in this way, it is not possible to use hover like what stackoverflow is doing now (you can hover over any objects behind the menu).
Make an element “invisible” to clicks
It is not the correct answer, because in this way, it is not possible to use onclick event to hide menu itself.
JavaScript to prevent Default action
It is not the correct answer, because in this way, it is not possible to use hover and onclick events at the same time. then it is not possible to make it like stackoverflow.
Can you please guide me how stackoverflow is passing the Github limitation?

Just don't create a transparent overlay at all.
Instead listen for the click event on document and close the menu if it's fired.
document.querySelector('button').addEventListener('click', e => {
console.log('button clicked')
})
document.addEventListener('click', e => {
console.log('click reached document, close menu')
})
<div>
<button>Click me</button>
</div>

First you need to toggle menu using classes like this:
when it is close:
<div class="menu">...</div>
when it is open:
<div class="menu open">...</div>
and in CSS:
.menu {
display: none;
}
.menu.open {
display: block;
}
then you need to add an onclick event on the document to find all open menus and remove open class of them.
<script type="text/javascript" language="JavaScript">
document.onclick = closeAllOpenMenus;
function closeAllOpenMenus() {
const all_open_menus = document.querySelectorAll(".menu.open");
[].forEach.call(all_open_menus, function(el) {
//remove 'open' class
el.classList.remove("open");
});
}
</script>
you need to work more on the above function to prevent closeAllOpenMenus when the user is clicked over the menu itself.

Related

jQuery collapsible through toggleClass on element

I have an off canvas navigation menu (classname that is enabled via hover-over using jQuery on my Wordpress site. It is, as it should be, not visible on page load.
For the mobile version, I want the same nav menu to be activated by clicking on a menu icon (that I've given two classes, in this order: mobile-nav-toggle show-nav-mobile). The toggle method seems to only work for a vertical toggle. My solution to replicating the same animation on click rather than hover, is by using the toggleClass method on the icon to toggle between a classname that opens the menu nav (show-nav-mobile) and closes it (hide-nav-mobile) Using the below code:
jQuery(".show-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'0px' }, 250);
});
jQuery(".mobile-nav-toggle").click(function(){
jQuery(".mobile-nav-toggle").toggleClass("show-nav-mobile hide-nav-mobile");
});
jQuery(".hide-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'-640px' }, 250);
});
That doesn't seem to do the job though. The jQuery opens the offcanvasmain div just fine, but doesn't close it again.
What is wrong with my approach?
I assume your element initially looks somewhat like this:
<nav class="mobile-nav-toggle hide-nav-mobile">...</nav>
This means that
a) Both these click handlers will always run when clicking, no matter if the element still has the class hide-nav-mobile:
jQuery(".mobile-nav-toggle").click(function(){
jQuery(".mobile-nav-toggle").toggleClass("show-nav-mobile hide-nav-mobile");
});
jQuery(".hide-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'-640px' }, 250);
});
jQuery finds the element at the moment you define the click handler; it doesn't recheck if the element still has this class when clicking later.
b) This never attaches a click handler:
jQuery(".show-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'0px' }, 250);
});
because at the time of calling jQuery(".show-nav-mobile") it cannot find any element with that class.
To fix it, do this all in a single click handler:
jQuery(".mobile-nav-toggle").on('click', function(){
const that = jQuery(this);
that.toggleClass("show-nav-mobile hide-nav-mobile");
jQuery(".offcanvasmainnav").animate({left: that.hasClass('show-nav-mobile') ? '0px' : '-640px' }, 250);
});

How to give a button (class) active hover-status on document ready?

On a website I have 4 clickable buttons (service buttons) on the homepage. They all respond individually to a css hover effect (background-color change) when the user hovers over one of the buttons. So far so god, this is what i want.
CSS:
.service-button:hover {
background: #F7AA06;
color: #1F213F;
}
The FIRST of the four buttons is the most important service. Therefore I want to highlight this button by having it "active" with the hover effect (background-color) when a user first enters the page. If the user hovers over one of the other buttons, the first button should "lose" it's hover-status and return to standard bg-color (white).
My temporary solution so far is to give the first button it's highlighted color with the nth:first-child selector from css. This kind a works as it sets the correct background-color to the first button. The problem is that the button does not change back to standard color if users hovers over on of the other buttons.
Is it possible to accomplish this from just css, or do I need to use jQuery?
https://imgur.com/Jutg3RS
NEW fix! I actually got it working with some jQuery. Guess it's not the cleanest solution, but it does the job! Could/should it be resolved in a better way..?
jQuery(document).ready(function($){
// Add hover class to first button
$('.service-button.totalentreprise').addClass('bg-orange');
$('.service-button').hover(
function() {
// Remove hover class from first button
$('.service-button.totalentreprise').removeClass('bg-orange');
// Add hover class to any button
$( this ).addClass('bg-orange');
}, function() {
$( this ).removeClass('bg-orange');
}
);
});
try these
window.addEventListener('load', function(){
$(".service-button").hover(function(e) {
$(this).css("background-color",e.type === "mouseenter"?"#F7AA06":"transparent")
});
})

Onclick and onmouseover together?

Using jquery, I am interested in using onclick and onmouseover together for one volume button (found in a html5 player).
To help you visualize it, think of it as being the YouTube volume button:
Normally:
When you hover:
When you click (to mute):
In my case, both events onclick and on mouseover will work, under the condition that you don't use them together.
If you add them both like the code below, then the onclick event won't work, the other will.
My code (simplified):
//When the user clicks on the volume button
$(".volume").on("click",function() {
$(".volume").hide();
$(".volume_mute").show();
});
//When the user clicks on the volume button
$(".volume").on("mouseover", show_volume_bar);
//show_volume is a function here which shows the volume bar
//which will make the user change the volume (doesn't interest you).
The jQuery I am using:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
How can I make the both events (onclick and onmouseover) work together for the same button? As I said, when I use them together one of them won't work (which is onclick).
You can use jQuery .bind() to bind multiple events.
$( ".volume" ).bind({
click: function() {
$(".volume").hide();
$(".volume_mute").show();
},
mouseover: function() {
show_volume_bar();
}
});
Other solution than the bind is just to use the .click() and .mouseover() functions :
$(".volume").click(function() {
$(".volume").hide();
$(".volume_mute").show();
}).mouseover(function() {
show_volume_bar();
});
You can also use CSS instead
`HTML
<div class="container">
<div id="transition-hover">
<span>Transition Hover</span>
<div id="transition-hover-content">
This content or image is visible only when you mouse hover the parent div and it has transition effect.
</div>
</div>
CSS
#transition-hover-content {
opacity:0;
-webkit-transition:.5s;
-moz-transition:.5s;
-o-transition:.5s;
-ms-transition:.5s;
transition:.5s;
}
#transition-hover:hover #transition-hover-content {
opacity:1;
}
</div>
I used tutorial from this a link

jquery menu, hover and display:none

I have this menu http://jsbin.com/useqa4/3
The hover I think works correct, but what I want is the normal: when the user's cursor isn't on the "Solution" item or on the submenu then I want the div #submenuSolutions to return in "display:none".
How can I achieve this?
If you read the jQuery api more carefuly you will see that the hover function can take handle two events http://api.jquery.com/hover/
$("document").ready(function() {
$("#menuSolutions a").hover(function () {
$("#menuSolutions").addClass("menuHover");
$("#submenuSolutions").show("3000");
},function() {
$("#menuSolutions").removeClass("menuHover");
$("#submenuSolutions").hide("3000")});
});​
This will work only if your menu is a suckerfish menu.
See Demo
Just added this code to hide it back when mouse leaves it:
$("#submenuSolutions").mouseleave(function(){
$(this).hide();
});
Since submenuSolutions is the id of your panel, you can use the mouseleave event which triggers when mouse leaves the area of element specified.

how to make the menu close if it is clicked out

i have an menu with some values and i got someting hidden and while click on more button it shows like google more menu... if it is clicked out it is not hiding till the more menu is clicked once again
More<small>▼</small><div class="more list" id="one" style="display:none">test <span style="color:#329">|</span> test1 <span style="color:#169">|</span> test4</div></div>
Script:
function toggle(one)
{
var o=document.getElementById(one);
o.style.display=(o.style.display=='none')?'block':'none';
}
how to make it close while the mosuse clicks on any other place other than the menus
Try using the onblur event.
I see you've tagged this with jQuery, if that is an option, you can clear up the link a bit, like this:
More<small>▼</small>
And use unobtrusive script combined with event bubbling to your advantage, like this:
$(function() {
$(".more_link").click(function(e) {
$(this).next(".more").toggle();
e.stopPropagation();
});​​
$(".more").click(function(e) {
e.stopPropagation();
});
$(document).click(function() {
$(".more").hide();
});​
});
You can test it out here, this only closes the menu if you clicked neither the menu of the toggle, e.g. clicking one of the test links will not close it. If you want it to, just remove the $(".more").click(function(e) { e.stopPropagation(); }); portion.
It uses event.stopPropagation() to stop the click from bubbling up to document, which if happens (and would if you clicked anything else) triggers its click handler, closing all the .more elements.
I wouldn't use onBlur because it's not a good accessibility approach (for example if the user is using tab to navigate the page).
Look at this solution instead:
jQuery click event for document but ignore a div
Typically, I let the event bubble up to the 'body' or 'html' doc and check if the target is what i want (and/or isn't contained within what i want). If the event target is not contained within your menu, then perform your desired operation (in this case, hide the div).
i.e.
jQuery(document).ready(function(){
jQuery("html").bind("click", function(evt){
var $target = jQuery(evt.target);
var shouldShowMenu = $target.hasClass("menu_toggle");
shouldShowMenu |= $target.parents(".menu_toggle, .more_list").length;
if(!shouldShowMenu)jQuery(".more_list").hide();
});
});
NOTE: your markup would needs to be extended such that the "more" href becomes has a class attribute, class="menu_toggle"

Categories