I am having issues with the nav bar collapsing when in full screen view. I want the nav bar to collapse in the hamburger via the mobile screen and i wrote a custom directive. Now when in full screen and you click a link the nav bar collapses and is causing an annoying flicker! Any ideas or help would be greatly appreciated!
Here is my code:
js:
.directive('collapseMenu', function () {
return {
link: function (scope, elem, attrs) {
$('.nav a').on('click', function(){
$('.navbar-toggle').click()
});
}
}
});
html:
<!-- Navigation -->
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div collapse-menu class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
<span class="sr-only">Show Menu</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- navbar-brand is hidden on larger screens, but visible when the menu is collapsed -->
<a class="navbar-brand" href="#/home"></a><a <img src="images/phone.png" alt="press to call"></a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="navbar-collapse-1" >
<ul class="nav navbar-nav">
<li><a class="home" href="#/home">Home</a></li>
<li><a class="about" href="#/about">About</a></li>
<li><a class="con" href="#/contact">Contact</a></li>
<li><a class="review" href="#/review">Reviews</a></li>
<li><a class="admin" href="#/admin">Admin</a></li>
</ul>
</div>
</div>
</nav>
So, if you want to eliminate the collapse on larger screens, you'll have to add a screen width check to your link click function. And, if it's less than a certain size, you fire off the .navbar-toggle click function. Otherwise, you do nothing. You could check the screen width using $(window).width(). So, your directive code would become:
.directive('collapseMenu', function () {
return {
link: function (scope, elem, attrs) {
$('.nav a').on('click', function(){
if ($(window).width() <= 1200) {
$('.navbar-toggle').click();
}
});
}
}
});
Related
When I click on the hamburger menu when the page first refreshes, it works fine and the menu drops down as expected. After redirecting to a different page from the submenu, the hamburger button no longer drops down and will only drop down again after a page refresh.
However, my ng-click is still being registered.
This is my HTML:
<body ng-app="app">
<create-merchant ng-if="loaded && loaded.all_root_collections"></create-merchant>
<create-ticket ng-if="loaded && loaded.all_root_collections"></create-ticket>
<!-- Navigation Bar-->
<header id="topnav" ng-if="authenticated && userPermissions" ng-cloak>
<!-- Topbar Start -->
<div class="navbar-custom">
<div class="container-fluid">
<ul class="list-unstyled topnav-menu float-right mb-0">
<li class="dropdown notification-list">
<!-- Mobile menu toggle-->
<script>console.log(navigationOpen);</script>
<a class="navbar-toggle nav-link" ng-click="navigationOpen = !navigationOpen" ng-class="{'open': navigationOpen}">
<div class="lines">
<span></span>
<span></span>
<span></span>
</div>
</a>
<!-- End mobile menu toggle-->
</li>
<li ng-show="!hideNavBar" class="dropdown notification-list">
<a class="nav-link" href="#/notifications" role="button">
<i class="fe-bell noti-icon"></i>
<span class="badge badge-danger rounded-circle noti-icon-badge">{{rootAlertCount||0}}</span>
</a>
</li>
This is in my app.js :
$rootScope.navigationOpen = false;
console.log($rootScope.navigationOpen);
This is my directive:
(function () {
'use strict';
angular
.module('app')
.directive("navbarDirective", ['$timeout', function ($timeout) {
function link(scope, element, attrs) {
$(element).find('.has-submenu').children('a').on('click', function (event) {
if(window.innerWidth < 992){
event.preventDefault();
$(this).parent().find('.submenu').stop().slideToggle();
$(element).find('.submenu').find('a').unbind( "click" ).bind('click', function (event) {
if(window.innerWidth < 992){
console.log(scope.navigationOpen);
scope.navigationOpen = !scope.navigationOpen;
console.log(scope.navigationOpen);
scope.$apply();
}
})
}
});
}
return {
resrict: 'A',
link: link
};
}])
})();
Question
How can I swap classes of my navbar using javascript.
Background
I have a fixed navbar that I am trying to change to a static navbar on smaller screen sizes (< 768px) because my mobile menu pusher is having layout problems due to the fixed nav.
HTML
<nav class="navbar navbar-default navbar-fixed-top" id="mynav">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-
toggle="collapse" data-target="#navbar" aria-expanded="false" aria-
controls="navbar">
<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 id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active">Home</li>
<li>About</li>
<li>Products</li>
<li>Contact</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
I tried creating a javascript function to add / remove the static nav class but for some reason it's not working.
JS
function changeNav() {
if ($(window).width() < 768) {
$("#mynav").addClass("navbar-static-top");
$("#mynav").removeClass("navbar-fixed-top");
} else {
$("#mynav").removeClass("navbar-static-top");
$("#mynav").addClass("navbar-fixed-top");
}
}
changeNav();
You can use this instead, this is propper and have better performances:
let lastState = false;
function checkForViewportChange () {
var state = window.matchMedia("(max-width: 768px)").matches;
if (state != lastState) {
if (state) {
//do your stuff here
} else {
//do your other stuff here
}
lastState = state
}}
window.setInterval (checkForViewportChange, 150);
You should check every time user resizes the screen, use .resize() method
Ex.
$(window).resize(() => {
let b = $(window).width() < 768;
$("#mynav").addClass("navbar-"+(b ? "static":"fixed")+"-top");
$("#mynav").removeClass("navbar-"+(b ? "fixed":"static")+"-top");
});
This is probably easier done with css media queries than javascript.
Example:
#media (max-width: 768px) {
// styles for device width <= 768px
}
If you really want to use javascript, then the answer from Abdeslem Charif is a good start
I'm struggling with getting my navigation menu to show the selected page. I'm using the Bootstrap framework to build my site. This is my navigation menu:
<nav class="navbar">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<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="/index.html">Digital Transformation</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav pull-right">
<li class="active">Transformation deck</li>
<li>Background information</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
As far as I can tell, Bootstrap uses the following JS to make the selected menu item active, which I have in my header:
<script>
$('label').click(function() {
$(this).parent('li').toggleClass('active');
});
</script>
However with this code my primary nav item is active on page load, but when I select the second item it keeps 'Tranformation deck' as active instead of 'Background information'.
Am I missing a trick here? Any help would be greatly appreciated.
If you want to hook up click listeners to your nav items, your script should be something like this:
<script>
$('#navbar nav li a').click(function() {
$(this).parent('li').toggleClass('active');
});
</script>
You don't have any 'label' tags in your code, so there isn't anything to attach click event handlers to.
$(function() {
// this will get the full URL at the address bar
var url = window.location.href;
// passes on every "a" tag
$("#navbar a").each(function() {
// checks if its the same on the address bar
if (url == (this.href)) {
$(this).closest("li").addClass("active");
}
});
});
I am trying to fade in the navigation bar and stick to top while scrolling to bottom of the page. Its fade effect works only the first time. My code is below.
<style type="text/css">
.navOpacity{
opacity: 0;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$(window).scroll(function(){
var ht = $('header').height()+70;
if($(this).scrollTop() >= ht){
$("#navb").addClass("navbar-fixed-top navOpacity")
.fadeTo('slow','1');
$(".row:first").css("padding-top","50px");
}else{
$("#navb").removeClass("navbar-fixed-top navOpacity");
$(".row:first").css("padding-top","0px");
}
});
});
</script>
<div class="container">
<header class="page-header">
<h1>Hello world</h1>
</header>
<nav id="navb" class="navbar navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="dropdown">
<a class="dropdown-toggle"
data-toggle="dropdown" href="#">Page 1
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Page 1-1</li>
<li>Page 1-2</li>
<li>Page 1-3</li>
</ul>
</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
</div>
</nav>
<div class="row">
<div class="col-md-4">
<h3>h1. Bootstrap heading</h3>
Hello world and Mario.
</div>
<div class="col-md-4">
<h3>h2. Bootstrap heading</h3>
Hello world and Mario.
</div>
<div class="col-md-4">
<h3>h3. Bootstrap heading</h3>
Hello world and Mario.
<img src="rsz_myimg.jpg" class="img-responsive" />
</div>
</div><!-- end or row class-->
</div><!-- end container class-->
Your problem is that after the first time fadeTo is executed, your element is left with a style="opacity: 1" attribute, which is left there. So you have to remove it when you scroll to the top.
I've also changed the way the navbar is hidden, I suggest using .hide(), cause it also uses the elements' style attribute, that way it will not be overridden. And there's also a navbarVisible var that is used to determine if the navbar is already faded in and if it is, the code for fading it in is not executed when not needed. This should be a tiny step up in performance.
This seems to work just fine:
<script type="text/javascript">
$(document).ready(function(){
var navbarVisible = false;
$(window).scroll(function(){
var ht = $('header').height()+70;
if ($(this).scrollTop() >= ht) {
if (!navbarVisible) {
$("#navb").addClass("navbar-fixed-top")
.hide()
.fadeTo('slow','1');
$(".row:first").css("padding-top","50px");
navbarVisible = true;
};
} else {
$("#navb").removeClass("navbar-fixed-top").removeAttr('style');
$(".row:first").css("padding-top","0px");
navbarVisible = false;
}
});
});
</script>
You don't need this part anymore:
<style type="text/css">
.navOpacity{
opacity: 0;
}
</style>
Here's a link to an example JSFiddle with working code: JSFiddle Link
My two cents...
Just add this Javascript and away you go. Currently configured to graduate over the first 200px of scroll.
var scrollFadePixels = 200;
var fadeNavbar = function (window)
{
var opacity = window.scrollTop() / scrollFadePixels;
$('.navbar-fixed-top').css('background-color', 'rgba(34,34,34,' + opacity + ')');
}
fadeNavbar($(window));
$(window).scroll(function () {
fadeNavbar($(this));
});
Question Background:
I have a standard bootstrap NavBar that collpases to a button on mobile devices.
The Issue:
When the user clicks on an item in the NavBar dropdown list the page will scroll down to the corrosponding div. I have a piece of JQuery that collpases the dropdown menu when the item has been clicks.
Without the JQuery to close the dropdown Nav menu the page scrolls down to the div with no issues. With the JQuery the page is scrolling down but stops well after the set 10px offset.
Without the JQuery menu closing code - working:
Note the small 10px above the panel item, this is what is wanted.
With the JQuery closing code - Broken:
Note that the page now scrolls down past the top of the div.
The Code:
The NavBar:
<div class="navbar">
<nav class="navbar navbar-default navbarColour" role="navigation" id="nav">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<img src="~/Images/DC.png" class="dc">
</div>
<div class="middleNavPadding">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav pull-right">
<li>Services</li>
<li>Our Mission</li>
<li>Projects Gallery</li>
<li>Contact Us</li>
</ul>
</div>
</div>
</div>
</nav>
</div>
The JQuery Menu closing code:
$(document).ready(function () {
$(".navbar-nav .scroll-link").click(function (event) {
$(".navbar-collapse").collapse('hide');
});
});
The JQuery used to scroll to the Div as set in the NavBar menu:
$(document).ready(function () {
$('.scroll-link').on('click', function (event) {
event.preventDefault();
var sectionID = $(this).attr("data-id");
scrollToID('#' + sectionID, 750);
});
function scrollToID(id, speed) {
var offSet = 10;
var targetOffset = $(id).offset().top - offSet;
$('html,body').animate({ scrollTop: targetOffset }, speed);
}
});
The HTML Markup of the Panel:
<div id="Info">
//panel HTML
</div>
I believe the issue is that the JQuery is setting the 'top' of the page as the bottom of the dropdown menu which is then causing a false offset. Any help with solving a a solution to this would be much appreciated.
You are on the right track, just add the height of the #bs-example-navbar-collapse-1 to your offset.
function scrollToID(id, speed) {
var offSet = 10 + $('#bs-example-navbar-collapse-1').height(); // NAVBAR HEIGHT !!!
var targetOffset = $(id).offset().top - offSet;
$('html,body').animate({ scrollTop: targetOffset }, speed);
}
This should work.