jQuery插件开发之windowScroll
回首望,曾经洋洋得意的代码现在不忍直视。曾经看起来碉堡的效果现在也能稍微弄点出来。社会在往前发展,人也得向前迈进。
参考于搜狗浏览器4.2版本首页的上下滚动效果。主要实现整个窗口的上下和左右滚动逻辑,还有很多可以拓展的空间。希望大家能多提意见与建议。
欢迎fork项目:https://github.com/codetker/myWindowScroll, 实现的效果见http://www.梦萦无双.xyz/myWindowScroll/demo/Default.html, 应用见http://wechat.wutnews.net/Web/PhotoWall/(尚在改善中)。
插件效果:
实现window的上下滚动,默认绑定键盘上下按钮和鼠标滑轮
实现window的左右滚动,默认绑定键盘左右按钮
可附加ul li协助控制滚动
可修改后附加缓动函数,实现多种效果,详情见缓动函数表 http://easings.net/zh-cn#easeInOutQuad
html 结构(ZenCoding形式)
-div.divClass
-div.toLeftOrTop
-div.toRightOrBottom
-div.stageClass*n -ul.controlUl
-li.liClass*n
其中div.toLeftOrTop,div.toRightOrBottom,ul.controlUl可选
调用方法(详情见demo)(按需设置参数)
A.vertical
$(".divClass").windowScroll({
'choose': 0, //垂直滚动,默认
'verticalSpeed': 1, //控制垂直滚动速度
'objControlUl': 'ul.controlUl', //控制垂直滚动按钮,默认为null
'list': '.stageClass', //垂直滚动的对象
'crash': true, //撞击底部特效
'toTop': '.toLeftOrTop', //向上按钮,默认为null
'toBottom': 'toRightOrBottom', //向下按钮,默认为null
'liHover': 'stageSelect' //设置当前stage的类名
});
B.horizontal
$(".divClass").windowScroll({
'choose': 1, //水平滚动
'horizontalSpeed': 1, //控制水平滚动速度
'objControlUl': 'ul.controlUl', //控制水平滚动按钮,默认为null
'list': '.stageClass', //水平滚动的对象
'crash': true, //撞击左右特效
'toTop': '.toLeftOrTop', //向左按钮,默认为null
'toBottom': 'toRightOrBottom', //向右按钮,默认为null
'liHover': 'stageSelect' //设置当前page的类名
});
运行demo
最简单的方法为改Default.html中jquery对应script元素的src为本地的jquery(离线)或CDN中的jquery(在线),然后双击Default.html即可
或者配置myBoxScroll.jquery.json or package.json
PS:代码之间耦合过强,可重复利用的很多,准备参考学长的建议按模块写个人函数库,通过模块加载注入需要使用的工具函数
Demo代码如下:
HTML
<!doctype html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta content="" name="keywords" />
<meta content="" name="description" />
<meta name="author" content="codetker" />
<head>
<title>window对象滚动插件</title>
<link href="style/reset.css" rel="stylesheet" type="text/css">
<link href="style/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="../src/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="../dest/jquery.codetker.windowScroll.min.js"></script>
</head> <body scroll="no">
<div class="wrap" style="dispaly:block;">
<div class="stageControl">
<ul>
<li class="stageSelect">stage1</li>
<li>stage2</li>
<li>stage3</li>
<li>stage4</li>
<li>stage5</li>
</ul>
</div>
<div class="toTop">Top</div>
<div class="toBottom">Bottom</div>
<div class="stage stage1">
<div class="pageControl">
<ul>
<li class="pageSelect">page1</li>
<li>page2</li>
<li>page3</li>
</ul>
</div>
<div class="toLeft">Left</div>
<div class="toRight">Right</div>
<div class="page page1"></div>
<div class="page page2"></div>
<div class="page page3"></div>
</div>
<div class="stage stage2"></div>
<div class="stage stage3"></div>
<div class="stage stage4"></div>
<div class="stage stage5"></div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$(".wrap").windowScroll({
'choose': 0,
'verticalSpeed': 1,
'objControlUl': '.wrap .stageControl',
'list': '.wrap .stage',
'crash': true,
'toTop': '.toTop',
'toBottom': '.toBottom',
'liHover': 'stageSelect'
});
$(".stage1").windowScroll({
'choose': 1,
'horizontalSpeed': 1,
'objControlUl': '.stage1 .pageControl',
'list': '.stage1 .page',
'crash': true,
'toLeft': '.toLeft',
'toRight': '.toRight',
'liHover': 'pageSelect'
});
});
</script>
</body>
</html>
HTML
CSS
@charset "utf-8";
/* CSS Document */
/* whole */
body{
margin : 0 0;
padding : 0 0;
height : 100%;
width : 100%;
overflow: hidden;;
}
.wrap{
font-family: "微软雅黑","宋体", Times, "Times New Roman", serif;
font-size : 14px;
margin : 0 0;
padding : 0 0;
height : 100%;
width : 100%;
overflow : hidden;
}
/* whole end */ /* stage */
.stage,.page{
width : 100%;
height: 100%;
}
.stage1{
background-color: #b9f579;
}
.stage2{
background-color: #d87efa;
}
.stage3{
background-color: #f97171;
}
.stage4{
background-color: #ffc438;
}
.stage5{
background-color: #9ff4d5;
}
.stageControl{
position: fixed;
}
.stageControl ul li{
-webkit-transition-duration: 0.3s;
-o-transition-duration : 0.3s;
transition-duration : 0.3s;
/* 兼容低版本IE,add PIE.htc or IE-css3.htc here */
}
.stageSelect{
background-color: #888 !important;
}
/* stage end */ /* page */
.page{
float: left;
}
.page2{
background-color: #fca172;
}
.page3{
background-color: #b6befc;
}
.pageControl{
position: absolute;
left : 200px;
}
.pageControl ul li{
float : left;
-webkit-transition-duration: 0.3s;
-o-transition-duration : 0.3s;
transition-duration : 0.3s;
/* 兼容低版本IE,add PIE.htc or IE-css3.htc here */
}
.pageSelect{
background-color: #888 !important;
}
/* page end */ /* left,right,top,bottom button */
.toTop,.toBottom{
position: fixed;
}
.toTop{
top :180px;
}
.toBottom{
top :220px;
}
.toLeft,.toRight{
position: absolute;
}
.toLeft{
left: 600px;
}
.toRight{
left: 720px;
}
.toLeft,.toRight,.toTop,.toBottom,.pageControl ul li,.stageControl ul li{
width : 100px;
height: 30px;
line-height: 30px;
text-align : center;
cursor: pointer;
color : #fff;
background-color: #aaa;
}
.toLeft:hover,.toRight:hover,.toTop:hover,.toBottom:hover,.pageControl ul li:hover,.stageControl ul li:hover{
background-color: #888;
}
/* left,right,top,bottom button end */
CSS
JavaScript
/*
* windowScroll 0.1
* window滚动插件,上下左右,可选择是否回弹。参考搜狗欢迎页面
* 兼容等常见浏览器
* 借鉴搜狗4.2版http://ie.sogou.com/features4.2.html
*/
;(function($, window, document, undefined) {
//定义构造函数
var WindowObj = function(ele, opt) {
this.$element = ele;
this.defaults = {
'choose': 0,
'list': null,
'verticalSpeed': 1,
'horizontalSpeed': 1,
'objControlUl': null,
'toLeft': null,
'toRight': null,
'toTop': null,
'toBottom': null,
'crash': true,
'liHover': null
}; this.options = $.extend({}, this.defaults, opt); }; //给构造函数添加方法
WindowObj.prototype = { //上下滚动的方法
verticalMove: function() {
var
obj = this.$element,
speed = this.options.verticalSpeed,
objControl = this.options.objControlUl,
controlList = $(objControl).find('li'),
windowHeight = $(window).height(),
list = this.options.list,
listMax = $(list).length,
toTop = this.options.toTop,
toBottom = this.options.toBottom,
crashButton = this.options.crash,
liHover = this.options.liHover,
stop = 0,
stageIndex,
windowobject = is_chrome(); function setCss() {
$(obj).css({
'width': $(window).width() + 'px',
'height': $(window).height() * listMax + 'px'
});
$(list).css({
'min-width': $(window).width() + 'px',
'height': $(window).height() + 'px'
});
}
setCss(); function markStage() {
getIndex();
$(controlList).removeClass(liHover);
$(controlList).eq(stageIndex).addClass(liHover);
} function is_chrome() {
var is_ch = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
if (is_ch) {
//判断webkit内核,供scrollTop兼容性使用
return 'body';
} else {
//支持IE和FF
return 'html';
}
} //阻止默认行为和冒泡
function stopDefaultAndBubble(e) {
e = e || window.event;
if (e.preventDefault) {
e.preventDefault();
}
e.returnValue = false; if (e.stopPropagation) {
e.stopPropagation();
}
e.cancelBubble = true;
} //得到当前的垂直位置
function getIndex() {
stageIndex = Math.round($(window).scrollTop() / windowHeight);
} function goTop() {
getIndex();
scrollStage(windowobject, stageIndex, 1);
} function goBottom() {
getIndex();
scrollStage(windowobject, stageIndex, -1);
} //绑定键盘上下按键事件
$(document).keydown(function(event) {
/* 绑定keycode38,即向上按钮 */
if (event.keyCode == 38) {
goTop(); } else if (event.keyCode == 40) { //绑定40,即向下按钮
goBottom();
}
}); //绑定滑轮功能的函数
function handle(delta) {
getIndex();
if (delta < 0) {
scrollStage(windowobject, stageIndex, -1); //stageIndex为当前页码
} else {
scrollStage(windowobject, stageIndex, 1); //stageIndex为当前页码
} } //判断滑轮,解决兼容性
function wheel(event) {
var delta = 0;
if (!event) event = window.event;
if (event.wheelDelta) {
delta = event.wheelDelta;
if (window.opera) delta = -delta;
} else if (event.detail) {
delta = -event.detail;
}
if (delta)
handle(delta); //调用执行函数
} //注册事件
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', wheel, false);
}
window.onmousewheel = document.onmousewheel = wheel; //绑定鼠标滚轮事件
$(document).bind('mousedown', function(e) {
if (e.which == 2) { //which=2代表鼠标滚轮,即为中键
stopDefaultAndBubble(e); //bugfix 搜狗浏览器的ie内核只有在定时器触发这个函数才生效
setTimeout(function() {
stopDefaultAndBubble(e);
}, 10);
}
}); //如果有ul li控制按钮
if (objControl !== null) {
$(objControl).delegate('li', 'click', function() {
stageIndex = $(this).index();
scrollStage(windowobject, stageIndex, 0);
});
} //如果有上下控制
$(toTop).click(function() {
goTop();
});
$(toBottom).click(function() {
goBottom();
}); function scrollStage(obj, stIndex, dir) { var
sIndex = stIndex,
windowobject = obj,
direction = 0 || dir,
target = windowHeight * sIndex; function move() {
$(windowobject).animate({
'scrollTop': target + 'px'
}, 1000 * speed, function() {
crash(1, target, 20, 150, -1); markStage();
});
} function after_crash(distant, time, termin) {
if (distant <= 15 || time > 150) {
stop = 1; //停止碰撞
$(windowobject).animate({
'scrollTop': termin + 'px'
}, time, function() {
stop = 0;
});
}
} //撞击函数
function crash(direction, termin, distant, time, aspect) {
if (crashButton) {
if (!stop) {
if (direction === 1) {
direction = 0;
if (aspect === 1) {
$(windowobject).animate({
'scrollTop': '-=' + distant + 'px'
}, time, function() {
crash(direction, termin, distant * 0.6, time, 1);
after_crash(distant, time, termin);
});
} else {
$(windowobject).animate({
'scrollTop': '+=' + distant + 'px'
}, time, function() {
crash(direction, termin, distant * 0.6, time, -1);
after_crash(distant, time, termin);
});
} } else if (direction === 0) {
direction = 1;
if (aspect === 1) {
$(windowobject).animate({
'scrollTop': termin + 'px'
}, time, function() {
crash(direction, termin, distant * 0.6, time, 1);
after_crash(distant, time, termin);
});
} else {
$(windowobject).animate({
'scrollTop': termin + 'px'
}, time, function() {
crash(direction, termin, distant * 0.6, time, -1);
after_crash(distant, time, termin);
});
} }
}
} } if (!$(windowobject).is(':animated')) { switch (direction) {
case 0:
if ($(window).scrollTop() > target) {
direction = -1;
move();
} else if ($(window).scrollTop() == windowHeight * sIndex) {
direction = 0;
crash(1, target, 20, 150, -1);
} else {
direction = 1;
move();
}
break; case 1:
if (sIndex === 0) {
crash(1, target, 20, 150, 1);
} else {
sIndex -= 1;
target = windowHeight * sIndex;
move();
}
break; case -1:
if (sIndex === listMax - 1) {
crash(1, target, 20, 150, -1);
} else {
sIndex += 1;
target = windowHeight * sIndex;
move();
}
break; default:
}
}
} }, //左右滚动
horizontalMove: function() {
var
obj = this.$element,
speed = this.options.horizontalSpeed,
objControl = this.options.objControlUl,
controlList = $(objControl).find('li'),
windowWidth = $(window).width(),
list = this.options.list,
listMax = $(list).length,
liHover = this.options.liHover,
toLeft = this.options.toLeft,
toRight = this.options.toRight,
crashButton = this.options.crash,
pageIndex; function setCss() {
$(obj).css({
'width': windowWidth * listMax + 'px',
'height': $(window).height() + 'px'
});
$(list).css({
'width': windowWidth + 'px',
'min-height': $(window).height() + 'px'
});
}
setCss(); function markPage() {
getPageIndex();
$(controlList).removeClass(liHover);
$(controlList).eq(pageIndex).addClass(liHover);
} function getPageIndex() {
pageIndex = (-1) * Math.round(parseInt($(obj).css('margin-left')) / windowWidth);
} function goLeft() {
getPageIndex();
scrollPage(obj, pageIndex, 1);
} function goRight() {
getPageIndex();
scrollPage(obj, pageIndex, -1);
} //绑定键盘左右按键事件
$(document).keydown(function(event) {
//判断event.keyCode为39(即向右按钮)
if (event.keyCode === 39) {
goRight();
}
//判断event.keyCode为37(即向左按钮
else if (event.keyCode === 37) {
goLeft();
}
}); //如果有ul li控制按钮
if (objControl !== null) {
$(objControl).delegate('li', 'click', function() {
pageIndex = $(this).index();
scrollPage(obj, pageIndex, 0);
});
} //如有有左右控制按钮
$(toLeft).click(function() {
goLeft();
});
$(toRight).click(function() {
goRight();
}); function scrollPage(obj, pageIndex, dir) {
var
windowobject = obj,
direction = 0 || dir,
dist = Math.round(parseInt($(obj).css('margin-left'))),
aim; function getAim() {
aim = pageIndex * windowWidth * (-1);
} function crash(type) {
if (crashButton) {
if (type === 'left') {
$(windowobject).animate({
'margin-left': '+=' + '50px'
}, 500).animate({
'margin-left': '-=' + '100px'
}, 500).animate({
'margin-left': '+=' + '50px'
}, 500);
} else {
$(windowobject).animate({
'margin-left': '-=' + '50px'
}, 500).animate({
'margin-left': '+=' + '100px'
}, 500).animate({
'margin-left': '-=' + '50px'
}, 500);
}
} } function move() {
$(windowobject).animate({
'margin-left': aim + 'px'
},
1000 * speed,
function() {
markPage();
});
} if (!$(windowobject).is(':animated')) {
switch (direction) { case 0:
getAim();
if (dist !== aim) {
move();
} else {
direction = 0;
crash('left');
}
break; case 1:
if (pageIndex === 0) {
crash('left');
} else {
pageIndex -= 1;
getAim();
move();
}
break; case -1:
if (pageIndex === (listMax - 1)) {
crash('right');
} else {
pageIndex += 1;
getAim();
move();
}
break; default:
break;
} }
} }
}; //绑定方法到jquery对象原型上
$.fn.windowScroll = function(options) { var windowObj = new WindowObj(this, options); if (windowObj.options.choose === 0) {
return windowObj.verticalMove();
} else if (windowObj.options.choose === 1) {
return windowObj.horizontalMove();
} else {
//add some functions
}
};
})(jQuery, window, document);
JS
jQuery插件开发之windowScroll的更多相关文章
- jQuery插件开发之boxScroll与marquee
BoxScroll 常见图片轮播效果的简单实现.可以数字列表控制或者左右按键控制.逻辑很简单,下面的Marquee形成环,这个到了尽头得往回跑,看看注释就知道了. 图片轮播GitHub:https:/ ...
- jQuery插件开发之datalist
HTML5中定义了一种input框很好看的下拉列表--datalist,然而目前它的支持性并不好(万恶的IE,好在你要渐渐退役了...).于是最近更据需求写了一个小型datalist插件,兼容到IE8 ...
- 插件开发之360 DroidPlugin源码分析(五)Service预注册占坑
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52264977 在了解系统的activity,service,broa ...
- 插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52258434 在了解系统的activity,service,broa ...
- Chrome插件开发之manifest.json
广而告之: Chrome插件之一键保存网页为PDF1.1发布 http://www.cnblogs.com/bdstjk/p/3179543.html 最近做“一键保存网页为PDF”过程中,对Chro ...
- Qgis插件开发之Qgis源码学习
Qgis源码中的拖拽.zoomin/out等各个基础功能插件的实现位于qgis_app工程中. 具体头文件为: \QGIS\src\app\qgisapp.h 根据此类可以逐个找到Qgis的基础插件的 ...
- 插件开发之360 DroidPlugin源码分析(二)Hook机制
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52124397 前言:新插件的开发,可以说是为插件开发者带来了福音,虽然还很多坑要填补, ...
- 插件开发之360 DroidPlugin源码分析(一)初识
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52123450 DroidPlugin的是什么? 一种新的插件机制,一种免安装的运行机制 ...
- 新人大餐:2018最新Office插件开发之ExcelDNA开发XLL插件免费教学视频,五分钟包教包会
原始链接:https://www.cnblogs.com/Charltsing/p/ExcelDnaVideoCourse.html QQ: 564955427 先解释一下,为什么要做这个视频: 我在 ...
随机推荐
- 学习React前端框架,报错 'render' is not defined no-undef
报错 'render' is not defined no-undef 原因没有 写 import { render } from 'react-dom'
- windows phone 8.0 app 移植到windows10 app笔记
8.0 public class Convisibility : IValueConverter { public object Convert(object value, Type targetTy ...
- log4net 日志打印不全
程序用的是log4net打印日志,偶现日志打印不全的问题,程序的log4net配置如下: <log4net> <root> <level value="ALL& ...
- sqlserver常用函数
1.字符串函数 --ascii函数,返回字符串最左侧字符的ascii码值 SELECT ASCII('dsd') AS asciistr --ascii代码转换函数,返回指定ascii值对应的字符 ) ...
- iOS 使用 TestFlight 测试
TestFlight 已经并入 Itunes connect. 测试方法: 1. itunes connect 上创建应用 2. xcode 里 archive 应用并 submit 到 itunes ...
- java学习笔记—标准连接池的实现(27)
javax.sql.DataSource. Java.sql.* DataSource 接口由驱动程序供应商实现.共有三种类型的实现: 基本实现 - 生成标准的 Connection 对象 – 一个D ...
- robot framework-tags(标签)实例
robot framework的标签是一个简单而又强大的分类机制,功能如下: 标签在reports,logs以及测试数据中展示,显示关于测试用例的元数据信息 用例的执行统计(total,passed, ...
- flask 安装
flask官网 : http://docs.jinkan.org/docs/flask/installation.html (基本上就是按照官网思路一点一点来的) 1,安装easy_install: ...
- Linux磁盘及文件系统(一)
一.磁盘 1.IO接口类型 (1)传输类型分类 并口:同一个线缆可以接多块设备 IDE口:两个,一个主设备,一个从设备 SCSI:宽带:16-1:窄带:8-1 串口:同一个线缆只可以接一个设备 (2) ...
- 用css做出来一个三角形
用css做出来一个三角形 <!--不设置宽高 转换行内块 边线设置成宽度--> <div class="triangle"> 三角 ...