I have customized using jquery the bootstrap navigation whereby instead of clicking to enable the dropdown menu you can simply hover. However, I am trying to get it so the first menu is clickable as currently it is not. For example currently BLOG isn't clickable but I would like it to be. The other categories are clickable.
Does anyone have any experience in this on bootstrap? It is being built on wordpress. The jquery I used to allow the menu to show on hover is:
jQuery(document).ready(function() {
var mq = window.matchMedia('(min-width: 768px)');
if (mq.matches) {
jQuery('ul.navbar-nav li').addClass('hovernav');
} else {
jQuery('ul.navbar-nav li').removeClass('hovernav');
};
/*
The addClass/removeClass also needs to be triggered
on page resize <=> 768px
*/
if (matchMedia) {
var mq = window.matchMedia('(min-width: 768px)');
mq.addListener(WidthChange);
WidthChange(mq);
}
function WidthChange(mq) {
if (mq.matches) {
jQuery('ul.navbar-nav li').addClass('hovernav');
} else {
jQuery('ul.navbar-nav li').removeClass('hovernav');
}
};
});
The css is:
@media (min-width: 768px) {
.navbar-nav .caret {
display:none;
}
.navbar-nav .open ul {
display:none;
}
.navbar-default .navbar-nav > .open > a,.navbar-default .navbar-nav > .open > a:hover,.navbar-default .navbar-nav > .open > a:focus,.navbar-default .navbar-nav > .active > a,.navbar-default .navbar-nav > .active > a:hover,.navbar-default .navbar-nav > .active > a:focus {
color:#555;
background:none;
}
.navbar-inverse .navbar-nav > .open > a,.navbar-inverse .navbar-nav > .open > a:hover,.navbar-inverse .navbar-nav > .open > a:focus,.navbar-inverse .navbar-nav > .active > a,.navbar-inverse .navbar-nav > .active > a:hover,.navbar-inverse .navbar-nav > .active > a:focus {
color:#969696;
background:none;
}
.navbar-default .navbar-nav > .hovernav > a {
color:#555;
}
.navbar-inverse .navbar-nav > .hovernav > a {
color:#969696;
}
.navbar-default .navbar-nav > .hovernav:hover > a,.navbar-default .navbar-nav > .hovernav:hover > a:hover,.navbar-default .navbar-nav > .hovernav:hover > a:focus {
color:#333;
background:transparent;
}
.navbar-inverse .navbar-nav > .hovernav:hover > a,.navbar-inverse .navbar-nav > .hovernav:hover > a:hover,.navbar-inverse .navbar-nav > .hovernav:hover > a:focus {
color:#F7F7F7;
background:transparent;
}
.navbar-default .navbar-nav > li:hover {
background:#e7e7e7;
}
.navbar-inverse .navbar-nav > li:hover {
background:#080808;
}
.navbar-nav .hovernav:hover > .dropdown-menu {
display:block;
}
}
Problems using matchMedia/media queries to accomplish what you're doing:
Media queries for many touch devices are the same as desktop.
Hover does not exist on touch. IOS takes a hover and one click triggers the dropdown 2 clicks get to the link, BUUUT android doesn't work this way. So on touch devices those drop menus won't be accessible. How to do this correctly:
Detect touch and no-touch on Android, IOS, and Windows 8 phones.
Remove the Attribute data-toggle on the .dropdown a link -- removing this allows the click to work on that toggle.
Wrap the removing attribute in an if statement if no-touch
Wrap the hover script in a no-touch if statement
Have a fallback for touch devices so they can get to the first menu item
Edit: http://jsbin.com/ejAXoda/1/edit
CSS
.touch .mobile-link {display:block;}
.no-touch .mobile-link {display:none}
Script(s)
/* ----- Detect touch or no-touch */
/* Detects touch support and adds appropriate classes to html and returns a JS object
* Copyright (c) 2013 Izilla Partners Pty Ltd
* http://www.izilla.com.au
* Licensed under the MIT license
* https://coderwall.com/p/egbgdw
*/
var supports = (function () {
var a = document.documentElement,
b = "ontouchstart" in window || navigator.msMaxTouchPoints;
if (b) {
a.className += " touch";
return {
touch: true
}
} else {
a.className += " no-touch";
return {
touch: false
}
}
})();
// -------- DO the stuff only on no-touch devices only
if ($("html").hasClass("no-touch")) {
// ------- REMOVE THE DATA TOGGLE ONLY ON "no-touch" devices and get the link to work
$('.dropdown > a').removeAttr("data-toggle");
// Hover dropdown for Bootstrap 3.x wrapped in this no-touch var
/*
* Project: Bootstrap Hover Dropdown
* Author: Cameron Spear
* Contributors: Mattia Larentis
*
* Dependencies: Bootstrap's Dropdown plugin, jQuery
*
* A simple plugin to enable Bootstrap dropdowns to active on hover and provide a nice user experience.
*
* License: MIT
*
* http://cameronspear.com/blog/bootstrap-dropdown-on-hover-plugin/
*/
(function (e, t, n) {
if ("ontouchstart" in document) return;
var r = e();
e.fn.dropdownHover = function (n) {
r = r.add(this.parent());
return this.each(function () {
var i = e(this),
s = i.parent(),
o = {
delay: 500,
instantlyCloseOthers: !0
}, u = {
delay: e(this).data("delay"),
instantlyCloseOthers: e(this).data("close-others")
}, a = e.extend(!0, {}, o, n, u),
f;
s.hover(function (n) {
if (!s.hasClass("open") && !i.is(n.target)) return !0;
a.instantlyCloseOthers === !0 && r.removeClass("open");
t.clearTimeout(f);
s.addClass("open");
s.trigger(e.Event("show.bs.dropdown"))
}, function () {
f = t.setTimeout(function () {
s.removeClass("open");
s.trigger("hide.bs.dropdown")
}, a.delay)
});
i.hover(function () {
a.instantlyCloseOthers === !0 && r.removeClass("open");
t.clearTimeout(f);
s.addClass("open");
s.trigger(e.Event("show.bs.dropdown"))
});
s.find(".dropdown-submenu").each(function () {
var n = e(this),
r;
n.hover(function () {
t.clearTimeout(r);
n.children(".dropdown-menu").show();
n.siblings().children(".dropdown-menu").hide()
}, function () {
var e = n.children(".dropdown-menu");
r = t.setTimeout(function () {
e.hide()
}, a.delay)
})
})
})
};
e(document).ready(function () {
e('[data-hover="dropdown"]').dropdownHover()
})
})(jQuery, this);
} //END IF no-touch for hover script & removeAttr for the links to work
SAMPLE HTML with fallback for the link:
<!-- Static navbar -->
<div class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="http://getbootstrap.com" data-toggle="dropdown" data-hover="dropdown" data-delay="1000" data-close-others="false">Blog <b class="caret"></b></a>
<ul class="dropdown-menu">
<!-- add for touch they won't be able to get to the link -->
<li class="mobile-link"><a href="blog.html">Latest News</a></li>
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="./">Default</a></li>
<li><a href="../navbar-static-top/">Static top</a></li>
<li><a href="../navbar-fixed-top/">Fixed top</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
I tested this on Android. Test this on IOS, Windows 8, and other devices before awarding/accepting. Should work smoothly.
$('body').on('mouseover', '.dropdown-toggle', function(e){
$(e.currentTarget).trigger('click')
})
or instead of ".dropdown-toggle" you could use the id of the element that triggers the dropdown
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With