I am using fullpage.js to create a wp site, I wonder if it is possible change the scroll direction when the user gets to a certain page.
To explain better, let's use this this example:
http://alvarotrigo.com/fullPage/examples/navigationV.html
Is it possible for the scroll direction to change to horizontal when you visit the second slide?
So instead of clicking on the arrows to navigate horizontally, I want the mouse wheel to scroll horizontally.
Is this possible with fullpage.js or do I have to change to another script?
Okay, here's the basic method:
When you get to a page that needs horizontally scrolled, add a mousewheel listener that:
Turns scroll events into left or right slide changes and
Prevents the default for the mousewheel unless:
Last slide and scroll down or
First slide and scroll up
Turn off the listener when you enter another slide.
There is also some code to prevent things from happening while slides are loading.
var currentSlide = 0;
var loaded = false;
$('#fullpage').fullpage({
navigation: true,
navigationTooltips: ['First section', 'Second section', 'Third section'],
sectionsColor: ['#f1c40f', '#e67e22', '#c0392b'],
loopHorizontal: false,
afterLoad: function (anchorLink, index){
loaded = true;
},
afterSlideLoad: function(anchorLink, index, slideAnchor, slideIndex){
currentSlide = slideIndex;
loaded = true;
},
onLeave: function(index, nextIndex, direction) {
loaded = false;
if (nextIndex == 2) {
$('#fullpage').on("mousewheel",function(e){
if(loaded){
loaded = false;
var delta = e.originalEvent.deltaY;
console.log(delta);
if(delta>0){ //down
if(currentSlide===2){//if last slide
$('#fullpage').off("mousewheel");
}else{
$.fn.fullpage.moveSlideRight();
e.preventDefault();
e.stopPropagation();
}
}else{ //up
if(currentSlide===0){//if first slide
$('#fullpage').off("mousewheel");
}else{
$.fn.fullpage.moveSlideLeft();
e.preventDefault();
e.stopPropagation();
}
}
}else{ //slide still loading, don't scroll
e.preventDefault();
e.stopPropagation();
}
});
}
}
});
JSFiddle
This works on Chrome. I'm not sure how cross browser the e.originalEvent.deltaY bit is. You can replace the mousewheel handler with this plugin to make it properly cross platform.
Here's a JSFiddle with jquery.mousewheel for a fully cross platform solution.
Related
I'm working with two jQuery plugins fullpage and ferromenu.
fullpage makes it so that the window scrolls by entire pages and ferromenu is a neat circular menu that expands and collapses.
The problem is that since fullpage makes my entire website one page, ferromenu is shown on every single page so I don't want to just initialize it with $(document).ready
This is what I have tried but the problem I have now is that it doesn't disappear when the page changes away from the url
$(window).on('hashchange', function(e){
var pageURL = $(location).attr("href");
if (pageURL === "https://www.example.com/index.php#thirdPage") {
$("#custom-nav").ferroMenu({
position : "center-center"
});
};
});
You should be using the callbacks provided by fullPage.js such as onLeave and afterLoad:
$(document).ready(function () {
$("#custom-nav").ferroMenu({
position: "center-center"
});
$('#fullpage').fullpage({
anchors: ['firstPage', 'secondPage', 'thirdPage', 'fourthPage', 'lastPage'],
onLeave: function (index, nextIndex, direction) {
//going to section 3 ?
if (nextIndex == 3) {
$('.ferromenu-controller').show();
} else {
$('.ferromenu-controller').hide();
}
}
});
});
Or even by using the css3 class added to the body by fullpage.js as detailed in this tutorial.
I don't know if this is the best way to do it but I found the class for the html object it creates and just changed the display property in the else part of my if statement.
$(window).on('hashchange', function(e){
var pageURL = $(location).attr("href");
if (pageURL === "https://www.example.com/index.php#thirdPage") {
$("#custom-nav").ferroMenu({
position : "center-center"
});
} else {
$('.ferromenu-controller').css('display', 'none');
};
});
Prevent Scroll Script
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = [37, 38, 39, 40];
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function keydown(e) {
for (var i = keys.length; i--;) {
if (e.keyCode === keys[i]) {
preventDefault(e);
return;
}
}
}
function wheel(e) {
preventDefault(e);
}
function disable_scroll() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', wheel, false);
}
window.onmousewheel = document.onmousewheel = wheel;
document.onkeydown = keydown;
}
function enable_scroll() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', wheel, false);
}
window.onmousewheel = document.onmousewheel = document.onkeydown = null;
}
Usage
Call disable_scroll(); to disable the page scrolling and enable_scroll() to enable the scrolling once again.
The Problem
Unlike the Facebook modal box, you are still able to click and drag the page to scroll down.
JSFiddle
Link: http://jsfiddle.net/2rud0aLm/
#Terry's first sentence provides a quick solution. Simply change overflow to 'hidden' on the body to prevent scrolling.
You will also need to keep track of the window's scrolled position, and set it after changing the overflow property.
To prevent the mousewheel from being able to drag, attach a scroll event to the window, which sets scrollTop to the window's position when the modal dialog was opened:
function disable_scroll() {
var top= $(window).scrollTop();
$('body').css({
overflow: 'hidden'
});
$(window).scrollTop(top);
$(window).on('scroll', function() {
$(window).scrollTop(top);
});
}
function enable_scroll() {
var top= $(window).scrollTop();
$('body').css({
overflow: ''
});
$(window).scrollTop(top);
$(window).off('scroll');
}
Because modal_close and modal_2 in your code has href="#", the script will attempt to jump to the top of the page. You can prevent that using preventDefault:
$('a[href=#]').on('click', function(ev) {
ev.preventDefault();
});
Fiddle
Here is a rather rudimentary fix, and I will explain what I have changed in order to make it work:
CSS: For the overlay, you actually do not need to sniff the viewport dimensions. Simply setting to position: fixed with all four offsets, top, left, bottom, and right set to 0 will force it to fill the screen :)
Markup: Wrap all your page content in a container, say <div class="page-wrap">. This element is set to fixed position upon toggling of the modal box to prevent click-drag scrolling.
JS:
Set a global variable as fromTop, which we will use to track the user's scroll position.
When the modal box is opened, update scroll position. Hide vertical overflow of the body element, and vertically translate the entire page content, i.e. .page-wrap to preserve vertical location
When the modal box is closed, reverse what we have done above :) I have decided to use a callback at the end of .fadeOut() to prevent jerking.
With all that done, you don't even need to prevent the scroll event from firing, or listening to keypress events anymore. Without further ado, here is the code (here's the functional demo):
var fromTop;
$('.modal_2').click(function(){
// Disable scroll and fade in modal box
disable_scroll();
$('.block_page').fadeIn();
$('.modal_box').fadeIn();
// Fetch current scroll position
fromTop = $(window).scrollTop();
// Hide overflowing vertical content
$('body').css({
'overflow-y': 'hidden'
});
$('.page-wrap').css({
'transform': 'translateY(-'+fromTop+'px)'
});
});
$('.modal_close').click(function(e){
e.preventDefault();
// Enable scroll and fade out modal box
$('.block_page').fadeOut(function() {
// Wait for modal box to fade out before reversing things
// Hide overflowing vertical content
$('body').css({
'overflow-y': 'visible'
});
$('.page-wrap').css({
'transform': 'translateY(0)'
});
$(window).scrollTop(fromTop);
});
$(this).parent().fadeOut();
enable_scroll();
});
Proof-of-concept fiddle: http://jsfiddle.net/teddyrised/mjq8gv29/
Even better: use jQuery promises to check if fadeOut animations have been completed on both the .block_page element and the parent element. This is exceptionally important if you want to set variable animation durations for either elements:
$('.modal_close').click(function(e){
e.preventDefault();
// Enable scroll and fade out modal box
$('.block_page').fadeOut();
$(this).parent().fadeOut();
// Use jQuery promises to check if all fadeOut animation has completed
var p1 = $('.block_page').promise(),
p2 = $(this).parent().promise();
// When all animations have completed, reverse effects
$.when(p1, p2).done(function() {
// Hide overflowing vertical content
$('body').css({
'overflow-y': 'visible'
});
$('.page-wrap').css({
'transform': 'translateY(0)'
});
$(window).scrollTop(fromTop);
});
});
Advanced fiddle that uses jQuery .promise() deferred object: http://jsfiddle.net/teddyrised/2rud0aLm/6/
I am currently learning jQuery. I am having some problems with the following code. I am trying to make my website move using some buttons, but once i click them it does not seem to work. Below is my jquery code.
jQuery(document).ready(function ($) {
//initialise Stellar.js
$(window).stellar();
//Cache some variables
var links = $('.navigation').find('li');
slide = $('.slide');
button = $('.button');
mywindow = $(window);
htmlbody = $('html,body');
//Setup waypoints plugin
slide.waypoint(function (event, direction) {
//cache the variable of the data-slide attribute associated with each slide
dataslide = $(this).attr('data-slide');
//If the user scrolls up change the navigation link that has the same data-slide attribute as the slide to active and
//remove the active class from the previous navigation link
if(direction === 'down') {
$('.navigation li[data-slide="' + dataslide + '"]').addClass('active').prev().removeClass('active');
}
// else If the user scrolls down change the navigation link that has the same data-slide attribute as the slide to active and
//remove the active class from the next navigation link
else {
$('.navigation li[data-slide="' + dataslide + '"]').addClass('active').next().removeClass('active');
}
});
//waypoints doesnt detect the first slide when user scrolls back up to the top so we add this little bit of code, that removes the class
//from navigation link slide 2 and adds it to navigation link slide 1.
mywindow.scroll(function () {
if(mywindow.scrollTop() === 0) {
$('.navigation li[data-slide="1"]').addClass('active');
$('.navigation li[data-slide="2"]').removeClass('active');
}
});
//Create a function that will be passed a slide number and then will scroll to that slide using jquerys animate. The Jquery
//easing plugin is also used, so we passed in the easing method of 'easeInOutQuint' which is available throught the plugin.
function goToByScroll(dataslide) {
htmlbody.animate({
scrollTop: $('.slide[data-slide="' + dataslide + '"]').offset().top
}, 2000, 'easeInOutQuint');
}
//When the user clicks on the navigation links, get the data-slide attribute value of the link and pass that variable to the goToByScroll function
links.click(function (e) {
e.preventDefault();
dataslide = $(this).attr('data-slide');
goToByScroll(dataslide);
});
//When the user clicks on the button, get the get the data-slide attribute value of the button and pass that variable to the goToByScroll function
button.click(function (e) {
e.preventDefault();
dataslide = $(this).attr('data-slide');
goToByScroll(dataslide);
});
});
It would be great if anyone can help me solve my problem.
Put your script before the closing tag body (</body>) and include Jquery library
You may have conflictions of jquery try to use jQuery.noConflict() after adding any version of jquery like,
<script>
jQuery.noConflict();
</script>
I have a list of links in a div with overflow. What I want to happen is that the user can navigate in this menu of links with an up and down button. I want the div to scroll up or down by the height of 1 link element every time the user clicks the corresponding button. I tried out some code but I can't seem to figure out how to make it scroll the right amount in both directions. Can anyone help me out?
All the links have the same class.
Edit:
I have already managed to scroll up and down. Now I just need to scroll in little steps of the height of 1 link.
$(function() {
var ele = $('#scroller');
var speed = 10, scroll = 5, scrolling;
$('.scroller-btn-up').click(function() {
// Scroll the element up
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() - scroll );
}, speed);
});
$('.scroller-btn-down').click(function() {
// Scroll the element down
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() + scroll );
}, speed);
});
$('.scroller-btn-up, .scroller-btn-down').bind({
click: function(e) {
// Prevent the default click action
e.preventDefault();
},
mouseleave: function() {
if (scrolling) {
window.clearInterval(scrolling);
scrolling = false;
}
}
});
});
That should be easy enough using your current code, all you have to do is get rid of the interval to stop it from scrolling repeatedly. Then you won't need the mouseleave function either, you can set the scroll variable to the same value of the height of a link tag e.g. 20 for a 20px high link tag:
$(function() {
var ele = $('#scroller');
var scroll = 20;
$('.scroller-btn-up').click(function() {
// Scroll the element up
ele.scrollTop(ele.scrollTop() - scroll);
});
$('.scroller-btn-down').click(function() {
// Scroll the element down
ele.scrollTop(ele.scrollTop() + scroll);
});
$('.scroller-btn-up, .scroller-btn-down').bind({
click: function(e) {
// Prevent the default click action
e.preventDefault();
}
});
});
I want to be able to slide back to the previous page within a javascript function (android/HTML5 project). I can get back to the previous page through history.back(), however, this code will not slide back.
Is it possible to make it do the sliding as well?
Swipe solution
Here's a working example: http://jsfiddle.net/Gajotres/ru3D3/
$(document).off('swipeleft').on('swipeleft', 'article', function(event){
var nextpage = $.mobile.activePage.next('article[data-role="page"]');
// swipe using id of next page if exists
if (nextpage.length > 0) {
$.mobile.changePage(nextpage, {transition: "slide", reverse: false}, true, true);
}
});
$(document).off('swiperight').on('swiperight', 'article', function(event){
history.back();
return false;
event.handled = true;
});
This code is used to go back to previous page:
history.back();
return false;
In this line:
$(document).off('swiperight').on('swiperight'
.off(..) is used to prevent multiple swipe event binding during the page transitions. If you have more questions do not hesitate to ask.
Button solution:
Working example also here: http://jsfiddle.net/Gajotres/ru3D3/
$(document).on('pagebeforeshow', '[ data-role="page"]', function(){
$(document).off('click touchStart').on('click touchStart', '#slide-back-btn', function(){
history.back();
return false;
});
});