以下是 jquery网页视差滚动效果代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!doctype html>
<html>
<head>
<title>jquery网页视差滚动效果</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
font-family: helvetica, arial;
padding-top: 40px;
}
h1 {
background-color: black;
color: white;
height: 40px;
font-size: 24px;
font-weight: normal;
left: 0;
line-height: 40px;
position: fixed;
text-align: center;
top: 0;
width: 100%;
z-index: 1;
}
h1 a {
border-bottom: 1px solid white;
color: white;
display: inline-block;
line-height: 30px;
text-decoration: none;
}
.photo {
background-attachment: fixed;
background-position: 50% 0;
background-repeat: no-repeat;
height: 450px;
position: relative;
}
.photo span {
bottom: 0;
color: white;
display: block;
left: 50%;
margin-left: -640px;
font-size: 38px;
padding: 10px;
position: absolute;
text-shadow: 0 2px 0 black, 0 0 10px black;
width: 1280px;
}
.summer {
background-image: url(images/summer.jpg);
}
.autumn {
background-image: url(images/autumn.jpg);
}
.winter {
background-image: url(images/winter.jpg);
}
.spring {
background-image: url(images/spring.jpg);
}
</style>
<script src="js/jquery.min.js"></script>
<script src="js/stellar.js"></script>
<script>
$(function(){
$.stellar({
horizontalScrolling: false,
verticalOffset: 40
});
});
</script>
</head>
<body>
<h1>jquery网页视差滚动效果</h1>
<div class="photo summer" data-stellar-background-ratio="0.5"><span>Summer</span></div>
<div class="photo autumn" data-stellar-background-ratio="0.5"><span>Autumn</span></div>
<div class="photo winter" data-stellar-background-ratio="0.5"><span>Winter</span></div>
<div class="photo spring" data-stellar-background-ratio="0.5"><span>Spring</span></div>
<div class="photo summer" data-stellar-background-ratio="0.5"><span>Summer</span></div>
<div class="photo autumn" data-stellar-background-ratio="0.5"><span>Autumn</span></div>
<div class="photo winter" data-stellar-background-ratio="0.5"><span>Winter</span></div>
<div class="photo spring" data-stellar-background-ratio="0.5"><span>Spring</span></div>
</body>
</html>
JS代码(stellar.js):
/* Stellar.js v0.1 * Copyright 2012,Mark Dalgleish * * This content is released under the MIT License * markdalgleish.mit-license.org */
;
(function($,window,document,undefined){
var pluginName = 'stellar',defaults ={
scrollProperty:'scroll',positionProperty:'position',horizontalScrolling:true,verticalScrolling:true,horizontalOffset:0,verticalOffset:0,parallaxBackgrounds:true,parallaxElements:true,hideDistantElements:true,viewportDetectionInterval:10000,hideElement:function($elem){
$elem.hide();
}
,showElement:function($elem){
$elem.show();
}
}
,scrollProperty ={
scroll:{
getTop:function($elem){
return $elem.scrollTop();
}
,setTop:function($elem,val){
$elem.scrollTop(val);
}
,getLeft:function($elem){
return $elem.scrollLeft();
}
,setLeft:function($elem,val){
$elem.scrollLeft(val);
}
}
,position:{
getTop:function($elem){
return parseInt($elem.css('top'),10) * -1;
}
,setTop:function($elem,val){
$elem.css('top',val);
}
,getLeft:function($elem){
return parseInt($elem.css('left'),10) * -1;
}
,setLeft:function($elem,val){
$elem.css('left',val);
}
}
,margin:{
getTop:function($elem){
return parseInt($elem.css('margin-top'),10) * -1;
}
,setTop:function($elem,val){
$elem.css('margin-top',val);
}
,getLeft:function($elem){
return parseInt($elem.css('margin-left'),10) * -1;
}
,setLeft:function($elem,val){
$elem.css('margin-left',val);
}
}
,transform:{
getTop:function($elem){
return ($elem.css(vendorPrefix + 'transform') !== 'none' ? parseInt($elem.css(vendorPrefix + 'transform').match(/(-?[0-9]+)/g)[5],10) * -1:0);
}
,setTop:function($elem,val){
setTransform($elem,val,'Y');
}
,getLeft:function($elem){
return ($elem.css(vendorPrefix + 'transform') !== 'none' ? parseInt($elem.css(vendorPrefix + 'transform').match(/(-?[0-9]+)/g)[4],10) * -1:0);
}
,setLeft:function($elem,val){
setTransform($elem,val,'X');
}
}
}
,positionProperty ={
position:{
setTop:function($elem,top){
$elem.css('top',top);
}
,setLeft:function($elem,left){
$elem.css('left',left);
}
}
,transform:{
setTop:function($elem,top,startingTop){
setTransform($elem,top - startingTop,'Y');
}
,setLeft:function($elem,left,startingLeft){
setTransform($elem,left - startingLeft,'X');
}
}
}
,vendorPrefix = (function(){
var prefix = '';
if ($.browser.webkit){
prefix = '-webkit-';
}
else if ($.browser.mozilla){
prefix = '-moz-';
}
else if ($.browser.opera){
prefix = '-o-'}
else if ($.browser.msie){
prefix = '-ms-'}
return prefix;
}
)(),setTransform = function($elem,val,dimension /* 'X' or 'Y' */
){
var currentTransform = $elem.css(vendorPrefix + 'transform');
if (currentTransform === 'none'){
$elem.css(vendorPrefix + 'transform','translate' + dimension + '(' + val + 'px)');
}
else{
$elem.css(vendorPrefix + 'transform',replaceNthOccurence(currentTransform,/(-?[0-9]+[.]?[0-9]*)/g,(dimension === 'X' ? 5:6),val));
}
}
,replaceNthOccurence = function(original,pattern,n,replace){
var parts,tempParts,indexOfNthMatch;
if (original.search(pattern) === -1){
return original;
}
parts = original.split(pattern);
indexOfNthMatch = n * 2 - 1;
if (parts[indexOfNthMatch] === undefined){
return original;
}
parts[indexOfNthMatch] = replace;
return parts.join('');
}
;
function Plugin(element,options){
this.element = element;
this.options = $.extend({
}
,defaults,options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype ={
init:function(){
this.options.name = pluginName + '_' + Math.floor(Math.random()*10000);
this._defineElements();
this._defineGetters();
this._defineSetters();
this.refresh();
this._startViewportDetectionLoop();
this._startAnimationLoop();
}
,_defineElements:function(){
this.$scrollElement = $(this.element);
this.$element = this.element === window ? $('body'):this.$scrollElement;
this.$viewportElement = (this.options.viewportElement !== undefined ? $(this.options.viewportElement):(this.$scrollElement[0] === window ? this.$scrollElement:this.$scrollElement.parent()) );
}
,_defineGetters:function(){
var self = this;
this._getScrollLeft = function(){
return scrollProperty[self.options.scrollProperty].getLeft(self.$scrollElement);
}
;
this._getScrollTop = function(){
return scrollProperty[self.options.scrollProperty].getTop(self.$scrollElement);
}
;
}
,_defineSetters:function(){
var self = this;
this._setScrollLeft = function(val){
scrollProperty[self.options.scrollProperty].setLeft(self.$scrollElement,val);
}
;
this._setScrollTop = function(val){
scrollProperty[self.options.scrollProperty].setTop(self.$scrollElement,val);
}
;
this._setLeft = function($elem,left,startingLeft){
positionProperty[self.options.positionProperty].setLeft($elem,left,startingLeft);
}
;
this._setTop = function($elem,top,startingTop){
positionProperty[self.options.positionProperty].setTop($elem,top,startingTop);
}
;
}
,refresh:function(){
var self = this;
this._setScrollLeft(0);
this._setScrollTop(0);
this._setOffsets();
this._findParticles();
this._findBackgrounds();
// Fix for Webkit background rendering bugif (navigator.userAgent.indexOf('Webkit') > 0){
$(window).load(function(){
var oldLeft = self._getScrollLeft(),oldTop = self._getScrollTop();
self._setScrollLeft(oldLeft + 1);
self._setScrollTop(oldTop + 1);
self._setScrollLeft(oldLeft);
self._setScrollTop(oldTop);
}
);
}
}
,_findParticles:function(){
var self = this,scrollLeft = this._getScrollLeft(),scrollTop = this._getScrollTop();
this.particles = [];
if (!this.options.parallaxElements) return;
this.$element.find('[data-stellar-ratio]').each(function(i){
var $this = $(this),horizontalOffset,verticalOffset,positionLeft,positionTop,$offsetParent,offsetLeft,offsetTop,parentOffsetLeft = 0,parentOffsetTop = 0,tempParentOffsetLeft = 0,tempParentOffsetTop = 0;
self.options.showElement($this);
// Save/restore the original top and left CSS values in case we refresh the particlesif ($this.data('stellar-startingLeft') === undefined){
$this.data('stellar-startingLeft',$this.css('left'));
$this.data('stellar-startingTop',$this.css('top'));
}
else{
$this.css('left',$this.data('stellar-startingLeft'));
$this.css('top',$this.data('stellar-startingTop'));
}
positionLeft = $this.position().left;
positionTop = $this.position().top;
offsetLeft = $this.offset().left - parseInt($this.css('margin-left'),10);
offsetTop = $this.offset().top - parseInt($this.css('margin-top'),10);
// Calculate the offset parent$this.parents().each(function(){
var $this = $(this);
if ($this.data('stellar-offset-parent') === true){
parentOffsetLeft = tempParentOffsetLeft;
parentOffsetTop = tempParentOffsetTop;
$offsetParent = $this;
return false;
}
else{
tempParentOffsetLeft += $this.position().left;
tempParentOffsetTop += $this.position().top;
}
}
);
// Detect the offsetshorizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset'):($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset'):self.horizontalOffset));
verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset'):($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset'):self.verticalOffset));
//Add our object to the particles collectionself.particles.push({
$element:$this,$offsetParent:$offsetParent,isFixed:$this.css('position') === 'fixed',horizontalOffset:horizontalOffset,verticalOffset:verticalOffset,startingPositionLeft:positionLeft,startingPositionTop:positionTop,startingOffsetLeft:offsetLeft,startingOffsetTop:offsetTop,parentOffsetLeft:parentOffsetLeft,parentOffsetTop:parentOffsetTop,stellarRatio:$this.data('stellar-ratio') !== undefined ? $this.data('stellar-ratio'):1,width:$this.outerWidth(true),height:$this.outerHeight(true),isHidden:false}
);
}
);
}
,_findBackgrounds:function(){
var self = this,scrollLeft = this._getScrollLeft(),scrollTop = this._getScrollTop(),$backgroundElements;
this.backgrounds = [];
if (!this.options.parallaxBackgrounds) return;
$backgroundElements = this.$element.find('[data-stellar-background-ratio]');
if (this.$element.is('[data-stellar-background-ratio]')){
$backgroundElements.add(this.$element);
}
$backgroundElements.each(function(){
var $this = $(this),backgroundPosition = $this.css('background-position').split(' '),horizontalOffset,verticalOffset,positionLeft,positionTop,offsetLeft,offsetTop;
offsetLeft = $this.offset().left - parseInt($this.css('margin-left'),10) - scrollLeft;
offsetTop = $this.offset().top - parseInt($this.css('margin-top'),10) - scrollTop;
// Detect the offsetshorizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset'):self.horizontalOffset);
verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset'):self.verticalOffset);
self.backgrounds.push({
$element:$this,isFixed:$this.css('background-attachment') === 'fixed',horizontalOffset:horizontalOffset,verticalOffset:verticalOffset,startingValueLeft:backgroundPosition[0],startingValueTop:backgroundPosition[1],startingBackgroundPositionLeft:isNaN(parseInt(backgroundPosition[0],10)) ? 0:parseInt(backgroundPosition[0],10),startingBackgroundPositionTop:isNaN(parseInt(backgroundPosition[1],10)) ? 0:parseInt(backgroundPosition[1],10),startingPositionLeft:$this.position().left,startingPositionTop:$this.position().top,startingOffsetLeft:offsetLeft,startingOffsetTop:offsetTop,stellarRatio:$this.data('stellar-background-ratio') === undefined ? 1:$this.data('stellar-background-ratio')}
);
}
);
}
,_setOffsets:function(){
var self = this;
$(window).unbind('resize.horizontal-' + this.name).unbind('resize.vertical-' + this.name);
if (typeof this.options.horizontalOffset === 'function'){
this.horizontalOffset = this.options.horizontalOffset();
$(window).bind('resize.horizontal-' + this.name,function(){
self.horizontalOffset = self.options.horizontalOffset();
}
);
}
else{
this.horizontalOffset = this.options.horizontalOffset;
}
if (typeof this.options.verticalOffset === 'function'){
this.verticalOffset = this.options.verticalOffset();
$(window).bind('resize.vertical-' + this.name,function(){
self.verticalOffset = self.options.verticalOffset();
}
);
}
else{
this.verticalOffset = this.options.verticalOffset;
}
}
,_repositionElements:function(){
var scrollLeft = this._getScrollLeft(),scrollTop = this._getScrollTop(),horizontalOffset,verticalOffset,particle,fixedRatioOffset,background,bgLeft,bgTop,isVisibleVertical = true,isVisibleHorizontal = true,newPositionLeft,newPositionTop,newOffsetLeft,newOffsetTop;
//First check that the scroll position or container size has changedif (this.currentScrollLeft === scrollLeft && this.currentScrollTop === scrollTop && this.currentWidth === this.viewportWidth && this.currentHeight === this.viewportHeight){
return;
}
else{
this.currentScrollLeft = scrollLeft;
this.currentScrollTop = scrollTop;
this.currentWidth = this.viewportWidth;
this.currentHeight = this.viewportHeight;
}
//Reposition elementsfor (var i = this.particles.length - 1;
i >= 0;
i--){
particle = this.particles[i];
fixedRatioOffset = particle.isFixed ? 1:0;
//Calculate position,then calculate what the particle's new offset will be (for visibility check)if (this.options.horizontalScrolling){
newPositionLeft = (scrollLeft + particle.horizontalOffset + this.viewportOffsetLeft + particle.startingPositionLeft - particle.startingOffsetLeft + particle.parentOffsetLeft) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionLeft;
newOffsetLeft = newPositionLeft - particle.startingPositionLeft + particle.startingOffsetLeft;
}
if (this.options.verticalScrolling){
newPositionTop = (scrollTop + particle.verticalOffset + this.viewportOffsetTop + particle.startingPositionTop - particle.startingOffsetTop + particle.parentOffsetTop) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionTop;
newOffsetTop = newPositionTop - particle.startingPositionTop + particle.startingOffsetTop;
}
//Check visibilityif (this.options.hideDistantElements){
isVisibleHorizontal = !this.options.horizontalScrolling || newOffsetLeft + particle.width > (particle.isFixed ? 0:scrollLeft) && newOffsetLeft < (particle.isFixed ? 0:scrollLeft) + this.viewportWidth + this.viewportOffsetLeft;
isVisibleVertical = !this.options.verticalScrolling || newOffsetTop + particle.height > (particle.isFixed ? 0:scrollTop) && newOffsetTop < (particle.isFixed ? 0:scrollTop) + this.viewportHeight + this.viewportOffsetTop;
}
if (isVisibleHorizontal && isVisibleVertical){
if (particle.isHidden){
this.options.showElement(particle.$element);
particle.isHidden = false;
}
if (this.options.horizontalScrolling){
this._setLeft(particle.$element,newPositionLeft,particle.startingPositionLeft);
}
if (this.options.verticalScrolling){
this._setTop(particle.$element,newPositionTop,particle.startingPositionTop);
}
}
else{
if (!particle.isHidden){
this.options.hideElement(particle.$element);
particle.isHidden = true;
}
}
}
//Reposition backgroundsfor (var i = this.backgrounds.length - 1;
i >= 0;
i--){
background = this.backgrounds[i];
fixedRatioOffset = background.isFixed ? 0:1;
bgLeft = this.options.horizontalScrolling ? (scrollLeft - background.horizontalOffset - this.viewportOffsetLeft - background.startingOffsetLeft - background.startingBackgroundPositionLeft) * (fixedRatioOffset - background.stellarRatio) + 'px':background.startingValueLeft;
bgTop = this.options.verticalScrolling ? (scrollTop - background.verticalOffset - this.viewportOffsetTop - background.startingOffsetTop - background.startingBackgroundPositionTop) * (fixedRatioOffset - background.stellarRatio) + 'px':background.startingValueTop;
background.$element.css('background-position',bgLeft + ' ' + bgTop);
}
}
,_startViewportDetectionLoop:function(){
var self = this,detect = function(){
var viewportOffsets = self.$viewportElement.offset();
self.viewportWidth = self.$viewportElement.width();
self.viewportHeight = self.$viewportElement.height();
self.viewportOffsetTop = viewportOffsets !== null ? viewportOffsets.top:0;
self.viewportOffsetLeft = viewportOffsets !== null ? viewportOffsets.left:0;
}
;
detect();
setInterval(detect,this.options.viewportDetectionInterval);
}
,_startAnimationLoop:function(){
var self = this,requestAnimFrame = (function(){
return window.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||window.msRequestAnimationFrame ||function(callback,element){
window.setTimeout(callback,1000 / 60);
}
;
}
)();
(function animloop(){
requestAnimFrame(animloop);
self._repositionElements();
}
)();
}
}
;
$.fn[pluginName] = function (options){
var args = arguments;
if (options === undefined || typeof options === 'object'){
return this.each(function (){
if (!$.data(this,'plugin_' + pluginName)){
$.data(this,'plugin_' + pluginName,new Plugin(this,options));
}
}
);
}
else if (typeof options === 'string' && options[0] !== '_' && options !== 'init'){
return this.each(function (){
var instance = $.data(this,'plugin_' + pluginName);
if (instance instanceof Plugin && typeof instance[options] === 'function'){
instance[options].apply(instance,Array.prototype.slice.call(args,1));
}
}
);
}
}
;
$[pluginName] = function(options){
var $window = $(window);
return $window.stellar.apply($window,Array.prototype.slice.call(arguments,0));
}
;
//Expose the scroll and position property function hashes so they can be extended$[pluginName].scrollProperty = scrollProperty;
$[pluginName].positionProperty = positionProperty;
}
)(jQuery,window,document);