使用步骤
1. 下载所需文件
这里提供原生 JavaScript 和 jQuery 两个版本可供下载:
从 GitHub 下载
2. 插入 JavaScript 和添加执行脚本
在页面底部 </body> 之前加入代码, 原生 JavaScript 例子如下:
<script src="sidebar-follow.js"></script>
<script>
/* <![CDATA[ */
(new SidebarFollow()).init({
element: 'sidebar-follow',
distanceToTop: 15
});
/* ]]> */
</script>
使用 jQuery 环境的例子如下:
<script src="jquery.js"></script> <!-- 如果已在网站的其他地方引入 jQuery, 请不要在次引入 -->
<script src="sidebar-follow-jquery.js"></script>
<script>
/* <![CDATA[ */
(new SidebarFollow()).init({
element: jQuery('#sidebar-follow'),
distanceToTop: 15
});
/* ]]> */
</script>
以上两段代码,请根据自己的环境选择,择其一使用即可。
后话
这个区域主要用于了推荐热门文章和增加广告展示, 希望增加用户逗留时间和广告点击率. 侧边栏跟随功能的开发很简单, 我一直不做是担心页面太多浮动区域影响用户阅读, 但现在页面跟随区域已经被广泛使用, 用户也习惯了那我也跟风加上. 现分享出来, 希望对其他站长也有帮助.
jquery 版本:
/** * @author: mg12 [http://www.neoease.com/] * @update: 2012/12/05 */ SidebarFollow = function() { this.config = { element: null, // 处理的节点 distanceToTop: 0 // 节点上边到页面顶部的距离 }; this.cache = { originalToTop: 0, // 原本到页面顶部的距离 prevElement: null, // 上一个节点 parentToTop: 0, // 父节点的上边到顶部距离 placeholder: jQuery('<div>') // 占位节点 } }; SidebarFollow.prototype = { init: function(config) { this.config = config || this.config; var _self = this; var element = jQuery(_self.config.element); // 如果没有找到节点, 不进行处理 if(element.length <= 0) { return; } // 获取上一个节点 var prevElement = element.prev(); while(prevElement.is(':hidden')) { prevElement = prevElement.prev(); if(prevElement.length <= 0) { break; } } _self.cache.prevElement = prevElement; // 计算父节点的上边到顶部距离 var parent = element.parent(); var parentToTop = parent.offset().top; var parentBorderTop = parent.css('border-top'); var parentPaddingTop = parent.css('padding-top'); _self.cache.parentToTop = parentToTop + parentBorderTop + parentPaddingTop; // 滚动屏幕 jQuery(window).scroll(function() { _self._scrollScreen({element:element, _self:_self}); }); // 改变屏幕尺寸 jQuery(window).resize(function() { _self._scrollScreen({element:element, _self:_self}); }); }, /** * 修改节点位置 */ _scrollScreen: function(args) { var _self = args._self; var element = args.element; var prevElement = _self.cache.prevElement; // 获得到顶部的距离 var toTop = _self.config.distanceToTop; // 如果 body 有 top 属性, 消除这些位移 var bodyToTop = parseInt(jQuery('body').css('top'), 10); if(!isNaN(bodyToTop)) { toTop += bodyToTop; } // 获得到顶部的绝对距离 var elementToTop = element.offset().top - toTop; // 如果存在上一个节点, 获得到上一个节点的距离; 否则计算到父节点顶部的距离 var referenceToTop = 0; if(prevElement && prevElement.length === 1) { referenceToTop = prevElement.offset().top + prevElement.outerHeight(); } else { referenceToTop = _self.cache.parentToTop - toTop; } // 当节点进入跟随区域, 跟随滚动 if(jQuery(document).scrollTop() > elementToTop) { // 添加占位节点 var elementHeight = element.outerHeight(); _self.cache.placeholder.css('height', elementHeight).insertBefore(element); // 记录原位置 _self.cache.originalToTop = elementToTop; // 修改样式 element.css({ top: toTop + 'px', position: 'fixed' }); // 否则回到原位 } else if(_self.cache.originalToTop > elementToTop || referenceToTop > elementToTop) { // 删除占位节点 _self.cache.placeholder.remove(); // 修改样式 element.css({ position: 'static' }); } } }; js版本:
/** * @author: mg12 [http://www.neoease.com/] * @update: 2012/12/05 */ SidebarFollow = function() { this.config = { element: null, // 处理的节点 distanceToTop: 0 // 节点上边到页面顶部的距离 }; this.cache = { originalToTop: 0, // 原本到页面顶部的距离 prevElement: null, // 上一个节点 parentToTop: 0, // 父节点的上边到顶部距离 placeholder: document.createElement('div') // 占位节点 } }; SidebarFollow.prototype = { init: function(config) { this.config = config || this.config; var _self = this; var element = document.getElementById(_self.config.element); var prevElement = document.getElementById(_self.config.prevElement); // 如果没有找到节点, 不进行处理 if(!element) { return; } // 获取上一个节点 var prevElement = _self._getPrevElement(element); while(prevElement.offsetHeight < 0) { prevElement = _self._getPrevElement(prevElement); if(!prevElement) { break; } } _self.cache.prevElement = prevElement; // 计算父节点的上边到顶部距离 var parent = element.parentNode; var parentToTop = _self._getCumulativeOffset(parent).top; var parentBorderTop = parseInt(parent.style.borderTop, 10); var parentPaddingTop = parseInt(parent.style.paddingTop, 10); _self.cache.parentToTop = parentToTop + parentBorderTop + parentPaddingTop; // 滚动屏幕 _self._addListener(window, 'scroll', function() { _self._scrollScreen({element:element, prevElement:prevElement, _self:_self}); }); // 改变屏幕尺寸 _self._addListener(window, 'resize', function() { _self._scrollScreen({element:element, prevElement:prevElement, _self:_self}); }); }, /** * 修改节点位置 */ _scrollScreen: function(args) { var _self = args._self; var element = args.element; var prevElement = args.prevElement; var toTop = _self.config.distanceToTop; // 如果 body 有 top 属性, 消除这些位移 var bodyToTop = parseInt(document.getElementsByTagName('body')[0].style.top, 10); if(!isNaN(bodyToTop)) { toTop += bodyToTop; } var elementToTop = 0; if(element.style.position === 'fixed') { elementToTop = _self._getScrollY(); } else { elementToTop = _self._getCumulativeOffset(element).top - toTop; } var elementToPrev = _self._getCumulativeOffset(prevElement).top + _self._getVisibleSize(prevElement).height; // 当节点进入跟随区域, 跟随滚动 if(_self._getScrollY() > elementToTop) { // 添加占位节点 var elementHeight = _self._getVisibleSize(element).height; _self.cache.placeholder.style.height = elementHeight + 'px'; element.parentNode.insertBefore(_self.cache.placeholder, element); // 记录原位置 _self.cache.originalToTop = elementToTop; // 修改样式 element.style.top = toTop + 'px'; element.style.position = 'fixed'; // 否则回到原位 } else if(_self.cache.originalToTop > elementToTop || elementToPrev > elementToTop) { var parent = _self.cache.placeholder.parentNode; if(parent) { // 删除占位节点 parent.removeChild(_self.cache.placeholder); // 修改样式 element.style.position = 'static'; } } }, /** * 获取累计偏移量, 即元素到页面左上角的横行和纵向距离 */ _getCumulativeOffset: function(element) { var offset = { left:0, top:0 }; do { offset.left += element.offsetLeft || 0; offset.top += element.offsetTop || 0; element = element.offsetParent; } while (element); return offset; }, /** * 获取元素可见尺寸 (包括边线和滚动条) */ _getVisibleSize: function(element) { var dimension = { width:0, height:0 }; dimension.width = element.offsetWidth; dimension.height = element.offsetHeight; return dimension; }, /** * 获得滚动条纵向距离 */ _getScrollY: function() { if(typeof window.pageYOffset != 'undefined') { return window.pageYOffset; } if(typeof document.compatMode != 'undefined' && document.compatMode != 'BackCompat') { return document.documentElement.scrollTop; } return document.body.scrollTop; }, /** * 添加监听事件 */ _addListener: function(node, type, listener) { if(node.addEventListener) { node.addEventListener(type, listener, false); return true; } else if(node.attachEvent) { node['e' + type + listener] = listener; node[type + listener] = function() { node['e' + type + listener](window.event); }; node.attachEvent('on' + type, node[type + listener]); return true; } return false; }, /** * 获取上一个节点 */ _getPrevElement: function(element) { var prev = element.previousSibling; while(prev.nodeType !== 1) { prev = prev.previousSibling; } return prev; } };
分类: web
标签:
搜索
标签
study
ab
amap
apache
apahe
awk
aws
bat
centos
CFS
chrome
cmd
cnpm
composer
consul
crontab
css
curl
cygwin
devops
di
docker
docker,docker-compose
ethereum
excel
fiddler
fluentd
framework
front-end
git
gitgui
github
glide
go
golang
gorm
grafana
gzip
ioc
item2
iterm2
javascript
jenkins
jsonp
kafka
laradock
laravel
larval
linux
liunux
log
mac
mac, wi-fi
macos
magento
mariaDB
minikube
mongoDB
msp
mysql
netbeans
nginx
nodejs
nohup
npm
nsq
oracle
php
php-fpm
php7
phpstorm
php扩展
Protobuf
python
redis
scp
server
shell
soap
socket
socket5
sql
sre
ssdb
ssh
ssl
study
sublime
swift
system
td-agent
uml
v2ray
vagrant
vagrnat
vim
vpn
vue
vue.js
webpack
webrtc
websocket
webtatic
windows
windows7
word
wps
xdebug
yarn
yii2
yum
zookeeper
世界国家
互联网
以太坊
分类
前端
小程序
打印机
排序算法
搞笑
权限
粤语
缓存
网络
虚拟机
视频
设计模式
项目管理
热门文章
友情链接