Reputation: 4984
I have a JSFiddle here.
It's a bootstrap nav with drop down menus. I'm not using bootstraps drop down but my own. The drop down menu needs to show on hover on the desktop and on click for mobile.
I have a media query to show the drop down menu on hover on desktop. I'm using Modernizr to add a click event at mobile sizes. The desktop and mobile functionalities work if the page is loaded at that size. If the page is loaded at desktop size the hover works and if the page is loaded at mobile size the mobile functionality works
If I load the page at desktop size and then resize the page to mobile size or vise versa the nav does not work.If I load at desktop size the hover works but if I then resize to mobile size the click doesn't work correctly.
I don't really need this to work after the page is resized because if you are on mobile you wouldn't be resizing. Can anyone tell me why this is happening and if there is a solution?
$(function(){
function doneResizing() {
if(Modernizr.mq('screen and (max-width:767px)')) {
$('.at-drop-down').on('click', function(e){
e.preventDefault();
$(this).next($('.sub-menu')).slideToggle();
})
}
}
var id;
$(window).resize(function() {
clearTimeout(id);
id = setTimeout(doneResizing, 0);
});
doneResizing();
});
Upvotes: 2
Views: 10452
Reputation: 2419
Alternatively, you can use only jQuery, without Modernizr, for the drop down menu to show on hover on the desktop and on click for mobile.
Take the dropdown menu above with data-toggle="dropdown"
:
<a class="dropdown-toggle" data-toggle="dropdown" role="menu" aria-expanded="false" href="www.example.com">
Parent
</a>
<ul class="dropdown-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
data-toggle="dropdown"
will prevent redirecting to URL on click and on touch.
Use ontouchstart
to detect mobile browser, and then force redirecting to URL when click on parent item only for desktop (NOT mobile):
function is_touch_device() {
return !!('ontouchstart' in window);
}
$(document).ready(function() {
if(!is_touch_device()) {
$('a.dropdown-toggle[data-toggle="dropdown"]').click(function (e) {
window.location.href = $(this).attr('href');
});
}
});
Upvotes: 0
Reputation: 43
$(window).resize(function(){
var wid = $(window).width();
if(wid < 768){
$(".dropdown").on('click', function(){
$('.dropdown-menu', this).stop( true, true ).fadeIn("fast");
$(this).toggleClass('open');
});
}
else{
$(".dropdown").hover(
function() {
$('.dropdown-menu', this).stop( true, true ).fadeIn("fast");
$(this).toggleClass('open');
},
function() {
$('.dropdown-menu', this).stop( true, true ).fadeOut("fast");
$(this).toggleClass('open');
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Inspiration<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">LookBook</a></li>
<li><a href="#">Designs</a></li>
<li><a href="#">Product</a></li>
<li><a href="#">Blog</a></li>
</ul>
</li>
Upvotes: 0
Reputation: 1851
I believe the problem is because, when you resize, the doneResizing()
method is called multiple times, and it attaches multiple on-click event handlers to the dropdown.
You could try this instead:
$(function(){
$('.at-drop-down').on('click', function(e){
if(Modernizr.mq('screen and (max-width:767px)')) {
e.preventDefault();
$(this).next($('.sub-menu')).slideToggle();
}
})
});
There's no need for resize events and on-click events are only ever registered once.
Demo: https://jsfiddle.net/alan0xd7/cwwaqp5k/45/
Update:
Hover issue: in "mobile mode", if you clicked on something, then resize to "full mode", the hovers stop working. This is because slideToggle()
sets CSS styles to hide and show the elements. You can do this to remove them:
$(window).resize(function() {
$('.sub-menu').attr("style", "");
});
Demo: https://jsfiddle.net/alan0xd7/cwwaqp5k/46/
Upvotes: 3
Reputation: 611
You're adding many event listeners when you resize. Try changing the JS to
$(function(){
function doneResizing() {
if(Modernizr.mq('screen and (max-width:767px)')) {
$('.at-drop-down').off('click'); //Remove all previous event listeners
$('.at-drop-down').on('click', function(e){
e.preventDefault();
$(this).next($('.sub-menu')).slideToggle();
})
}
}
var id;
$(window).resize(function() {
clearTimeout(id);
id = setTimeout(doneResizing, 0);
});
doneResizing();
});
Upvotes: 2