以下是 jquery右侧跟随悬浮固定窗口js代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jquery右侧跟随悬浮固定窗口</title>
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
* {margin:0;padding:0; list-style:none;font-size:12px;}
#wrapper{ width:400px; height:auto; margin:100px auto 0 auto; overflow:hidden;}
#content p{ color:#999; line-height:180%;}
/* 以下是主要的css样式 */
#content {width:240px; float:left; min-height:1200px;}
#sidebar {width:140px; background:#ccc; float:right; height:300px; padding:10px;}
#portamento_container {float:right; position:relative;}
#portamento_container #sidebar {float:none; position:absolute;}
#portamento_container #sidebar.fixed {position:fixed;}
</style>
</head>
<body>
<div id="wrapper">
<div id="content">
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
<p>不用理我啦,我是来占位打酱油滴.....</p>
</div>
<div id="sidebar">
<p>大家好,我是右侧浮动窗口,默认我是很正常的哦。鼠标下拉看看嘛,我会始终定位在浏览器这里的哦</p>
</div>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/portamento.js"></script>
<script>
$('#sidebar').portamento({disableWorkaround: true});
</script>
</body>
</html>
JS代码(portamento.js):
/*! * * Portamento v1.1.1 - 2011-09-02 * http://simianstudios.com/portamento * * Copyright 2011 Kris Noble except where noted. * * Dual-licensed under the GPLv3 and Apache 2.0 licenses:* http://www.gnu.org/licenses/gpl-3.0.html * http://www.apache.org/licenses/LICENSE-2.0 * */
/** * * Creates a sliding panel that respects the boundaries of * a given wrapper,and also has sensible behaviour if the * viewport is too small to display the whole panel. * * Full documentation at http://simianstudios.com/portamento * * ---- * * Uses the viewportOffset plugin by Ben Alman aka Cowboy:* http://benalman.com/projects/jquery-misc-plugins/#viewportoffset * * Uses a portion of CFT by Juriy Zaytsev aka Kangax:* http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED * * Uses code by Matthew Eernisse:* http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels * * Builds on work by Remy Sharp:* http://jqueryfordesigners.com/fixed-floating-elements/ * */
(function($){
$.fn.portamento = function(options){
// we'll use the window and document objects a lot,so// saving them as variables now saves a lot of function callsvar thisWindow = $(window);
var thisDocument = $(document);
/** * NOTE by Kris - included here so as to avoid namespace clashes. * * jQuery viewportOffset - v0.3 - 2/3/2010 * http://benalman.com/projects/jquery-misc-plugins/ * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ */
$.fn.viewportOffset = function(){
var win = $(window);
var offset = $(this).offset();
return{
left:offset.left - win.scrollLeft(),top:offset.top - win.scrollTop()}
;
}
;
/** * * A test to see if position:fixed is supported. * Taken from CFT by Kangax - http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED * Included here so as to avoid namespace clashes. * */
function positionFixedSupported (){
var container = document.body;
if (document.createElement && container && container.appendChild && container.removeChild){
var el = document.createElement("div");
if (!el.getBoundingClientRect){
return null;
}
el.innerHTML = "x";
el.style.cssText = "position:fixed;
top:100px;
";
container.appendChild(el);
var originalHeight = container.style.height,originalScrollTop = container.scrollTop;
container.style.height = "3000px";
container.scrollTop = 500;
var elementTop = el.getBoundingClientRect().top;
container.style.height = originalHeight;
var isSupported = elementTop === 100;
container.removeChild(el);
container.scrollTop = originalScrollTop;
return isSupported;
}
return null;
}
/** * * Get the scrollbar width by Matthew Eernisse. * http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels * Included here so as to avoid namespace clashes. * */
function getScrollerWidth(){
var scr = null;
var inn = null;
var wNoScroll = 0;
var wScroll = 0;
// Outer scrolling div scr = document.createElement('div');
scr.style.position = 'absolute';
scr.style.top = '-1000px';
scr.style.left = '-1000px';
scr.style.width = '100px';
scr.style.height = '50px';
// Start with no scrollbar scr.style.overflow = 'hidden';
// Inner content div inn = document.createElement('div');
inn.style.width = '100%';
inn.style.height = '200px';
// Put the inner div in the scrolling div scr.appendChild(inn);
// Append the scrolling div to the doc document.body.appendChild(scr);
// Width of the inner div sans scrollbar wNoScroll = inn.offsetWidth;
// Add the scrollbar scr.style.overflow = 'auto';
// Width of the inner div width scrollbar wScroll = inn.offsetWidth;
// Remove the scrolling div from the doc document.body.removeChild(document.body.lastChild);
// Pixel width of the scroller return (wNoScroll - wScroll);
}
// ---------------------------------------------------------------------------------------------------// get the definitive optionsvar opts = $.extend({
}
,$.fn.portamento.defaults,options);
// setup the vars accordinglyvar panel = this;
var wrapper = opts.wrapper;
var gap = opts.gap;
var disableWorkaround = opts.disableWorkaround;
var fullyCapableBrowser = positionFixedSupported();
if(panel.length != 1){
// die gracefully if the user has tried to pass multiple elements// (multiple element support is on the TODO list!) or no elements...return this;
}
if(!fullyCapableBrowser && disableWorkaround){
// just stop here,as the dev doesn't want to use the workaroundreturn this;
}
// wrap the floating panel in a div,then set a sensible min-height and widthpanel.wrap('<div id="portamento_container" />');
var float_container = $('#portamento_container');
float_container.css({
'min-height':panel.outerHeight(),'width':panel.outerWidth()}
);
// calculate the upper scrolling boundaryvar panelOffset = panel.offset().top;
var panelMargin = parseFloat(panel.css('marginTop').replace(/auto/,0));
var realPanelOffset = panelOffset - panelMargin;
var topScrollBoundary = realPanelOffset - gap;
// a couple of numbers to account for margins and padding on the relevant elementsvar wrapperPaddingFix = parseFloat(wrapper.css('paddingTop').replace(/auto/,0));
var containerMarginFix = parseFloat(float_container.css('marginTop').replace(/auto/,0));
// do some work to fix IE misreporting the document widthvar ieFix = 0;
var isMSIE = /*@cc_on!@*/
0;
if (isMSIE){
ieFix = getScrollerWidth() + 4;
}
// ---------------------------------------------------------------------------------------------------thisWindow.bind("scroll.portamento",function (){
if(thisWindow.height() > panel.outerHeight() && thisWindow.width() >= (thisDocument.width() - ieFix)){
// don't scroll if the window isn't big enoughvar y = thisDocument.scrollTop();
// current scroll position of the documentif (y >= (topScrollBoundary)){
// if we're at or past the upper scrolling boundaryif((panel.innerHeight() - wrapper.viewportOffset().top) - wrapperPaddingFix + gap >= wrapper.height()){
// if we're at or past the bottom scrolling boundaryif(panel.hasClass('fixed') || thisWindow.height() >= panel.outerHeight()){
// check that there's work to dopanel.removeClass('fixed');
panel.css('top',(wrapper.height() - panel.innerHeight()) + 'px');
}
}
else{
// if we're somewhere in the middlepanel.addClass('fixed');
if(fullyCapableBrowser){
// supports position:fixedpanel.css('top',gap + 'px');
// to keep the gap}
else{
panel.clearQueue();
panel.css('position','absolute').animate({
top:(0 - float_container.viewportOffset().top + gap)}
);
}
}
}
else{
// if we're above the top scroll boundarypanel.removeClass('fixed');
panel.css('top','0');
// remove any added gap}
}
else{
panel.removeClass('fixed');
}
}
);
// ---------------------------------------------------------------------------------------------------thisWindow.bind("resize.portamento",function (){
// stop users getting undesirable behaviour if they resize the window too smallif(thisWindow.height() <= panel.outerHeight() || thisWindow.width() < thisDocument.width()){
if(panel.hasClass('fixed')){
panel.removeClass('fixed');
panel.css('top','0');
}
}
else{
thisWindow.trigger('scroll.portamento');
// trigger the scroll event to place the panel correctly}
}
);
// ---------------------------------------------------------------------------------------------------thisWindow.bind("orientationchange.portamento",function (){
// if device orientation changes,trigger the resize eventthisWindow.trigger('resize.portamento');
}
);
// ---------------------------------------------------------------------------------------------------// trigger the scroll event immediately so that the panel is positioned correctly if the page loads anywhere other than the top.thisWindow.trigger('scroll.portamento');
// return this to maintain chainability return this;
}
;
// set some sensible defaults$.fn.portamento.defaults ={
'wrapper':$('body'),// the element that will act as the sliding panel's boundaries 'gap':10,// the gap (in pixels) left between the top of the viewport and the top of the panel 'disableWorkaround':false // option to disable the workaround for not-quite capable browsers}
;
}
)(jQuery);