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%; }
}
Related
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).
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);
Is it possible to write a script that turns off a script at a certain screen resolution? I have these svg's that do not work properly under 480px, and I would like to turn them off. I am super new to this. Any help would be amazing.
<script>
(function() {
function init() {
var speed = 250,
easing = mina.easeinout;
[].slice.call ( document.querySelectorAll( '#grid > .container > .row .activities_home > a' ) ).forEach( function( el ) {
var s = Snap( el.querySelector( 'svg' ) ), path = s.select( 'path' ),
pathConfig = {
from : path.attr( 'd' ),
to : el.getAttribute( 'data-path-hover' )
};
el.addEventListener( 'mouseenter', function() {
path.animate( { 'path' : pathConfig.to }, speed, easing );
} );
el.addEventListener( 'mouseleave', function() {
path.animate( { 'path' : pathConfig.from }, speed, easing );
} );
} );
}
init();
})();
</script>
You can attach an event listener to the document DOMContentLoaded and window resize events to query the screen resolution (the window.innerWidth and window.innerHeight properties).
If the resolution falls below your breakpoint, then you can remove the event listeners from each of the paths (you will need a reference to the function in order to do so).
If you don't need to handle resize events and just want to initially disable the script based on the resolution, then you can do something simple like replacing:
init();
with
if (window.innerWidth > 480)
init();
So there is some code from codepen.io http://codepen.io/karolpodlesny/pen/npKqu. It is uploaded here: http://fredricarms.com/javatestindex.html.
Now, the HTML, CSS and JavaScript for making the boxes expand and do all the cool things, are working how they are supposed to, being in separate files, so is the modernizr. I also the know that the js is being called because in the boxlayout.js I wrote some code to bring up and alert box and it worked just fine. So I am guessing that codepen fixes the code so it runs perfectly. I just don't know what is wrong with the code in the boxlayout.js that is not working on my server. Please help and thank you so much. Below is the code in the boxlayout js file.
var Boxlayout = (function() {
var $el = $( '#bl-main' ),
$sections = $el.children( 'section' ),
// works section
$sectionWork = $( '#bl-work-section' ),
// work items
$workItems = $( '#bl-work-items > li' ),
// work panels
$workPanelsContainer = $( '#bl-panel-work-items' ),
$workPanels = $workPanelsContainer.children( 'div' ),
totalWorkPanels = $workPanels.length,
// navigating the work panels
$nextWorkItem = $workPanelsContainer.find( 'nav > span.bl-next-work' ),
// if currently navigating the work items
isAnimating = false,
// close work panel trigger
$closeWorkItem = $workPanelsContainer.find( 'nav > span.bl-icon-close' ),
transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
},
// transition end event name
transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
// support css transitions
supportTransitions = Modernizr.csstransitions;
function init() {
initEvents();
}
function initEvents() {
$sections.each( function() {
var $section = $( this );
// expand the clicked section and scale down the others
$section.on( 'click', function() {
if( !$section.data( 'open' ) ) {
$section.data( 'open', true ).addClass( 'bl-expand bl-expand-top' );
$el.addClass( 'bl-expand-item' );
}
} ).find( 'span.bl-icon-close' ).on( 'click', function() {
// close the expanded section and scale up the others
$section.data( 'open', false ).removeClass( 'bl-expand' ).on( transEndEventName, function( event ) {
if( !$( event.target ).is( 'section' ) ) return false;
$( this ).off( transEndEventName ).removeClass( 'bl-expand-top' );
} );
if( !supportTransitions ) {
$section.removeClass( 'bl-expand-top' );
}
$el.removeClass( 'bl-expand-item' );
return false;
} );
} );
// clicking on a work item: the current section scales down and the respective work panel slides up
$workItems.on( 'click', function( event ) {
// scale down main section
$sectionWork.addClass( 'bl-scale-down' );
// show panel for this work item
$workPanelsContainer.addClass( 'bl-panel-items-show' );
var $panel = $workPanelsContainer.find("[data-panel='" + $( this ).data( 'panel' ) + "']");
currentWorkPanel = $panel.index();
$panel.addClass( 'bl-show-work' );
return false;
} );
// navigating the work items: current work panel scales down and the next work panel slides up
$nextWorkItem.on( 'click', function( event ) {
if( isAnimating ) {
return false;
}
isAnimating = true;
var $currentPanel = $workPanels.eq( currentWorkPanel );
currentWorkPanel = currentWorkPanel < totalWorkPanels - 1 ? currentWorkPanel + 1 : 0;
var $nextPanel = $workPanels.eq( currentWorkPanel );
$currentPanel.removeClass( 'bl-show-work' ).addClass( 'bl-hide-current-work' ).on( transEndEventName, function( event ) {
if( !$( event.target ).is( 'div' ) ) return false;
$( this ).off( transEndEventName ).removeClass( 'bl-hide-current-work' );
isAnimating = false;
} );
if( !supportTransitions ) {
$currentPanel.removeClass( 'bl-hide-current-work' );
isAnimating = false;
}
$nextPanel.addClass( 'bl-show-work' );
return false;
} );
// clicking the work panels close button: the current work panel slides down and the section scales up again
$closeWorkItem.on( 'click', function( event ) {
// scale up main section
$sectionWork.removeClass( 'bl-scale-down' );
$workPanelsContainer.removeClass( 'bl-panel-items-show' );
$workPanels.eq( currentWorkPanel ).removeClass( 'bl-show-work' );
return false;
} );
}
return { init : init };
})();
Your code relies entirely on jQuery, however you haven't included jQuery on your live site. On your CodePen example you're using jQuery 1.9.1:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
You can continue to use the Google-hosted version, or if you want to host it yourself you can download jQuery from jQuery's own website.
The problem is that you need to initialize your BoxLayout once your document has finished loading (all those jQuery variables you're using inside your library won't be defined because their equivalent dom elements are not yet rendered), that's why you need to init everything when dom is ready.
Add this line of code to the bottom of your boxlayout.js file:
$(document).ready(function() {
Boxlayout.init();
});
Just for testing purposes, open up the web developer console on your website, and run this js code:
Boxlayout.init();
You'll see everything will work just fine.
I recently repurposed a template for http://c42d.com, a portfolio website I'm building for a company called C42D. My issue concerns the scrolling functionality of the navigation system.
It works properly on the homepage. When you click any link in the nav at the top, it scrolls right to that section on the page perfectly, and it takes into consideration the height of the fixed header. The following Javascript is responsible for this functionality:
/** Hash Scroll */
/** Portfolio Filter */
$( '#navbar-spy' ).off( 'click' ).on( 'click', 'a', function( e ) {
if(!$( this ).attr( 'href' ).match(/^#/)) return;
e.preventDefault();
var elmHash = $( this ).attr( 'href' );
var elmOffsetTop = Math.ceil( $( this.hash ).offset().top );
var windowOffsetTop = Math.ceil( $(window).scrollTop() );
if( elmOffsetTop != 0 ) {
elmOffsetTop = elmOffsetTop - 84;
if( windowOffsetTop == 0 ) {
elmOffsetTop = elmOffsetTop - 0;
}
}
//console.log( $( this ).attr( 'href' ) );
$( 'html:not(:animated), body:not(:animated)' ).animate({ scrollTop: elmOffsetTop }, 1100 );
});
Unfortunately, when you navigate to any interior page on the site (http://c42d.com/termsandconditions, for example) and click a link in the nav, it brings you right to the proper anchor on the homepage, but doesn't take into consideration the height of the fixed header, and the title becomes partly obscured.
Any help would be greatly appreciated.
Thank you!
Zan
What I would do is on page load, detect the hash if any, and if there is, then run that same animation code to go to that.