我坚持使用页面滚动效果。
这是我迄今为止所做的 - https://codepen.io/DCRSLG/pen/jzYJeY
$(document).ready(function($) {
//variables
var hijacking = $('body').data('hijacking'),
animationType = $('body').data('animation'),
delta = 0,
scrollThreshold = 5,
actual = 1,
animating = false;
//DOM elements
var sectionsAvailable = $('.cd-section'),
verticalNav = $('.cd-vertical-nav'),
prevArrow = verticalNav.find('a.cd-prev'),
nextArrow = verticalNav.find('a.cd-next');
//check the media query and bind corresponding events
var MQ = deviceType(),
bindToggle = false;
bindEvents(MQ, true);
$(window).on('resize', function() {
MQ = deviceType();
bindEvents(MQ, bindToggle);
if (MQ == 'mobile') bindToggle = true;
if (MQ == 'desktop') bindToggle = false;
});
function bindEvents(MQ, bool) {
if (MQ == 'desktop' && bool) {
//bind the animation to the window scroll event, arrows click and keyboard
if (hijacking == 'on') {
initHijacking();
$(window).on('DOMMouseScroll mousewheel', scrollHijacking);
} else {
scrollAnimation();
$(window).on('scroll', scrollAnimation);
}
prevArrow.on('click', prevSection);
nextArrow.on('click', nextSection);
$('a[href*="#"]').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var target = $(this).attr('href');
$(target).velocity('scroll', {
duration: 3000,
offset: 0,
easing: 'ease-in-out',
mobileHA: false
});
});
$(document).on('keydown', function(event) {
if (event.which == '40' && !nextArrow.hasClass('inactive')) {
event.preventDefault();
nextSection();
} else if (event.which == '38' && (!prevArrow.hasClass('inactive') || (prevArrow.hasClass('inactive') && $(window).scrollTop() != sectionsAvailable.eq(0).offset().top))) {
event.preventDefault();
prevSection();
}
});
//set navigation arrows visibility
checkNavigation();
} else if (MQ == 'mobile') {
//reset and unbind
resetSectionStyle();
$(window).off('DOMMouseScroll mousewheel', scrollHijacking);
$(window).off('scroll', scrollAnimation);
prevArrow.off('click', prevSection);
nextArrow.off('click', nextSection);
$(document).off('keydown');
}
}
function scrollAnimation() {
//normal scroll - use requestAnimationFrame (if defined) to optimize performance
(!window.requestAnimationFrame) ? animateSection(): window.requestAnimationFrame(animateSection);
}
function animateSection() {
var scrollTop = $(window).scrollTop(),
windowHeight = $(window).height(),
windowWidth = $(window).width();
sectionsAvailable.each(function() {
var actualBlock = $(this),
offset = scrollTop - actualBlock.offset().top;
//according to animation type and window scroll, define animation parameters
var animationValues = setSectionAnimation(offset, windowHeight, animationType);
transformSection(actualBlock.children('div'), animationValues[0], animationValues[1], animationValues[2], animationValues[3], animationValues[4]);
(offset >= 0 && offset < windowHeight) ? actualBlock.addClass('visible'): actualBlock.removeClass('visible');
});
checkNavigation();
}
function transformSection(element, translateY, scaleValue, rotateXValue, opacityValue, boxShadow) {
//transform sections - normal scroll
element.velocity({
translateY: translateY + 'vh',
scale: scaleValue,
rotateX: rotateXValue,
opacity: opacityValue,
boxShadowBlur: boxShadow + 'px',
translateZ: 0,
}, 0);
}
function initHijacking() {
// initialize section style - scrollhijacking
var visibleSection = sectionsAvailable.filter('.visible'),
topSection = visibleSection.prevAll('.cd-section'),
bottomSection = visibleSection.nextAll('.cd-section'),
animationParams = selectAnimation(animationType, false),
animationVisible = animationParams[0],
animationTop = animationParams[1],
animationBottom = animationParams[2];
visibleSection.children('div').velocity(animationVisible, 1, function() {
visibleSection.css('opacity', 1);
topSection.css('opacity', 1);
bottomSection.css('opacity', 1);
});
topSection.children('div').velocity(animationTop, 0);
bottomSection.children('div').velocity(animationBottom, 0);
}
function scrollHijacking(event) {
// on mouse scroll - check if animate section
if (event.originalEvent.detail < 0 || event.originalEvent.wheelDelta > 0) {
delta--;
(Math.abs(delta) >= scrollThreshold) && prevSection();
} else {
delta++;
(delta >= scrollThreshold) && nextSection();
}
return false;
}
function prevSection(event) {
//go to previous section
typeof event !== 'undefined' && event.preventDefault();
var visibleSection = sectionsAvailable.filter('.visible'),
middleScroll = (hijacking == 'off' && $(window).scrollTop() != visibleSection.offset().top) ? true : false;
visibleSection = middleScroll ? visibleSection.next('.cd-section') : visibleSection;
var animationParams = selectAnimation(animationType, middleScroll, 'prev');
unbindScroll(visibleSection.prev('.cd-section'), animationParams[3]);
if (!animating && !visibleSection.is(":first-child")) {
animating = true;
visibleSection.removeClass('visible').children('div').velocity(animationParams[2], animationParams[3], animationParams[4])
.end().prev('.cd-section').addClass('visible').children('div').velocity(animationParams[0], animationParams[3], animationParams[4], function() {
animating = false;
if (hijacking == 'off') $(window).on('scroll', scrollAnimation);
});
actual = actual - 1;
}
resetScroll();
}
function nextSection(event) {
//go to next section
typeof event !== 'undefined' && event.preventDefault();
var visibleSection = sectionsAvailable.filter('.visible'),
middleScroll = (hijacking == 'off' && $(window).scrollTop() != visibleSection.offset().top) ? true : false;
var animationParams = selectAnimation(animationType, middleScroll, 'next');
unbindScroll(visibleSection.next('.cd-section'), animationParams[3]);
if (!animating && !visibleSection.is(":last-of-type")) {
animating = true;
visibleSection.removeClass('visible').children('div').velocity(animationParams[1], animationParams[3], animationParams[4])
.end().next('.cd-section').addClass('visible').children('div').velocity(animationParams[0], animationParams[3], animationParams[4], function() {
animating = false;
if (hijacking == 'off') $(window).on('scroll', scrollAnimation);
});
actual = actual + 1;
}
resetScroll();
}
function unbindScroll(section, time) {
//if clicking on navigation - unbind scroll and animate using custom velocity animation
if (hijacking == 'off') {
$(window).off('scroll', scrollAnimation);
(animationType == 'catch') ? $('body, html').scrollTop(section.offset().top): section.velocity("scroll", {
duration: time
});
}
}
function resetScroll() {
delta = 0;
checkNavigation();
}
function checkNavigation() {
//update navigation arrows visibility
(sectionsAvailable.filter('.visible').is(':first-of-type')) ? prevArrow.addClass('inactive'): prevArrow.removeClass('inactive');
(sectionsAvailable.filter('.visible').is(':last-of-type')) ? nextArrow.addClass('inactive'): nextArrow.removeClass('inactive');
}
function resetSectionStyle() {
//on mobile - remove style applied with jQuery
sectionsAvailable.children('div').each(function() {
$(this).attr('style', '');
});
}
function deviceType() {
//detect if desktop/mobile
return window.getComputedStyle(document.querySelector('body'), '::before').getPropertyValue('content').replace(/"/g, "").replace(/'/g, "");
}
function selectAnimation(animationName, middleScroll, direction) {
// select section animation - scrollhijacking
var animationVisible = 'translateNone',
animationTop = 'translateUp',
animationBottom = 'translateDown',
easing = 'ease',
animDuration = 800;
switch (animationName) {
case 'gallery':
animDuration = 1500;
if (middleScroll) {
animationTop = 'scaleDown.moveUp.scroll';
animationVisible = 'scaleUp.moveUp.scroll';
animationBottom = 'scaleDown.moveDown.scroll';
} else {
animationVisible = (direction == 'next') ? 'scaleUp.moveUp' : 'scaleUp.moveDown';
animationTop = 'scaleDown.moveUp';
animationBottom = 'scaleDown.moveDown';
}
break;
}
return [animationVisible, animationTop, animationBottom, animDuration, easing];
}
function setSectionAnimation(sectionOffset, windowHeight, animationName) {
// select section animation - normal scroll
var scale = 1,
translateY = 100,
rotateX = '0deg',
opacity = 1,
boxShadowBlur = 0;
if (sectionOffset >= -windowHeight && sectionOffset <= 0) {
// section entering the viewport
translateY = (-sectionOffset) * 100 / windowHeight;
switch (animationName) {
case 'gallery':
if (sectionOffset >= -windowHeight && sectionOffset < -0.9 * windowHeight) {
scale = -sectionOffset / windowHeight;
translateY = (-sectionOffset) * 100 / windowHeight;
boxShadowBlur = 400 * (1 + sectionOffset / windowHeight);
} else if (sectionOffset >= -0.9 * windowHeight && sectionOffset < -0.1 * windowHeight) {
scale = 0.9;
translateY = -(9 / 8) * (sectionOffset + 0.1 * windowHeight) * 100 / windowHeight;
boxShadowBlur = 40;
} else {
scale = 1 + sectionOffset / windowHeight;
translateY = 0;
boxShadowBlur = -400 * sectionOffset / windowHeight;
}
break;
}
} else if (sectionOffset > 0 && sectionOffset <= windowHeight) {
//section leaving the viewport - still has the '.visible' class
translateY = (-sectionOffset) * 100 / windowHeight;
switch (animationName) {
case 'gallery':
if (sectionOffset >= 0 && sectionOffset < 0.1 * windowHeight) {
scale = (windowHeight - sectionOffset) / windowHeight;
translateY = -(sectionOffset / windowHeight) * 100;
boxShadowBlur = 400 * sectionOffset / windowHeight;
} else if (sectionOffset >= 0.1 * windowHeight && sectionOffset < 0.9 * windowHeight) {
scale = 0.9;
translateY = -(9 / 8) * (sectionOffset - 0.1 * windowHeight / 9) * 100 / windowHeight;
boxShadowBlur = 40;
} else {
scale = sectionOffset / windowHeight;
translateY = -100;
boxShadowBlur = 400 * (1 - sectionOffset / windowHeight);
}
break;
}
} else if (sectionOffset < -windowHeight) {
translateY = 100;
switch (animationName) {
case 'gallery':
scale = 1;
break;
}
} else {
//section not visible anymore
translateY = -100;
switch (animationName) {
case 'gallery':
scale = 1;
break;
}
}
return [translateY, scale, rotateX, opacity, boxShadowBlur];
}
});
/* Custom effects registration - feature available in the Velocity UI pack */
//gallery
$.Velocity
.RegisterEffect("scaleDown.moveUp", {
defaultDuration: 1,
calls: [
[{
translateY: '-10%',
scale: '0.9',
boxShadowBlur: '40px'
}, 0.20],
[{
translateY: '-100%'
}, 0.60],
[{
translateY: '-100%',
scale: '1',
boxShadowBlur: '0'
}, 0.20]
]
});
$.Velocity
.RegisterEffect("scaleDown.moveUp.scroll", {
defaultDuration: 1,
calls: [
[{
translateY: '-100%',
scale: '0.9',
boxShadowBlur: '40px'
}, 0.60],
[{
translateY: '-100%',
scale: '1',
boxShadowBlur: '0'
}, 0.40]
]
});
$.Velocity
.RegisterEffect("scaleUp.moveUp", {
defaultDuration: 1,
calls: [
[{
translateY: '90%',
scale: '0.9',
boxShadowBlur: '40px'
}, 0.20],
[{
translateY: '0%'
}, 0.60],
[{
translateY: '0%',
scale: '1',
boxShadowBlur: '0'
}, 0.20]
]
});
$.Velocity
.RegisterEffect("scaleUp.moveUp.scroll", {
defaultDuration: 1,
calls: [
[{
translateY: '0%',
scale: '0.9',
boxShadowBlur: '40px'
}, 0.60],
[{
translateY: '0%',
scale: '1',
boxShadowBlur: '0'
}, 0.40]
]
});
$.Velocity
.RegisterEffect("scaleDown.moveDown", {
defaultDuration: 1,
calls: [
[{
translateY: '10%',
scale: '0.9',
boxShadowBlur: '40px'
}, 0.20],
[{
translateY: '100%'
}, 0.60],
[{
translateY: '100%',
scale: '1',
boxShadowBlur: '0'
}, 0.20]
]
});
$.Velocity
.RegisterEffect("scaleDown.moveDown.scroll", {
defaultDuration: 1,
calls: [
[{
translateY: '100%',
scale: '0.9',
boxShadowBlur: '40px'
}, 0.60],
[{
translateY: '100%',
scale: '1',
boxShadowBlur: '0'
}, 0.40]
]
});
$.Velocity
.RegisterEffect("scaleUp.moveDown", {
defaultDuration: 1,
calls: [
[{
translateY: '-90%',
scale: '0.9',
boxShadowBlur: '40px'
}, 0.20],
[{
translateY: '0%'
}, 0.60],
[{
translateY: '0%',
scale: '1',
boxShadowBlur: '0'
}, 0.20]
]
});
我正试图这样做,所以右侧的Dots可以作为向下滚动到每个部分的参考,如下所示:
https://codyhouse.co/demo/vertical-fixed-navigation/index.html
$('a[href*="#"]').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var target = $(this).attr('href');
$(target).velocity('scroll', {
duration: 3000,
offset: 0,
easing: 'ease-in-out',
mobileHA: false
});
});
我可以使用上面的代码让它工作,只要我在滚动条上禁用数据劫持,有没有人知道在启用数据劫持的同时让它工作的方法?