Coding conflict between two javascript files - javascript

I'm trying to get a Jekyll site setup and I want the navigation to hide when scrolling down and show when scrolling up. I also want to setup ajax loading with pushState so that I can animate page transitions. I had the navigation hiding and showing properly with scrolling until I put in the code for doing the ajax loading. Now, the navigation will hide and show properly until I click a link, then it stays shown no matter what.
I'm assuming its breaking because I'm using two different jQuery libraries, however the navigation won't work on v2 and the ajax loading won't work on v3. They both work when used on their own. I could really use some help with this.
This is what my HTML looks like for loading the files:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/history.js/1.8/bundled/html4+html5/jquery.history.js"></script>
<script src="js/ajax.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="js/hide-navigation.js"></script>
Here is the navigation.js
jQuery(document).ready(function($){
var mainHeader = $('.cd-auto-hide-header'),
secondaryNavigation = $('.cd-secondary-nav'),
//this applies only if secondary nav is below intro section
belowNavHeroContent = $('.sub-nav-hero'),
headerHeight = mainHeader.height();
var isLateralNavAnimating = false;
//set scrolling variables
var scrolling = false,
previousTop = 0,
currentTop = 0,
scrollDelta = 10,
scrollOffset = 0;
mainHeader.on('click', '.nav-trigger', function(event){
// open primary navigation on mobile
event.preventDefault();
if( !isLateralNavAnimating ) {
if($(this).parents('.csstransitions').length >= 0 ) isLateralNavAnimating = true;
mainHeader.toggleClass('nav-open');
$('.cd-navigation-wrapper').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
//animation is over
isLateralNavAnimating = false;
});
}
});
$(window).on('scroll', function(){
if( !scrolling && !mainHeader.hasClass("nav-open")) {
scrolling = true;
(!window.requestAnimationFrame)
? setTimeout(autoHideHeader, 250)
: requestAnimationFrame(autoHideHeader);
}
});
$(window).on('resize', function(){
headerHeight = mainHeader.height();
});
function autoHideHeader() {
var currentTop = $(window).scrollTop();
( belowNavHeroContent.length > 0 )
? checkStickyNavigation(currentTop) // secondary navigation below intro
: checkSimpleNavigation(currentTop);
previousTop = currentTop;
scrolling = false;
}
function checkSimpleNavigation(currentTop) {
//there's no secondary nav or secondary nav is below primary nav
if (previousTop - currentTop > scrollDelta) {
//if scrolling up...
mainHeader.removeClass('is-hidden');
} else if( currentTop - previousTop > scrollDelta && currentTop > scrollOffset) {
//if scrolling down...
mainHeader.addClass('is-hidden');
}
}
function checkStickyNavigation(currentTop) {
//secondary nav below intro section - sticky secondary nav
var secondaryNavOffsetTop = belowNavHeroContent.offset().top - secondaryNavigation.height() - mainHeader.height();
if (previousTop >= currentTop ) {
//if scrolling up...
if( currentTop < secondaryNavOffsetTop ) {
//secondary nav is not fixed
mainHeader.removeClass('is-hidden');
secondaryNavigation.removeClass('fixed slide-up');
belowNavHeroContent.removeClass('secondary-nav-fixed');
} else if( previousTop - currentTop > scrollDelta ) {
//secondary nav is fixed
mainHeader.removeClass('is-hidden');
secondaryNavigation.removeClass('slide-up').addClass('fixed');
belowNavHeroContent.addClass('secondary-nav-fixed');
}
} else {
//if scrolling down...
if( currentTop > secondaryNavOffsetTop + scrollOffset ) {
//hide primary nav
mainHeader.addClass('is-hidden');
secondaryNavigation.addClass('fixed slide-up');
belowNavHeroContent.addClass('secondary-nav-fixed');
} else if( currentTop > secondaryNavOffsetTop ) {
//once the secondary nav is fixed, do not hide primary nav if you haven't scrolled more than scrollOffset
mainHeader.removeClass('is-hidden');
secondaryNavigation.addClass('fixed').removeClass('slide-up');
belowNavHeroContent.addClass('secondary-nav-fixed');
}
}
}
});
and finally the ajax.js
( function( $, History, undefined ) {
if ( !History.enabled ) {
return false;
}
var $wrap = $( "#wrap" );
$wrap.on( "click", ".page-link", function( event ) {
event.preventDefault();
if ( window.location === this.href ) {
return;
}
var pageTitle = ( this.title ) ? this.title : this.textContent;
pageTitle = ( this.getAttribute( "rel" ) === "home" ) ? pageTitle : pageTitle + " — Acme";
History.pushState( null, pageTitle, this.href );
} );
History.Adapter.bind( window, "statechange", function() {
var state = History.getState();
$.get( state.url, function( res ) {
$.each( $( res ), function( index, elem ) {
if ( $wrap.selector !== "#" + elem.id ) {
return;
}
$wrap
.html( $( elem ).html() )
.promise()
.done( function( res ) {
if ( typeof ga === "function" && res.length !== 0 ) { // Make sure the new content is added, and the 'ga()' method is available.
ga('set', {
page: window.location.pathname,
title: state.title
});
ga('send', 'pageview');
}
});
} );
} );
} );
} )( jQuery, window.History );

Related

WordPress dynamic paging - url conflict

I have downloaded theme which is static html & css template, now I'm trying to convert into wordpress dynamic template. the issue is that the static template is one page website and have some section within it. Scrolling to these section is done by jquery function that uses url to scroll to that specific section like this:
mysite.com/?page=about
so its conflict with main wordpress dynamic paging the website doesn't scroll to that specific section any more.
I've tried to change jquery code in my template but I couldn't fix it, is there a way to change the default wordpress setting in order to stop this conflict?
here the JS code :
(function(window, undefined) {
"use strict";
var Page = (function() {
var $container = $( '#container' ),
// the scroll container that wraps the articles
$scroller = $container.find( 'div.content-scroller' ),
$menu = $container.find( 'aside' ),
// menu links
$links = $menu.find( 'nav > a' ),
$articles = $container.find( 'div.content-wrapper > article' ).not(".noscroll"),
// button to scroll to the top of the page
// only shown when screen size < 715
$toTop = $container.find( 'a.totop-link' ),
// the browser nhistory object
History = window.History,
// animation options
animation = { speed : 800, easing : 'easeInOutExpo' },
// jScrollPane options
scrollOptions = { verticalGutter : 0, hideFocus : true },
// init function
init = function() {
// initialize the jScrollPane on both the menu and articles
_initCustomScroll();
// initialize some events
_initEvents();
// sets some css properties
_layout();
// jumps to the respective chapter
// according to the url
_goto();
},
_initCustomScroll = function() {
// Only add custom scroll to articles if screen size > 715.
// If not the articles will be expanded
if( $(window).width() > 767 ) {
$articles.jScrollPane( scrollOptions );
}
// add custom scroll to menu
$menu.children( 'nav' ).jScrollPane( scrollOptions );
},
_goto = function( chapter ) {
// get the url from history state (e.g. chapter=3) and extract the chapter number
var chapter = chapter || History.getState().url.queryStringToJSON().page,
isHome = ( chapter === undefined ),
// we will jump to the introduction chapter if theres no chapter
$article = $( chapter ? '#' + 'chapter' + chapter : '#' + 'introduction' );
$('#link_introduction').removeClass('active');
$('#link_about').removeClass('active');
$('#link_skills').removeClass('active');
$('#link_experience').removeClass('active');
$('#link_education').removeClass('active');
$('#link_portfolio').removeClass('active');
$('#link_contact').removeClass('active');
$('#link_'+chapter).addClass('active');
if( $article.length ) {
// left / top of the element
var left = $article.position().left,
top = $article.position().top,
// check if we are scrolling down or left
// is_v will be true when the screen size < 715
is_v = ( $(document).height() - $(window).height() > 0 ),
// animation parameters:
// if vertically scrolling then the body will animate the scrollTop,
// otherwise the scroller (div.content-scroller) will animate the scrollLeft
param = ( is_v ) ? { scrollTop : (isHome) ? top : top + $menu.outerHeight( true ) } : { scrollLeft : left },
$elScroller = ( is_v ) ? $( 'html, body' ) : $scroller;
$elScroller.stop().animate( param, animation.speed, animation.easing, function() {
// active class for selected chapter
//$articles.removeClass( 'content-active' );
//$article.addClass( 'content-active' );
} );
}
},
_saveState = function( chapter ) {
// adds a new state to the history object
// this will trigger the statechange on the window
if( History.getState().url.queryStringToJSON().page !== chapter ) {
History.pushState( null, null, '?page=' + chapter );
$('#link_introduction').removeClass('active');
$('#link_about').removeClass('active');
$('#link_skills').removeClass('active');
$('#link_experience').removeClass('active');
$('#link_education').removeClass('active');
$('#link_portfolio').removeClass('active');
$('#link_contact').removeClass('active');
$('#link_'+chapter).addClass('active');
}
},
_layout = function() {
// control the overflow property of the scroller (div.content-scroller)
var windowWidth = $(window).width();
var isipad = navigator.userAgent.toLowerCase().indexOf("ipad");
if(isipad > -1)
{
//$('.totop-link').hide();
switch( true ) {
case ( windowWidth <= 768 ) : $scroller.scrollLeft( 0 ).css( 'overflow', 'visible' ); break;
case ( windowWidth <= 1024 ): $scroller.css( 'overflow-x', 'hidden' ); break;
case ( windowWidth > 1024 ) : $scroller.css( 'overflow', 'hidden' ); break;
};
}
else
{
switch( true ) {
case ( windowWidth <= 768 ) : $scroller.scrollLeft( 0 ).css( 'overflow', 'visible' ); break;
case ( windowWidth <= 1024 ): $scroller.css( 'overflow-x', 'hidden' ); break;
case ( windowWidth > 1024 ) : $scroller.css( 'overflow', 'hidden' ); break;
};
}
},
_initEvents = function() {
_initWindowEvents();
_initMenuEvents();
_initArticleEvents();
},
_initWindowEvents = function() {
$(window).on({
// when resizing the window we need to reinitialize or destroy the jScrollPanes
// depending on the screen size
'smartresize' : function( event ) {
var isipad = navigator.userAgent.toLowerCase().indexOf("ipad");
var ismobile = navigator.userAgent.toLowerCase().indexOf("mobile");
if(isipad > -1 || ismobile > -1 )
{
}
else
{
_layout();
$('article.content').not(".noscroll").each( function() {
var $article = $(this),
aJSP = $article.data( 'jsp' );
if( $(window).width() > 767 ) {
( aJSP === undefined ) ? $article.jScrollPane( scrollOptions ) : aJSP.reinitialise();
_initArticleEvents();
}
else {
// destroy article's custom scroll if screen size <= 715px
if( aJSP !== undefined )
aJSP.destroy();
$container.off( 'click', 'article.content' );
}
});
var nJSP = $menu.children( 'nav' ).data( 'jsp' );
nJSP.reinitialise();
// jumps to the current chapter
_goto();
}
},
// triggered when the history state changes - jumps to the respective chapter
'statechange' : function( event ) {
_goto();
}
});
},
_initMenuEvents = function() {
// when we click a menu link we check which chapter the link refers to,
// and we save the state on the history obj.
// the statechange of the window is then triggered and the page/scroller scrolls to the
// respective chapter's position
$links.on( 'click', function( event ) {
var href = $(this).attr('href'),
chapter = ( href.search(/chapter/) !== -1 ) ? href.substring(8) : 0;
_saveState( chapter );
if (href.indexOf("#") != -1)
return false;
else
return true;
});
// scrolls to the top of the page.
// this button will only be visible for screen size < 715
$toTop.on( 'click', function( event ) {
$( 'html, body' ).stop().animate( { scrollTop : 0 }, animation.speed, animation.easing );
return false;
});
},
_initArticleEvents = function() {
// when we click on an article we check which chapter the article refers to,
// and we save the state on the history obj.
// the statechange of the window is then triggered and the page/scroller scrolls to the
// respective chapter's position
if($(window).width()>768)
{
$container.on( 'click', 'article.content', function( event ) {
var id = $(this).attr('id'),
chapter = ( id.search(/chapter/) !== -1 ) ? id.substring(7) : 0;
_saveState( chapter );
//return false;
});
}
};
return { init : init };
})();
Page.init();
})(window);

How to reload a page on slider navigation click

I've a problem with this slider: I want to make it slider reload the page after I'm clicking the link "next/prev" in the slider or hte thumbnail.
Can someone help me ?
$(function() {
// ======================= imagesLoaded Plugin ===============================
// https://github.com/desandro/imagesloaded
// $('#my-container').imagesLoaded(myFunction)
// execute a callback when all images have loaded.
// needed because .load() doesn't work on cached images
// callback function gets image collection as argument
// this is the container
// original: mit license. paul irish. 2010.
// contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou
$.fn.imagesLoaded = function( callback ) {
var $images = this.find('img'),
len = $images.length,
_this = this,
blank = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
function triggerCallback() {
callback.call( _this, $images );
}
function imgLoaded() {
if ( --len <= 0 && this.src !== blank ){
setTimeout( triggerCallback );
$images.off( 'load error', imgLoaded );
}
}
if ( !len ) {
triggerCallback();
}
$images.on( 'load error', imgLoaded ).each( function() {
// cached images don't fire load sometimes, so we reset src.
if (this.complete || this.complete === undefined){
var src = this.src;
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
// data uri bypasses webkit log warning (thx doug jones)
this.src = blank;
this.src = src;
}
});
return this;
};
// gallery container
var $rgGallery = $('#rg-gallery'),
// carousel container
$esCarousel = $rgGallery.find('div.es-carousel-wrapper'),
// the carousel items
$items = $esCarousel.find('ul > li'),
// total number of items
itemsCount = $items.length;
Gallery = (function() {
// index of the current item
var current = 0,
// mode : carousel || fullview
mode = 'carousel',
// control if one image is being loaded
anim = false,
init = function() {
// (not necessary) preloading the images here...
$items.add('<img src="images/ajax-loader.gif"/><img src="images/black.png"/>').imagesLoaded( function() {
// add options
_addViewModes();
// add large image wrapper
_addImageWrapper();
// show first image
_showImage( $items.eq( current ) );
});
// initialize the carousel
if( mode === 'carousel' )
_initCarousel();
},
_initCarousel = function() {
// we are using the elastislide plugin:
// http://tympanus.net/codrops/2011/09/12/elastislide-responsive-carousel/
$esCarousel.show().elastislide({
imageW : 65,
onClick : function( $item ) {
if( anim ) return false;
anim = true;
// on click show image
_showImage($item);
// change current
current = $item.index();
}
});
// set elastislide's current to current
$esCarousel.elastislide( 'setCurrent', current );
},
_addViewModes = function() {
// top right buttons: hide / show carousel
var $viewfull = $(''),
$viewthumbs = $('');
$rgGallery.prepend( $('<div class="rg-view"/>').append( $viewfull ).append( $viewthumbs ) );
$viewfull.on('click.rgGallery', function( event ) {
if( mode === 'carousel' )
$esCarousel.elastislide( 'destroy' );
$esCarousel.hide();
$viewfull.addClass('rg-view-selected');
$viewthumbs.removeClass('rg-view-selected');
mode = 'fullview';
return false;
});
$viewthumbs.on('click.rgGallery', function( event ) {
_initCarousel();
$viewthumbs.addClass('rg-view-selected');
$viewfull.removeClass('rg-view-selected');
mode = 'carousel';
return false;
});
if( mode === 'fullview' )
$viewfull.trigger('click');
},
_addImageWrapper= function() {
// adds the structure for the large image and the navigation buttons (if total items > 1)
// also initializes the navigation events
$('#img-wrapper-tmpl').tmpl( {itemsCount : itemsCount} ).prependTo( $rgGallery );
if( itemsCount > 1 ) {
// addNavigation
var $navPrev = $rgGallery.find('a.rg-image-nav-prev'),
$navNext = $rgGallery.find('a.rg-image-nav-next'),
$imgWrapper = $rgGallery.find('div.rg-image');
$navPrev.on('click.rgGallery', function( event ) {
_navigate( 'left' );
return false;
});
$navNext.on('click.rgGallery', function( event ) {
_navigate( 'right' );
return false;
});
// add touchwipe events on the large image wrapper
$imgWrapper.touchwipe({
wipeLeft : function() {
_navigate( 'right' );
},
wipeRight : function() {
_navigate( 'left' );
},
preventDefaultEvents: false
});
$(document).on('keyup.rgGallery', function( event ) {
if (event.keyCode == 39)
_navigate( 'right' );
else if (event.keyCode == 37)
_navigate( 'left' );
});
}
},
_navigate = function( dir ) {
// navigate through the large images
if( anim ) return false;
anim = true;
if( dir === 'right' ) {
if( current + 1 >= itemsCount )
current = 0;
else
++current;
}
else if( dir === 'left' ) {
if( current - 1 < 0 )
current = itemsCount - 1;
else
--current;
}
_showImage( $items.eq( current ) );
},
_showImage = function( $item ) {
// shows the large image that is associated to the $item
var $loader = $rgGallery.find('div.rg-loading').show();
$items.removeClass('selected');
$item.addClass('selected');
var $thumb = $item.find('img'),
largesrc = $thumb.data('large'),
title = $thumb.data('description');
$('<img/>').load( function() {
$rgGallery.find('div.rg-image').empty().append('<img src="' + largesrc + '"/>');
if( title )
$rgGallery.find('div.rg-caption').show().children('p').empty().text( title );
$loader.hide();
if( mode === 'carousel' ) {
$esCarousel.elastislide( 'reload' );
$esCarousel.elastislide( 'setCurrent', current );
}
anim = false;
}).attr( 'src', largesrc );
},
addItems = function( $new ) {
$esCarousel.find('ul').append($new);
$items = $items.add( $($new) );
itemsCount = $items.length;
$esCarousel.elastislide( 'add', $new );
};
return {
init : init,
addItems : addItems
};
})();
Gallery.init();
/*
Example to add more items to the gallery:
var $new = $('<li><img src="images/thumbs/1.jpg" data-large="images/1.jpg" alt="image01" data-description="From off a hill whose concave womb reworded" /></li>');
Gallery.addItems( $new );
*/
});
Here is the code for the view
<noscript>
<style>
.es-carousel ul{
display:block;
}
</style>
</noscript>
<script id="img-wrapper-tmpl" type="text/x-jquery-tmpl">
<div class="rg-image-wrapper">
{{if itemsCount > 1}}
<div class="rg-image-nav">
Previous Image
Next Image
</div>
{{/if}}
<div class="rg-image"></div>
<div class="rg-loading"></div>
<div class="rg-caption-wrapper">
<div class="rg-caption" style="display:none;">
<p></p>
</div>
</div>
</div>
</script>
</head>
<body>
<div class="container">
<div class="header">
<span>« Previous Demo: </span>Elastislide
<span class="right_ab">
Images by Shermeee
CC BY 2.0
<strong>back to the Codrops post</strong>
</span>
<div class="clr"></div>
</div><!-- header -->
<div class="content">
<h1>Responsive Image Gallery <span>A jQuery image gallery with a thumbnail carousel</span></h1>
<div id="rg-gallery" class="rg-gallery">
<div class="rg-thumbs">
<!-- Elastislide Carousel Thumbnail Viewer -->
<div class="es-carousel-wrapper">
<div class="es-nav">
<span class="es-nav-prev">Previous</span>
<span class="es-nav-next">Next</span>
</div>
<div class="es-carousel">
<ul>
<li><img src="images/thumbs/1.jpg" data-large="images/1.jpg" alt="image01" data-description="From off a hill whose concave womb reworded" /></li>
</ul>
</div>
</div>
<!-- End Elastislide Carousel Thumbnail Viewer -->
</div><!-- rg-thumbs -->
</div><!-- rg-gallery -->
</div><!-- content -->
</div><!-- container -->
Sorry if my English is not so good, but I really need to solve this.
Well I have no idea why would you do that, but if you want to reload the page every time you click on the Next and Prev buttons, including the Thumbnail you could do something like this:
$(document).ready(function() {
$('.es-nav span, .es-carousel img').on('click', function() {
location.reload();
});
});
This will reload the page when you click on the nav or an image in the thumbnail area.

Can I modify this waypoint so that it doesnt take effect until scrolling 500px down the screen

A WordPress theme I am using has this code which is what I assume initiates the themes fixed header class once the user starts to scroll down.
Is there a way to modify this so that the class is not initiated on scroll rather initiated when the user gets to a certain point down the screen such as 100px or something liek that. Here is the code.
if ( et_is_fixed_nav ) {
$('#main-content').waypoint( {
offset: function() {
if ( etRecalculateOffset ) {
et_calculate_header_values();
etRecalculateOffset = false;
}
return et_header_offset;
},
handler : function( direction ) {
if ( direction === 'down' ) {
$('#main-header').addClass( 'et-fixed-header' );
} else {
$('#main-header').removeClass( 'et-fixed-header' );
}
}
} );
It looks like your theme is using Waypoints. The link I attached shows how to adjust the offset. The function that is currently in place looks like it handles the offset somewhere else though, possibly in your Wordpress options panel. I haven't tested it but I'd imagine your code would end up looking like this:
$('#main-content').waypoint( {
offset: 100px,
handler : function( direction ) {
if ( direction === 'down' ) {
$('#main-header').addClass( 'et-fixed-header' );
} else {
$('#main-header').removeClass( 'et-fixed-header' );
}
}
} );
Thanks for the help Austin. You were right about it being handled elsewhere. With the help f a friend, I found this bit elsewhere in the file...
function et_calculate_header_values() {
var $top_header = $( '#top-header' ),
secondary_nav_height = $top_header.length && $top_header.is( ':visible' ) ? $top_header.innerHeight() : 0,
admin_bar_height = $( '#wpadminbar' ).length ? $( '#wpadminbar' ).innerHeight() : 0;
et_header_height = $( '#main-header' ).innerHeight() + secondary_nav_height - 1,
et_header_modifier = et_header_height <= 90 ? et_header_height - 29 : et_header_height - 56,
et_header_offset = et_header_modifier + admin_bar_height;
et_primary_header_top = secondary_nav_height + admin_bar_height;
}
function et_fix_slider_height() {
if ( ! $et_pb_slider.length ) return;
$et_pb_slider.each( function() {
var $slide = $(this).find( '.et_pb_slide' ),
$slide_container = $slide.find( '.et_pb_container' ),
max_height = 0;
$slide_container.css( 'min-height', 0 );
$slide.each( function() {
var $this_el = $(this),
height = $this_el.innerHeight();
if ( max_height < height )
max_height = height;
} );
And then I changed this line...
et_header_offset = et_header_modifier + admin_bar_height;
to this...
et_header_offset = et_header_modifier + admin_bar_height - 1000;
Mission accomplished. Thanks for your help austinthedeveloper and Dan Mossop. By the way, this is what is being used in the custom.js in the Divi theme by Elegant Themes just in case in helps someone else.

How do I move the parent element when swiping over an iframe?

I have a slider that detects swipes via the touchmove event and moves the content accordingly. However when there is an iframe in the content, and I slide my finger over the iframe, the page won't move because the touchmove event is intercepted by the iframe itself, not the parent page. Thus the parent div doesn't move.
This iframe also needs to remain clickable since it is an ad so I can't just cover it with another div that has a higher z-index.
What can I do in Javascript to bubble the touchmove event up to the parent? They are on the same domain. Any help would be appreciated!
The slider I am using is this - http://dezignhero.github.io/swiper.js/ (which works fine when there are no iframes in the pages)
var Swiper = function(selector, options) {
/*------- Globals -------*/
var viewportWidth = 0,
frameWidth = 0,
animating = false,
numSlides = 0,
limitEnd = 0,
goTo = 0,
currentSlide = 0,
orientation = 0;
// Swiping
var swipe = {
started : false,
startX : 0,
endX : 0,
at : 0,
strength : 0
};
// Settings
var settings = {
ease : 0.3,
swipeMin : 40,
preventAdvance : false,
container : '.container',
frame : '.page',
frameWidth : false, // accepts a number in pixels
controls : '.control',
clickEvent : 'click',
updateEvent : 'update',
controlsOnly : false,
};
/*------- Handles -------*/
var el = selector,
$parent = $(el),
$container, $controls, $frame, $prevCtrl, $nextCtrl;
/*------- Methods -------*/
var init = function(options) {
// Exit if element doesn't exist
if ( $(el).length == 0 ) return;
// Merge settings
settings = $.extend(settings, options || {});
// Initialize handles
$container = $(settings.container, el);
$controls = $(settings.controls, el);
$frame = $(settings.frame, el);
// Assign Ids to frames
$frame.each(function(i){
$(this).attr('data-id', i);
numSlides++;
});
// Add initial class
$($frame.selector+'[data-id=0]', el).addClass('current');
// Set Dimensions
resize();
// Setup CSS
$container.css({
'-webkit-transition' : 'all '+settings.ease+'s ease-out',
'-webkit-transform' : 'translate3d(0,0,0)', // Performance optimization, put onto own layer for faster start
'left' : 0
});
// Monitoring controls if they exist
if ( $controls.length > 0 ) {
// Determine whether or not to use click event
if ('ontouchstart' in document.documentElement) {
settings.clickEvent = 'touchstart';
}
// Create handlers
$prevCtrl = $(settings.controls+'[data-action=prev]');
$nextCtrl = $(settings.controls+'[data-action=next]');
// Bind behavior
$controls.on(settings.clickEvent, function(){
var self = $(this),
action = self.attr('data-action');
// Ensure action defined
if ( typeof action == 'undefined' ) return;
if ( action == 'next' && currentSlide < numSlides - 1 ) {
goTo = currentSlide + 1;
} else if ( action == 'prev' && currentSlide > 0 ) {
goTo = currentSlide - 1;
}
// Move container
jumpTo(goTo);
});
}
// Display controls correctly
if ( settings.preventAdvance ) {
disableSliding();
} else {
updateControls();
}
// Swiping
if ( !settings.controlsOnly ) {
$container[0].addEventListener('touchstart', function(e) { touchStart(e); }, false);
$container[0].addEventListener('touchmove', function(e) { touchMove(e); }, false);
$container[0].addEventListener('touchend', function(e) { touchEnd(e); }, false);
// Desktop
$container[0].addEventListener('mousedown', function(e) { touchStart(e); }, false);
$container[0].addEventListener('mousemove', function(e) { if (e.which==1) { touchMove(e); } }, false);
$container[0].addEventListener('mouseup', function(e) { touchEnd(e); }, false);
}
// Prevent anchor tags from getting in the way
$('a', el).on('touchstart click', function(){
return swipe.started ? false : true;
});
// Prevent image dragging on getting in the way
$('img', el).on('dragstart', function(){
return false;
});
// Check if Android
var ua = navigator.userAgent.toLowerCase(),
isAndroid = ua.indexOf("android") > -1;
// Orientation Change
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = (supportsOrientationChange && !isAndroid) ? "orientationchange" : "resize";
// Listener for orientation changes
window.addEventListener(orientationEvent, function() {
// Prevent 'fake' orientation calls
if ( orientation != window.orientation ) {
orientation = window.orientation;
resize(function(){
jumpTo(currentSlide);
});
}
}, false);
},
resize = function(callback){
viewportWidth = $parent.width();
frameWidth = ( settings.frameWidth ) ? settings.frameWidth : viewportWidth;
// Apply new sizes
$frame.width(frameWidth);
$container.width(frameWidth*numSlides);
// Set end limit
limitEnd = settings.frameWidth ? viewportWidth/frameWidth : numSlides;
// callback
if ( typeof callback == 'function' ) {
callback();
}
},
touchStart = function(e) {
swipe.at = getPosition(); // for touch move
// Get start point
swipe.startX = e.touches ? e.touches[0].pageX : e.pageX;
swipe.startY = e.touches ? e.touches[0].pageY : e.pageY;
swipe.endX = swipe.startX; // prevent click swiping when touchMove doesn't fire
},
touchEnd = function(e) {
swipe.started = false;
// Nullify event
e.preventDefault();
if ( animating ) return;
var moved = swipe.endX - swipe.startX,
threshold = frameWidth / 3;
goTo = currentSlide;
// Figure out closest slide
if ( Math.abs(moved) > threshold || swipe.strength > settings.swipeMin ) {
if ( moved > 0 && currentSlide > 0 ) {
goTo--;
} else if ( moved < 0 && currentSlide < limitEnd-1 ) {
goTo++;
}
}
// Jump to closest
jumpTo(goTo);
},
touchMove = function(e) {
if ( !$parent.hasClass('disabled') ) {
swipe.started = true;
var touchX = e.touches ? e.touches[0].pageX : e.pageX,
touchY = e.touches ? e.touches[0].pageY : e.pageY,
dX = touchX - swipe.startX,
dY = touchY - swipe.startY;
swipe.strength = Math.abs(touchX - swipe.endX);
swipe.endX = touchX;
// Escape if motion wrong
if ( Math.abs(dX) < Math.abs(dY) ) return;
e.preventDefault();
// Always run this so that hit the ends
animate(swipe.at+dX, false);
}
},
getPosition = function() {
// Get current point and Stay there
var style = document.defaultView.getComputedStyle($container[0], null),
transform = new WebKitCSSMatrix(style.webkitTransform);
// Return position based on direction
return transform.m41;
},
animate = function(scrollTo, ease) {
// Momentum Effect or Not
$container[0].style.webkitTransition = ( ease ) ? 'all '+settings.ease+'s ease-out' : 'none';
$container[0].style.webkitTransform = 'translate3d('+scrollTo+'px,0,0)';
// Allow animating again
if ( ease ) {
animating = true;
window.setTimeout(function(){
animating = false;
}, settings.ease*1000);
}
},
jumpTo = function(num, ease) {
// Keep within range
if ( num >= 0 && num < limitEnd ) {
// Animate
var hasEase = ( typeof ease !== 'undefined' ) ? ease : true;
animate(-num*frameWidth, hasEase);
// If new slide
if ( num != currentSlide ) {
// Update current slide
currentSlide = num;
// Update current slide
$frame.removeClass('current');
$($frame.selector+'[data-id='+currentSlide+']').addClass('current');
// Update parent to trigger update event and new slide
$parent.trigger(settings.updateEvent, [ currentSlide, Math.floor(limitEnd) ]);
// Control Buttons
updateControls();
// Disable Again
if ( settings.preventAdvance ) {
disableSliding();
}
}
}
},
updateControls = function() {
// Only run if controls exist
if ( $controls.length == 0 ) return;
if ( currentSlide >= 0 && currentSlide < limitEnd ) {
$controls.show();
if ( currentSlide == 0 ) {
$prevCtrl.hide();
} else if ( currentSlide == limitEnd-1 ) {
$nextCtrl.hide();
}
} else {
$controls.hide();
}
},
disableSliding = function() {
// Hide Controls
$('.control', el).hide();
// Add disabled flag
$parent.addClass('disabled');
},
enableSliding = function() {
// Enable control buttons
updateControls();
// Remove disabled flag
$parent.removeClass('disabled');
};
// Initialize the object
init(options);
return {
element : $parent,
jumpTo : jumpTo,
swiping : function() {
return swipe.started;
},
disableSliding : disableSliding,
enableSliding : enableSliding,
status : function() {
return {
'current' : currentSlide+1,
'total' : numSlides
}
},
next : function() {
jumpTo(currentSlide+1);
},
prev : function() {
jumpTo(currentSlide-1);
}
};
}
The problem is that the iframe swallows touch events. So on the area that you are swiping if there is any iframe, you wont be able to swipe. The only solution I know, is to cover the iframe with a transparent div and dispatch any click events to the iframe. This way touchmove event will be enabled on the iframe.
I have created a basic jquery plugin to do that here.
https://gist.github.com/agaase/6971953
Usage
$(selector).coverIframes();
This will cover any iframes inside $(selector) with a transparent div and transfer any click events.
I know it's an old question but you can use:
iframe {
pointer-events: none;
}

URL Renaming via JavaScript

I’m developing a website based on this tutorial and would like to rename the URLs from /?chapter=# to their respective navigation names, e.g. /work, /about, /services etc.
index.php:
<aside id="menu">
<div id="scroll">
<nav>
<ul>
<li>Work</li>
<li>About</li>
<li>Services</li>
<li>Blog <!-- Coming Soon... --> </li>
<li>Contact</li>
</ul>
</nav>
</div> <!-- #scroll -->
</aside> <!-- #menu -->
...
...
<div class="content-scroller">
<div class="content-wrapper">
<article class="content" id="introduction">
<div class="inner">
...
...
<article class="content" id="chapter1">
<div class="inner">
...
...
jquery.page.js:
(function(window, undefined) {
var Page = (function() {
var $container = $( '#container' ),
// the scroll container that wraps the articles
$scroller = $container.find( 'div.content-scroller' ),
$menu = $container.find( 'aside' ),
// menu links
$links = $menu.find( 'a' ),
$articles = $container.find( 'div.content-wrapper > article' ),
// button to scroll to the top of the chapter
// only shown when screen size < 960
$toTop = $container.find( 'a.totop-link' ),
// the browser nhistory object
History = window.History,
// animation options
animation = { speed : 800, easing : 'easeInOutExpo' },
// jScrollPane options
scrollOptions = { verticalGutter : 0, hideFocus : true },
// init function
init = function() {
// initialize the jScrollPane on both the menu and articles
_initCustomScroll();
// initialize some events
_initEvents();
// sets some css properties
_layout();
// jumps to the respective chapter
// according to the url
_goto();
},
_initCustomScroll = function() {
// Only add custom scroll to articles if screen size > 960.
// If not the articles will be expanded
if( $(window).width() > 960 ) {
$articles.jScrollPane( scrollOptions );
}
// add custom scroll to menu
$menu.children( '#scroll' ).jScrollPane( scrollOptions );
},
_goto = function( chapter ) {
// get the url from history state (e.g. chapter=3) and extract the chapter number
var chapter = chapter || History.getState().url.queryStringToJSON().chapter,
isHome = ( chapter === undefined ),
// we will jump to the introduction chapter if theres no chapter
$article = $( chapter ? '#' + 'chapter' + chapter : '#' + 'introduction' );
if( $article.length ) {
// left / top of the element
var left = $article.position().left,
top = $article.position().top,
// check if we are scrolling down or left
// is_v will be true when the screen size < 960
is_v = ( $(document).height() - $(window).height() > 0 ),
// animation parameters:
// if vertically scrolling then the body will animate the scrollTop,
// otherwise the scroller (div.content-scroller) will animate the scrollLeft
param = ( is_v ) ? { scrollTop : (isHome) ? top : top + $menu.outerHeight( true ) } : { scrollLeft : left },
$elScroller = ( is_v ) ? $( 'html, body' ) : $scroller;
$elScroller.stop().animate( param, animation.speed, animation.easing, function() {
// active class for selected chapter
$articles.removeClass( 'content-active' );
$article.addClass( 'content-active' );
} );
}
},
_saveState = function( chapter ) {
// adds a new state to the history object
// this will trigger the statechange on the window
if( History.getState().url.queryStringToJSON().chapter !== chapter ) {
History.pushState( null, null, '?chapter=' + chapter );
}
},
_layout = function() {
// control the overflow property of the scroller (div.content-scroller)
var windowWidth = $(window).width();
switch( true ) {
case ( windowWidth <= 960 ) : $scroller.scrollLeft( 0 ).css( 'overflow', 'visible' ); break;
case ( windowWidth <= 1024 ): $scroller.css( 'overflow-x', 'scroll' ); break;
case ( windowWidth > 1024 ) : $scroller.css( 'overflow', 'hidden' ); break;
};
},
_initEvents = function() {
_initWindowEvents();
_initMenuEvents();
_initArticleEvents();
},
_initWindowEvents = function() {
$(window).on({
// when resizing the window we need to reinitialize or destroy the jScrollPanes
// depending on the screen size
'smartresize' : function( event ) {
_layout();
$('article.content').each( function() {
var $article = $(this),
aJSP = $article.data( 'jsp' );
if( $(window).width() > 960 ) {
( aJSP === undefined ) ? $article.jScrollPane( scrollOptions ) : aJSP.reinitialise();
_initArticleEvents();
}
else {
// destroy article's custom scroll if screen size <= 960px
if( aJSP !== undefined )
aJSP.destroy();
$container.off( 'click', 'article.content' );
}
});
var nJSP = $menu.children( '#scroll' ).data( 'jsp' );
nJSP.reinitialise();
// jumps to the current chapter
_goto();
},
// triggered when the history state changes - jumps to the respective chapter
'statechange' : function( event ) {
_goto();
}
});
},
_initMenuEvents = function() {
// when we click a menu link we check which chapter the link refers to,
// and we save the state on the history obj.
// the statechange of the window is then triggered and the page/scroller scrolls to the
// respective chapter's position
$links.on( 'click', function( event ) {
var href = $(this).attr('href'),
chapter = ( href.search(/chapter/) !== -1 ) ? href.substring(8) : 0;
_saveState( chapter );
return false;
});
// scrolls to the top of the page.
// this button will only be visible for screen size < 960
$toTop.on( 'click', function( event ) {
$( 'html, body' ).stop().animate( { scrollTop : 0 }, animation.speed, animation.easing );
return false;
});
},
_initArticleEvents = function() {
// when we click on an article we check which chapter the article refers to,
// and we save the state on the history obj.
// the statechange of the window is then triggered and the page/scroller scrolls to the
// respective chapter's position
$container.on( 'click', 'article.content', function( event ) {
var id = $(this).attr('id'),
chapter = ( id.search(/chapter/) !== -1 ) ? id.substring(7) : 0;
_saveState( chapter );
// return false;
});
};
return { init : init };
})();
Page.init();
})(window);
How would I be able to do this?
Thanks
Well, this line is what's writing your history state:
History.pushState(null, null, '?chapter=' + chapter);
So you would need to modify that function to do what you want. If you have a small site then you could make conditionals to swap the state to whatever you want easily. If you have a large dynamic site you don't want to do this unless you love horrible, tedious maintenance...
_saveState = function(chapter) {
// adds a new state to the history object
// this will trigger the statechange on the window
if (History.getState().url.queryStringToJSON().chapter !== chapter) {
var page;
if(chapter == 1)
page = "/about";
else if(chapter == 2)
page = "/services";
else
page = '?chapter=' + chapter;
History.pushState(null, null, page);
}
},
I may have missed the point of your question though. If so I can update this answer

Categories