I am using below JS code to fix header at the top for mobile only.
means if screen is scrolled for 80px css classes will be replaced.
working on android and PC but no luck on Ios.
any suggestions?
$(window).scroll(function () {
if ($(window).width() < 768) {
if ($(window).scrollTop() > 80) {
$('.navbar-right').addClass('custom-fixed-top');
}
else{
$('.navbar-right').removeClass('custom-fixed-top');
}
}
});
HTML CODE
<nav class="navbar navbar-default">
<div class="mid-container">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed hidden-xs" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<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="#"><img src="images/logo.png" class="img-responsive" alt="logo"></a>
</div>
<div class="navbar-collapse collapse in" id="bs-example-navbar-collapse-1" aria-expanded="true" style="">
<ul class="nav navbar-nav navbar-right">
<li class="hidden-xs"><a class="hdr-orng-btn" href="#">受付時間</a></li>
<li class="hidden-xs"><a class="" href="#">10:00~19:00</a></li>
<li><a class="num" href="tel:03-0000-0000">TEL 03-0000-0000</a></li>
<li><a class="hdr-grn-btn" href="#contact_form">お問い合わせ</a></li>
</ul>
</div>
</div>
</div>
.navbar-nav.custom-fixed-top{
position: fixed;
top: 0;
width: 100%;
height: auto;
padding: 0 15px 15px;
margin: 0;
z-index: 2;
background-color:#fff;
left:0;
}
this is the code.
Ok this might seem far fetched but...
Try add the following to your CSS in your html tag if they're on IOS:
cursor: pointer;
Maybe can be your if verification of viewport screen width with 768, verify if you use some screen above that size.
I try replicate your code here, but $(window).scrollTop() works fancy here for me.
Image with your code on google chrome
Try changing this;
if ($(window).scrollTop() > 80) {...
To this;
if ($(body).scrollTop() > 80) {...
If that then works on ios, then that's the issue, so to cover both devices/browsers implement something like this;
var scrollentity = $('html,body');
if (navigator.userAgent.match(/(iPod|iPhone|iPad)/))
{ scrollentity = $('body') }
else { scrollentity = $('html,body') }
scrollentity .scrollTop() > 80) {...
Hope it helps.
Related
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 am using a bootstrap navbar, and above the navigation links I have some text which I want to hide when the user scrolls down. Also, i want the navbar to be fixed top.
I am using a slideUp() and slideDown() to hide/show the text above the navbar, and I am using Jquery animate() to modify the navbar's height. (I need to have it's height explicit because of CSS reasons irrelevant to this issue)
The problem is that when I scroll to the top, the animate() gets queued after the slideDown() (Maybe it is not queued but it has some unwanted delay), which does not happen in the scrolling-down case. I want them to be simultaneous.
Here is a JSFiddle with minimal code reproducing the problem.
Here is the relevant minimal code:
html:
<nav class="navbar navbar-default navbar-fixed-top">
<div class="header">
Atención 24 horas 0800-777-8101
</div>
<div class="container-fluid">
<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="brand" href="#"><img src="img/logo.jpg" class="logo" /></a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active">DSDSADSA</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>ADSASD</li>
</ul>
</div>
</div>
</nav>
<div style="height:1000px;background-color:#ccc;padding:50px;"></div>
css:
.navbar {
height: 110px;
}
div.header{
text-align:right;
height:50px;
}
And the most important, Javascript:
$(document).ready(function(){
$(window).scroll(function() {
if ($(document).scrollTop() > 0) {
console.log('a');
$('.navbar').animate({height: '60px'});
$('div.header').slideUp();
} else {
console.log('b');
$('.navbar').animate({height: '110px'});
$('div.header').slideDown();
}
});
});
Your problem is, everytime you scroll when the scrollTop is greater than 0 it is applying:-
$('.navbar').animate({height: '110px'});
$('div.header').slideDown();
and not just when its up, (height and slideUp). This causes the else to fire multiple times. see the console for a
One way of fixing this is applying a class to .header to determine if you need to apply the animation. like so:-
$(document).ready(function(){
$(window).scroll(function() {
if ($(document).scrollTop() > 0 && !$('div.header').hasClass('hide')) {
console.log('a');
$('.navbar').animate({height: '60px'}, "fast");
$('div.header').slideUp("fast").toggleClass('hide');
} else if ($(document).scrollTop() == 0 && $('div.header').hasClass('hide')) {
console.log('b');
$('.navbar').animate({height: '110px'}, "fast");
$('div.header').slideDown("fast").toggleClass('hide');
}
});
});
Fiddle
or you could use data or a variable, etc.
Before you apply the animation or slideup make use of stop function to clear the queue.
$('div.header').stop();
$('.navbar').stop();
Check out the working demo for you code here JSfiddle
Determining if your .navbar is currently in the state of animation will do the trick, based on which you can decide NOT to animate.
Just add the following snippet which uses jQuery's is() method, and returns false if the .navbar is in the animation state:
if($('.navbar').is(':animated')){
return false;
}
JSFiddle
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();
}
});
}
}
});
<div class="container" id="menubar_1">
<nav class="navbar navbar-inverse" id="menubar_1">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#main_menu" aria-expanded="false">
<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="#"><img src="assets/images/logo.png" alt="logo" /></a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="main_menu">
<ul class="nav navbar-nav menu_bar text-uppercase">
<li class="active">adfadad</li>
<li>adfafaf</li>
<li>adadfa</li>
<li>ada</li>
<li class="contact_us">adfadfadf</li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
</div>
normally navbar has in to container without barnd-logo and the li's last-child.i want the result when the navbar scroll to top container class will removed and navbar-brand, li's last child will be added in the navbar.
I will try this js given below .
var distance = $('#menubar_1').offset().top;
$(window).scroll(function () {
if ($(window).scrollTop() >= distance) {
$('#menubar_1').addClass("fixed_top");
$('#menubar_1').removeClass("container");
$('#menubar_1').addClass("navbar-brand");
$('#menubar_1').addClass("contact_us");
} else {
$('#menubar_1').removeClass("fixed_top");
$('#menubar_1').addClass("container");
$('#menubar_1').removeClass("navbar-brand");
$('#menubar_1').removeClass("contact_us");
}
});
then fixed-top css is here:
.fixed_top {
width: 100%;
height: 50px;
top: 0px;
position: fixed;
overflow: visible!important;
z-index: 9998;
background: #fff;
padding-top:15px;
padding-bottom: 15px;
}
please help me with the scripts
finally i got the answer
<script>
var distance = $('#menubar_1').offset().top;
$(window).scroll(function () {
if ($(window).scrollTop() >= distance) {
$('#menubar_1').addClass("navbar-fixed-top");
$('#menubar_1').removeClass("container");
$('.navbar-brand').css("float" , "none");
$('.navbar-brand').css("display" , "block");
$('.contact_us').css("display" , "block");
} else {
$('#menubar_1').removeClass("navbar-fixed-top");
$('#menubar_1').addClass("container");
$('.navbar-brand').css("display" , "none");
$('.contact_us').css("display" , "none");
}
});
</script>
How can I add a class for an element, depending on the current screen dimensions?
Now I'm using Bootstrap's hidden-xs and visible-xs to handle it, but this requires duplicated code and elements in the DOM.
Update:
Overriding Bootstrap's predifined classes is not an option for me. Correct me if I'm wrong, but this would just be a hack and is bad practise in my point of view.
You can create directive for that purpose like below, but using CSS media queries seems to be better solution.
Please see here as well http://jsbin.com/mukec/1/edit?html,css,js,output
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
});
app.directive('top', function($window) {
return {
restrict: 'AE',
link: function(s, e, a) {
var body = angular.element(document.getElementsByTagName("body"));
$window.onresize = function(event) {
var clientWidth = document.documentElement.clientWidth;
if (clientWidth < 768)
{
e.removeClass('navbar-default')
e.addClass('navbar-fixed-top')
body.addClass('top50')
} else {
e.removeClass('navbar-fixed-top');
e.addClass('navbar-default');
body.removeClass('top50')
}
}
}
}
})
.navbar-fixed-top {
background-color: red
}
.navbar-default {
background-color: green
}
.top50 {
padding-top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<body ng-app="app">
<div class="navbar" top>
<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="#">Brand</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Home
</li>
<li>Link
</li>
<li>More
</li>
<li>Options
</li>
</ul>
</div>
</div>
<h1>SCROLL CONTENT</h1>
<img src="" height="1500px" />
</body>
May not be best practice but you could write a function that takes the screen size then applies the class
function screenLayout() {
var clientWidth = document.documentElement.clientWidth;
}
var classtoadd = angular.element('navbar');
if (clientWidth > 1024) {
classtoadd.addClass('largeScreen')
} else {
classtoadd.addClass('otherScreen')
}
Could just do it straight javascript or JQuery too