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
Related
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.
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 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();
}
});
}
}
});
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));
});
<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>