Get Bootstrap navbar collapse to trigger javascript instead? - javascript

I've got a standard Twitter Bootstrap 3 navbar with some buttons on it (as per here: http://getbootstrap.com/components/#navbar-default ). I want to change the collapse behaviour (where it becomes a dropdown menu below a certain screen width) so that my custom Javascript function is run, instead of the drop down menu being created. This is because I'm making more extensive changes to the interface for smaller screens, than just CSS would allow (e.g. I'm moving UI elements around in the DOM etc).
Should I just switch off the collapse behaviour of the navbar, and if so how?
And then I'm thinking on both page load and page resize (using JQuery's resize() event) I check new window width and trigger the mobile UI (via my function) if width is below the collapse point?
Or is there a better way of doing this?
Any thoughts appreciated!
Thanks

This is doable, and I applaud your effort to go beyond BS styling in extending the platform to something unique.
Using less open the BS Navbar.less file. Look for the section within the .navbar-collapse { class definition.
This is the default styling (remember mobile first is set) and will break to the horizontal styling at the default (if not overridden) of 768px. You can place your styling in here and it will default. You can place the horizontal styles within this section, and remove any #media (min-width: #grid-float-breakpoint) { sections that would flip to the horizontal (as it would be set by default.
Next step is to handle a breakpoint. I like enquire.js as it allows for identical registration of breakpoints between CSS and the JS listener.
http://wicky.nillia.ms/enquire.js/
enquire.register("screen and (max-width: 767px)", {
match : function() {
//Do something
},
unmatch : function() {
//undo something
}
});
Without enquire.js:
$(window).resize(function() {
if($(window).width() < 768){
//do it
}
});

Related

Toggling class on scroll when div enters viewport with CSS scroll-snap

I have a vertical slideshow that scrolls/sticks to the next panel when the user scrolls. Desired effect is https://www.tesla.com but I thought I could achieve this with CSS (example below).
Example 1: https://codepen.io/moy/pen/poNrVdO
The problem is I would like to add a class so I can fade in the text when the next panel becomes 'active' and I'm not sure what the best approach is. Due to the framework this is going into, a non-jQuery solution would be preferable. I tried using http://dbrekalo.github.io/whenInViewport/ but can't get that to play ball at the minute.
import * as whenInViewport from "https://cdn.skypack.dev/when-in-viewport#2.0.4";
var WhenInViewport = window.WhenInViewport;
var elements = Array.prototype.slice.call(
document.getElementsByClassName("slideshow__panel")
);
elements.forEach(function (element) {
new WhenInViewport(element, function (elementInViewport) {
elementInViewport.classList.add("inViewport");
});
});
Update
The JS I was trying to use would only add a class and not toggle (add/remove) when items entered/left the viewport. So I decided to try a few other options. I've used AOS (Animation On Scroll) before but this is also having problems...
Example 2: https://codepen.io/moy/pen/XWNavaO
I think this is done to the overflow-y: auto which is required to get the snap-scroll to work. Can anyone offer an advise on this or would I be better moving away from snap scroll - as it's more hassle than it's worth?

How to do an element that is toggable on small screen sizes but always visible on big

I want to have a menu that is toggable in small screen sizes and always visible on medium sizes upwards.
The behavior should be (basically) exactly like this demo here.
The steps are:
Go to a small screen size (til the body outline is gold)
Check that it's toggable
When the menu is hidden and you get a bigger screen size, the menu should appear
When the menu is not hidden, go to a bigger screen size and it should remain shown
When on a big screen size, and element was hidden, you should see it but when you drag to a smaller size, it should get hidden
When on a big screen size, and element was NOT hidden, you should see it but when you drag to a smaller size, it should get hidden
To achieve this is very easy with:
$(".click").click(function() {
$(".menu").toggleClass("hidden-md-down");
});
My problem now is that I want to animate this show and hide and I can't do it with the class toggle.
So I have to rely on for example slideToggle() and here is where my problem lies, see demo here.
If you now go to a small screen size, hide the menu and make the window size bigger, the menu won't appear because of the hide() function.
I know this could be solve with a $(window).resize but I definitely don't want that solution since it's terrible for performance for such a small feature.
So how can I either have this toggle class with an animation or do it with js without the resize method?
I've put my comment into an answer instead: "For best performance wire your window size check to only the end of the browser resize, not to every stage."
This code works and it only runs .5 sec after the end of the window resize event rather than during (better performance). Run the code full page and squeeze your browser window to see it in action.
Instead of sending the text values #width and #height you can elect to run your menu toggle or deactivate it; I'd do this by removing the js class you're using to activate the menu initially.
And make your menu an unordered list and set it to be inline on desktop and an unbulleted list on mobile using css.
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
$(window).bind('resizeEnd', function() {
var widthReport = $("#width").text($(this).width());
var heightReport = $("#height").text($(this).height());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="width"></div>
<div id="height"></div>

Color entire Bootstrap menubar when mobile (hamburger menu) is clicked

I've got a menubar that I want to add some CSS or JS to. I want to make it such that when I click on it when in responsive view, the entire object can be targeted (I plan to do some background styling). I've found some stack overflows re: coloring the menu items, the menu itself, but none of those when applied to the overall menubar either A) work at all B) work only for responsive, which is what I want.
I've made a codepen. I just can't figure out if things like :active or :focus or something else would be the right fit. Hopefully the code pen illustrates what I want. I just cannot seem to target the navbar in it's entirety whether thru JS or CSS. I want to achieve a background effect for not just the dropdown but the row the hamburger lives in when clicked.
You can use Bootstrap's collapse events.
$('.navbar-collapse').on('show.bs.collapse', function () {
// Do your stuff
// This event fires immediately when the show instance method is called.
});
$('.navbar-collapse').on('hide.bs.collapse', function () {
// Do your stuff
// This event is fired immediately when the hide method has been called.
});
CODEPEN
If you add this to your navbar-header div:
<div onClick="clickMe()" class="navbar-header page-scroll">
then add this as a function:
function clickMe(){
if(window.innerWidth < 768){
$('.navbar-header').css('background-color', 'red');
}
}
it will work. you can also do an addClass('className'), and specify the class name like so:
.navbar-header.className{
background-color:red;
}

jQuery Add & Remove Class Div Width

How can i add/remove class according as div width ? I tried some codes but I have no idea about jquery codes. I'd like add div class according as antoher div width. Just i need add class like that. If container is smaller than 600px "add class" to content div else "remove class" from content div. These are my codes;
<div class="container">
<div class="content"></div>
</div>
$(window).resizeboxes(function() {
if ($(".container").width < 600){
$( ".content" ).addClass( ".content_600" );
}
});
else{
removeClass('.content_600')
}
$(window).trigger('resizeboxes');
This works, though the code is changed slightly. There were some problems with the syntax also, so I've corrected those (for instance the else statement was slightly misplaced). Here is a working example:
https://jsfiddle.net/vt0nbx36/3/
Here is the code:
var resizeboxes = function() {
if ($(".container").width() < 600)
{
$(".content").addClass("content_600");
}
else
{
$(".content").removeClass("content_600")
}
};
resizeboxes();
$(window).resize(function(){
resizeboxes();
});
For this need exactly, you have jQuery's .toggleClass() function. It takes the class name as a first parameter, and optional second boolean parameter that states wether the class name should be added or removed. You can find the documentation here
$(".content").toggleClass("content_600", ($(".container").width() < 600));
Even tho your question is a JS related question, CSS as a matter of fact can handle this like no other beast can (mostly)!
CSS allows you to use media-queries to resize your content based on the width of the viewport.
The upside of this is that the browser will handle this for you within the rendering engine rather than having JS between your change and the rendering engine.
The major downside is that you can't define the width of element A based on element B but are unfortunately locked to using the viewport as an indicator.
Before I explain why you'd want to use CSS I'd like to point out why you don't want to use JS for this if possible.
The jQuery.resize eventhandler fires inconsistently across browsers and it fires alot of times usually.
This causes your scrolling to clog up and make your webpage feel laggy.
If there's anything your users will dislike it's the fact that scrolling is controlled by something they don't even know of which is slowing you down.
As for a CSS solution, a media query looks like this:
.my-selector {
width: 900px;
}
#media all and (max-width: 600px) {
.my-selector {
width: 600px;
...
}
}
You wrap your code in a sort-of conditional that allows you to be very flexible with manipulating elements on the page.
What happens in the above piece of code is that when the parser reads the CSS it sees the first selector not in a media query so it applies width: 900px; then it sees a media query and sees the other rule for my-selector however it will only apply that rule when the screen is at that width we defined in the #media ... rule. When you resize CSS handles things differently behind the scenes so it's much faster than JS in that case.
I'm not sure if it actually applies to your situation but if your container is sized by the viewport rather than parent elements this should be possible and I thought it'd be nice atleast to show you a good way of playing with element dimensions.
Also, you can use #media to for instance make a webpage print friendly by changing the all to print for example and setting the background-color: transparent for an element - saves ink ^.^ which is an additional extra on top of the general awesomeness of media queries.
Hope it helps, good luck if you wish to make your webpage 5 times faster ;)

Programmatically determining how many element to display in a web navigation bar

Lets say I have a horizontal navigation bar that can have an arbitrary number of items in it. Now let say this page has a width of 1000px and all the items if displayed would be 1300px. Now what I would want to do is to take whatever elements are causing it to extend beyond the 1000px and put them into a drop down menu. The issue I am having is what is the best way to figure out how many element I would need to take to make sure everything fits in the window when the window width can be changed (if the user changes the window width, the number of elements in the drop down would increase or decrease) and the navigation element widths are random?
Something similar to google plus's side navigation, just horizontal instead fo vertical.
Put the navigation elements in a parent div whose overflow is set to hidden so the extra nav elements are hidden.
Then, find the items that are hidden using jquery and append them to your dropdown menu. See answer to this question: jQuery: How to get content not visible with overflow: hidden?
See my working example: http://jsfiddle.net/zSXTb. The basics:
var h = $("#container").height();
$("#container").find("div").each(function() {
if ($(this).position().top > h) {
$(this).clone().appendTo($("#extrasContent"));
}
});
Run this onload and when the window is resized.
Try using #media queries with the css - you get a lot of control regarding screen size. For example:
#media all and (max-width: 1000px){
/*insert normal css. e.g.:*/
body{
width: 700px;
}
}
You can use min-width instead of max-width.

Categories