Resize calculated window height of variable - javascript

I'm creating a sticky nav on scroll for a clients website and have got it working. However, because the div above it has a variable height based on the height of the browser window minus the nav for a carousel height: calc(100vh - 100px); it's breaking when the browser window is resized. So can someone help me to add a resize event onto the below code, so that it updates the height of the window on resizing the browser?
var yourNavigation = $(".home-navbar");
stickyDiv = "sticky";
yourHeader = $('.home-carousel').height();
$(window).scroll(function() {
if( $(this).scrollTop() > yourHeader ) {
yourNavigation.addClass(stickyDiv);
$( "#sticky" ).addClass( "sticky__padding" );
} else {
yourNavigation.removeClass(stickyDiv);
$( "#sticky" ).removeClass( "sticky__padding" );
}
});

I think you just want to make the scrollTop check into a function and call it on load, scroll, and resize If so, you can use either pure JS or jQuery to accomplish this:
function headerStuff() {
var yourNavigation = $(".home-navbar");
var stickyDiv = "sticky";
var yourHeader = $('.home-carousel').height();
if( $(this).scrollTop() > yourHeader ) {
yourNavigation.addClass(stickyDiv);
$( "#sticky" ).addClass( "sticky__padding" );
} else {
yourNavigation.removeClass(stickyDiv);
$( "#sticky" ).removeClass( "sticky__padding" );
}
};
window.addEventListener("load", headerStuff);
window.addEventListener("resize", headerStuff);
window.addEventListener("scroll", headerStuff);

Related

JQuery position() and offset() methods not working

I'm a beginner programmer and I'm trying to create this effect that when I scroll past a specific element in the HTML, The colors of the buttons in my navbar change colors. I thought the correct way of doing this was jQuery. I'm having problems getting the position of the elements in the page. I have tried with the position() and offset() methods. But neither seem to work.
I want to get the vertical positions of the elements with the IDs "info" and "security". I have these methods aren't very reliable in certain cases, but I can't find an alternative.
This is the code I have so far:
$(window).on('load', function(){
window.loaded = true;
console.log("LOADED");
});
$( window ).scroll(function() {
if (window.loaded == true){
var scrollTop = $(window).scrollTop();
var infopos = $( "#info" );
var secpos = $("#security");
if (scrollTop >= 0 && scrollTop < infopos-25) {
$( "#navgeneral" ).addClass("active");
$( "#navinfo" ).removeClass("active");
$( "#navsecurity" ).removeClass("active");
}
else if (scrollTop >= infopos && scrollTop < secpos){
$( "#navgeneral" ).removeClass("active");
$( "#navinfo" ).addClass("active");
$( "#navsecurity" ).removeClass("active");
}
}
});`
Thank you for the advice in advance!!
Here you go.
//Declare these first
const infopos = $( "#info" ).scrollTop();
const secpos = $("#security").scrollTop();
$(window).on('load', function(){
window.loaded = true;
console.log("LOADED");
});
$( window ).scroll(function() {
if (window.loaded === true){
let scrollTop = $(window).scrollTop();
if (scrollTop < infopos-25) { //scrollTop >= 0 will always be true so skip it
$( "#navgeneral" ).addClass("active");
$( "#navinfo" ).removeClass("active");
$( "#navsecurity" ).removeClass("active");
}
else if (scrollTop >= infopos && scrollTop < secpos){
$( "#navgeneral" ).removeClass("active");
$( "#navinfo" ).addClass("active");
$( "#navsecurity" ).removeClass("active");
}
}
});`
First get a good understanding of how variables work and please try to use let instead of var most of the time while declaring variables. This will prevent accidentally overwriting global variables.
The objective mentioned is to let NAV bar change based on the position that you scrolled to.
First you need to get your target ID scroll position.Use code below to get every archor element ID:
$('#testB').position().top
(In jQuery, position will return you the left and top value, here we use top only.)
Second, get the current scroll position.Use code below:
currentHeight = $(window).scrollTop();
Third, write related jQuery code to change NAV elements.Sample JS as below:
Here we have 5 DIV (#testA to E) and 4 nav buttons (#test1 to 4)
$(window).scroll(function () {
var currentHeight = $(window).scrollTop();
if (currentHeight <= $('#testB').position().top) {
$("#test1").addClass('active-blue');
$("#test2").removeClass('active-blue');
$("#test3").removeClass('active-blue');
$("#test4").removeClass('active-blue');
} else if (currentHeight <= $('#testC').position().top) {
$("#test1").removeClass('active-blue');
$("#test2").addClass('active-blue');
$("#test3").removeClass('active-blue');
$("#test4").removeClass('active-blue');
} else if (currentHeight <= $('#testD').position().top) {
$("#test1").removeClass('active-blue');
$("#test2").removeClass('active-blue');
$("#test3").addClass('active-blue');
$("#test4").removeClass('active-blue');
} else {
$("#test1").removeClass('active-blue');
$("#test2").removeClass('active-blue');
$("#test3").removeClass('active-blue');
$("#test4").addClass('active-blue');
}
});

Resize function events fire 2 times more each time the window was resized

On my site, I am trying to fix the navigation so that when the browser is getting resized from desktop to mobile size, the mobile menu works. I have the mobile menu working on initial load, and the desktop navigation working on initial load, but when I run the script in a $(window).on('resize', function() {} and click an item as depicted in my script, the event fires always +1 each time the window was rested after a resize.
What I mean is, if I load the page, scale it into mobile size, click the menu and a dropdown item, the click event will fire once. Resize the window out and then back in, the click event will fire now 2 times, then 3, and so on, depending on how many times the browser was resized.
I'm not sure exactly what is going on in my resize script that is screwing everything up and I'm at my wits end at trying to figure it out. Normally people aren't sitting there resizing their browser from desktop to mobile, but my boss does when he show's clients a beta of their site and wants this to never be an issue.
Here is my resize script:
(function( $ ) {
var id,
$body = $('body'),
$window = $( window ),
$navSlider = $('.nav-slider'),
$navMask = $( '.nav-mask' ),
$navToggler = $( '.navbar-toggler' ),
$parent = $( '.menu-item-has-children' ),
$parentLink = $( '.dropdown-toggle' ),
$childContainer = $( '.dropdown-menu' );
$window.on( 'resize', function( e ) {
clearTimeout(id);
id = setTimeout(function() {
close();
var width = $window.width();
if ( width < 992 ) {
setHeightToNav();
$navMask.on( 'click', function() { close() } );
$navToggler.on( 'click', function() { open() } );
$parentLink.on( 'click', function( e ) {
e.preventDefault();
var $this = $( this );
$this.data( 'clicked', true );
console.log( $this.parent() );
} )
}
if ( width >= 992 ) {
resetNavHeight();
console.clear();
}
}, 500 );
} );
function setHeightToNav() {
if ( $body.hasClass( 'logged-in' ) ) {
var $wpAdminBar = $( '#wpadminbar' ).outerHeight();
$navSlider.css( { top: $wpAdminBar + 'px' } );
}
var $navHeight = $( '#header-container' ).outerHeight();
$navSlider.css( { marginTop: $navHeight + 'px' } );
}
function resetNavHeight() {
if ( $body.hasClass( 'logged-in' ) ) {
$navSlider.css( { top: 0 + 'px' } );
}
$navSlider.css( { marginTop: 0 + 'px' } );
}
function close() {
$body.removeClass( 'has-active-menu' );
setTimeout( function() {
$navSlider.removeClass( 'toggling' );
$parent.removeClass( 'show' );
$parentLink.attr( 'aria-expanded', false );
$childContainer.removeClass( 'show' ).removeAttr( 'style' );
$parentLink.data('clicked', false);
}, 250 );
console.log('close()');
}
function open() {
$body.addClass( 'has-active-menu' );
$navSlider.addClass( 'toggling' );
}
})( jQuery );
I've tried my script both with AND without the setTimeout function and it happens exactly the same.
On the project, we are using Bootstrap 4, with the Bootstraps Dropdown._clearMenus(); function commented out in the right places as it was causing conflicts with the functionality I wanted with the navigation.
A link to a site where you can see this is here. It's a WordPress site as well if that matters for anything.
Any help is appreciated. I've been at this for several hours and am at my wits end.
.on( 'click', function ) does not set the event listener, it adds an event listener. Try doing off('click') before setting it if you really need to set this listener here.
But note that any other 'click' listener for this element will also be removed.
That's for the quick fix. You could do better, but that would require more work (track with a boolean if you just changed "display mode", and add or remove the event listeners only then, for example).

Fullpage.js - video & page resizing issues

I'm using fullpage.js and I'm having a problem with the onloadedmeta function that resizes my background video.
It works perfectly when accessing the page URL directly including the section id with the video. That is to say it resizes to take up the entire screen.
If the section id I'm trying to access is not the section with the background video I see the below error - in this scenario the video resizes correctly but the remaining pages are 144px out from the top (this error fixes itself when I then go to scroll through sections).
Error: Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
When I refresh the page using any section id other than the section id that contains the background video the above error is not thrown and the pages resize correctly - but the video does not. The video is just the default size.
I haven't actually noticed this problem previously and some of the aforementioned issues do seem somewhat sporadic. Today I've been created the footer (which contains no JS) and adjusted my mobile menu a little but nothing different to what it was in terms of JS.
I've pasted the JS file below - as you'll see I'm using Fullpage in conjunction with Smoothstate.
If anyone has any suggestions or feedback I'd be eternally grateful.
Thanks very much in advance for your time,
Kind regards
Tom
Edit: all works perfectly if I remove the video from the section
( function( $ ) {
function addFullPage() {
if( $( 'html' ).hasClass( 'fp-enabled' ) ) {
$.fn.fullpage.destroy( 'all' ); // uninitialise fullpage
}
$( '#fullpage' ).fullpage( {
anchors: [ '2d', '3d', 'character','motionandgraphics', 'vfx', 'footer' ],
scrollOverflow: false,
fixedElements: '#masthead',
afterLoad: function( anchorLink, index ) {
if( index == 1 ) {
console.log( 'afterload function' );
$( '#video' ).get( 0 ).play();
}
}
} );
$( '#section0 video' ).on( 'loadedmetadata', function() {
console.log( 'onloadedmetadata function' );
var $width, $height, // Width and height of screen
$vidwidth = this.videoWidth, // Width of video (actual width)
$vidheight = this.videoHeight, // Height of video (actual height)
$aspectRatio = $vidwidth / $vidheight; // The ratio the video's height and width are in
( adjSize = function() { // Create function called adjSize
$width = $( window ).width(); // Width of the screen
$height = $( window ).height(); // Height of the screen
$boxRatio = $width / $height; // The ratio the screen is in
$adjRatio = $aspectRatio / $boxRatio; // The ratio of the video divided by the screen size
// Set the container to be the width and height of the screen
$( '#section0' ).css( { 'width' : $width+'px', 'height' : $height+'px' } );
if( $boxRatio < $aspectRatio ) { // If the screen ratio is less than the aspect ratio..
// Set the width of the video to the screen size multiplied by $adjRatio
$vid = $( '#section0 video' ).css( { 'width' : $width*$adjRatio+'px' } );
} else {
// Else just set the video to the width of the screen/container
$vid = $( '#section0 video' ).css( { 'width' : $width+'px' } );
}
} )(); // Run function immediately
// Run function also on window resize.
$( window ).resize( adjSize );
} );
function iedetect( v ) {
var r = RegExp( 'msie' + ( !isNaN(v) ? ( '\\s' + v ) : '' ), 'i' );
return r.test( navigator.userAgent );
}
}
$( document ).ready( function(){
addFullPage();
console.log( 'document ready function' );
mobMenu();
} );
function addBlacklistClass() {
$( 'a' ).each( function() {
if ( this.href.indexOf( '/wp-admin/' ) !== -1 || this.href.indexOf( '/wp-login.php' ) !== -1 ) {
$( this ).addClass( 'wp-link' );
}
} );
}
$( function() {
addBlacklistClass();
var settings = {
anchors: 'a',
blacklist: '.wp-link',
onStart: {
duration: 1000,
render: function ( $container ) {
$( '#content' ).addClass( 'fade-out' );
}
},
onAfter: function( $container ) {
addFullPage();
console.log( 'on after function in smoothstate' );
mobMenu();
$( '#content' ).removeClass( 'fade-out' );
var $hash = $( window.location.hash );
if ( $hash.length !== 0 ) {
var offsetTop = $hash.offset().top;
$( 'body, html' ).animate( {
scrollTop: ( offsetTop - 60 ),
}, {
duration: 280
} );
}
}
};
$( '#page' ).smoothState( settings );
} );
} )( jQuery );
Ultimately the cleanest solution for me was to simply use CSS to resize the video rather than JQuery. I'm also relying on the built-in functionality of Fullpage.js to play/pause the video as it goes in and out of the viewport rather than trying to manipulate it myself.
The DOM play() exception is still thrown but after much testing it doesn't seem as though it's causing any harm on the front-end.
#fullpage .section video { position:absolute; top:0; left:0; width:100%; height:100%; display:none; }
#media ( min-aspect-ratio:16/9 ) {
#fullpage .section video { width:100%; height:auto; }
}
#media ( max-aspect-ratio:16/9 ) {
#fullpage .section video { width:auto; height:100%; }
}

jquery mobile collapse if mobile device

I have a web application built on JQuery Mobile.
I've been looking for a way to have certain divs (which have data-role="collapsible") be collapsed when viewed on a mobile device, but expanded if viewed on a desktop browser.
I know there are a lot of similar questions, but I haven't been able to get any of those solutions to work. Here's what I've tried.
The divs have a class of mobileHide
<script type="text/javascript">
/*collapse non-crucial sections when viewed on mobile device*/
/* this works while resizing desktop browser, but can't resize mobile browser*/
$(window).on('resize', function(){
var w = $(window).width();
if(w >= 540 ) {
$( ".mobileHide" ).trigger( "expand" );
}else{
$( ".mobileHide" ).trigger( "collapse" );
}
});
/* Tried setting #media to make .hide-element {display:none} if screen size less than 540px (which worked in hiding that element) then set is_mobile to true. Also tried doing the same without the is_mobile and just using "if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) )"*/
$(window).resize(function() {
var is_mobile = false;
if( $('.hide-element').css('display')=='none' {
is_mobile = true;
}
if(!is_mobile) {
$( ".mobileHide" ).trigger( "expand" );
}else{
$( ".mobileHide" ).trigger( "collapse" );
}
});
/*Also tried this without being in a window.resize function. The alert works when viewed on mobile device, but the collapse and expand don't*/
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
/*alert("I am mobile!");*/
$( ".mobileHide" ).trigger( "collapse" );
} else {
$( ".mobileHide" ).trigger( "expand" );
}
</script>
I didn't have all of those running at once, but each piece that I commented on was the only part that was active at the time.
Any insight into why the last one detects mobile device and displays the alert (when it's not commented out) but won't trigger the collapse when it detects mobile device would be much appreciated!
Here is a working DEMO
The function CollapsiblesOnSize() checks the window width and then either collapses or expands all elements with class of mobileHide. You can then call this on window resize, orientation change and jQM's pageshow:
$(document).on("pageinit", "#page1", function () {
CollapsiblesOnSize();
$(window).on("resize orientationchange", function(){
CollapsiblesOnSize();
});
});
function CollapsiblesOnSize(){
var w = $(window).width();
if(w >= 540 ) {
$( ".mobileHide" ).trigger( "expand" );
}else{
$( ".mobileHide" ).trigger( "collapse" );
}
}

Responsive Button using jquery and css

I have a div with a heading using and i have a Vertical Navigation menu in same div.
To make it responsive i use media query and "Display:none and position:abolute" to Navigation Container.
it works perfectly fine till this step.
NOW what i want is that. when i click this heading the the Navigation menu appears and when i click a Link on the Navigation Menu disappears means the menu itself become"Display:none"
I used .toggle() jquery to achieve this.
when this works perfectly fine.
but problem is that i want that this .toggle() function not to work when the width of window is more then 980px;
<h2 id="heading"><span>Office<span class="blue">Managnment</span></span></h2>
<ul id="list">
<li>P</li>
<li>A</li>
<li>N</li>
<li>L</li>
<li>A</li>
<li>R</li>
<li>P</li>
</ul>
and javascript
$(function () {
$("#heading").click(function () {
$("#list").toggle();
});
$("#list").click(function () {
$("#list").toggle('hide');
});
});
and yes i tried if statement to execute this code only when the width is less then 980px but problem is that it only check for width when the page load. i.e if the window is less then 980 on load. script works fine. but when window is more then 980 on load the script do not work even on resizing it to less then 980px.
i dont understand how to achieve this. mainly problem in choosing the condition for the the if else statement.
load the window and check the width
if it is less then 980px execute the script
if it is more then 980 do not execute the script.
on resize of the window check the new width
if it was more then 980 previously
check if the width increased. if it is increased do nothing(script should not work)
check if the width is now less then 980 . START the script.Script should work now.
if it was less then 980 previosly.
check if the width increased more then 980. if it is increased STOP the script. it should not work now
check if the width is now less then 980 . Do nothing. Script should work now.
IN SHORT turn on the toggle function when width less then 980px. and turn the toggle off and set to show when width is more then 980px.
I figured it out as below. It works, but sometimes when i resize slowly it behave strangely.
var $window = $(window),
ONLOADtoggleEnabled = false,
smallscreenbefore = false;
$window.on('resize', function() {
if (smallscreenbefore == false && $window.width() > 1220) {
} else if( smallscreenbefore == false && $window.width() < 1220) {
$( "#Tablist" ).hide(400);
$( "#heading" ).click(function() {
$( "#Tablist" ).toggle(400);
});
$( "#Tablist" ).click(function() {
$( "#Tablist" ).toggle(400);
});
smallscreenbefore = true;
}
else if(smallscreenbefore == true && $window.width() > 1220 ) {
$( "#heading" ).unbind('click');
$( "#Tablist" ).unbind('click');
$( "#Tablist" ).show(400);
smallscreenbefore = false;
}
else if(smallscreenbefore == true && $window.width() < 1220 ) {
smallscreenbefore = false;
}
});
var $window = $(window);
$window.on('load', function() {
if ($window.width() < 1220) {
$( "#heading" ).click(function() {
$( "#Tablist" ).toggle(400);
});
$( "#Tablist" ).click(function() {
$( "#Tablist" ).toggle(400);
});
smallscreenbefore = true;
}
else if($window.width() > 1220) {
smallscreenbefore = false;
}
});
You can listen for the resize event on the window and then use the width to decide what you want to do. I suppose something like this should work:
var MAX_WIDTH = 980,
$window = $(window),
toggleEnabled = false;
$window.on('resize', function() {
// Check window width and check if toggle isn't already enabled
if ($window.width() < MAX_WIDTH) {
// Check if toggle isn't enabled yet
if (!toggleEnabled) {
// Use on() to add eventListener
$("#heading").on('click', function () {
$("#list").toggle();
});
$("#list").on('click', function () {
$("#list").toggle('hide');
});
toggleEnabled = true;
}
} else if (toggleEnabled) {
// Use off() to remove eventListener
$("#heading").off('click');
$("#list").off('click');
// Show the list
$('#list').show();
toggleEnabled = false;
}
$('#output').text('Width: ' + $window.width() + ', toggleEnabled: ' + toggleEnabled);
});
// You can trigger the resize event at the start to set the initial state of the menu
$window.trigger('resize');
Working version with your list: http://jsfiddle.net/srm6p/3/

Categories