纯javaScript实现元素平滑滚动,改进前两个版本,支持鼠标滚轮滚动和点击元素滚动,滚动更顺畅
windowScroll(id, number, distance, direction, obj) 参数介绍: 1.id:所要滚动的元素id; 2.number:滚动次数; 3.distance:每次滚动的距离; 4.direction:滚动的方向(上下传入"top",左右传入"left"); 5.obj:滚动的触发方式(滚轮触发、点击触发); 6.obj格式{touch: click||scroll||click&scroll, control_up: "控制往上滚动的点击元素的id", control_down: "控制页面往下滚动的点击元素的id"} a.touch:什么触发方式,三个选项click/scroll/click&scroll; b.control_up:你的触发页面向上滚动的按钮id; c.control_down:你的触发页面向下滚动的按钮id 7.该方法支持上下滚动和左右滚动 8.无返回值
示例:1.windowScroll("content", 10, 3000, "top", {touch:"scroll"});说明:滚动元素id为content,滚动10次,每次滚动3000px,滚动方向为上下滚动,滚动触发方式为鼠标滚轮触发
2.windowScroll("xxx",20,cHeight,"left",{touch:"click", click_up:"aaa", click_down:"bbb"});说明:滚动元素id为xxx,滚动20次,每次滚动 cHeight(一个变量) px距离,滚动方向为左右滚动,滚动方式为点击滚动,点击id为aaa的元素页面往左滚动,点击id为bbb的元素页面往右滚动touch还有一个值是"click&scroll"作用是即可以通过点击滚动也可以通过鼠标滚轮滚动
前两次版本链接:有兴趣可以对比一下改动的地方在哪里
第二版:对于鼠标滚动事件的补充(1)
最新版如下:
新增功能:
1.可以自定义滚动距离
2.解决了先前版本的滚动时候页面会晃动的问题
3.优化了滚动,实现页面的平滑滚动
附代码:
//使用鼠标滚轮每次滚动自定义大小的距离
function windowScroll(id, number, distance, direction, obj) {
var oHtml = document.documentElement;
//在IE8以下不支持使用class选取元素
var oContent = document.getElementById(id);
//获取文档的高度
var cHeight;
if(direction === "top" ) {
cHeight = oHtml.clientHeight;
}else if( direction === "left" ) {
cHeight = oHtml.clientWidth;
}
//用于控制鼠标每个多长时间才能让页面滚动设置的变量
var count = 1;
//用于添加触发点击事件的元素
if(obj.touch === "click" || obj.touch === "click&scroll"){
var oControl_up, oControl_down;
oControl_up = document.getElementById(obj.control_up);
oControl_down = document.getElementById(obj.control_down);
}
//在窗口尺寸改变的时候实时给cHeight赋值
window.onresize = function () {
if(direction === "top" ) {
cHeight = oHtml.clientHeight;
}else if( direction === "left" ) {
cHeight = oHtml.clientWidth;
}
};
if(window.addEventListener) {
//用于判断当前浏览器是否为FF
if( navigator.userAgent.toLowerCase().indexOf("firefox") !== -1 ) {
//滚动触发
if(obj.touch === "scroll") {
oHtml.addEventListener("DOMMouseScroll", function (e) {
//FF浏览器的滚动条滚动上下判断是与其它浏览器相反的,负值是向上滚动
if( count === 1 ) {
//滚轮向上滚动时
if( e.detail < 0 ) {
upRoll();
}
//e.detail是正值说明是想下滚动
else if( e.detail > 0 ) {
downRoll();
}
}
//阻止浏览器页面滚动的默认事件
e.preventDefault();
}, false);
} else if( obj.touch === "click" ) {
//点击触发的事件,下同
clickTouch();
}else if ( obj.touch === "click&scroll" ) {
oHtml.addEventListener("DOMMouseScroll", function (e) {
//FF浏览器的滚动条滚动上下判断是与其它浏览器相反的,负值是向上滚动
if( count === 1 ) {
//滚轮向上滚动时
if( e.detail < 0 ) {
upRoll();
}
//e.detail是正值说明是想下滚动
else if( e.detail > 0 ) {
downRoll();
}
}
//阻止浏览器页面滚动的默认事件
e.preventDefault();
}, false);
clickTouch();
}
} else {
if(obj.touch === "scroll") {
oHtml.addEventListener('mousewheel',function (e) {
var event = e || window.event;
//当count = 1 时让页面可以滚动
if( count === 1 ) {
//当鼠标向上滚动时
if( event.wheelDelta > 0 ) {
upRoll();
}
//当鼠标向下滚动时
if( event.wheelDelta < 0 ) {
downRoll();
}
}
//阻止浏览器滚动的默认事件,防止页面来回晃动
event.preventDefault();
}, {passive: false});
} else if( obj.touch === "click" ){
clickTouch();
} else if(obj.touch === "click&scroll"){
oHtml.addEventListener('mousewheel',function (e) {
var event = e || window.event;
//当count = 1 时让页面可以滚动
if( count === 1 ) {
//当鼠标向上滚动时
if( event.wheelDelta > 0 ) {
upRoll();
}
//当鼠标向下滚动时
if( event.wheelDelta < 0 ) {
downRoll();
}
}
//阻止浏览器滚动的默认事件,防止页面来回晃动
event.preventDefault();
}, {passive: false});
clickTouch();
}
}
} else if(window.attachEvent) {
if(obj.touch === "scroll") {
oHtml.attachEvent("onmousewheel",function(){
console.log(count);
if( count === 1 ){
//当鼠标向上滚动时
if( event.wheelDelta > 0 ) {
upRoll();
}
//当鼠标向下滚动时
if( event.wheelDelta < 0 ) {
downRoll();
}
}
//阻止浏览器滚动的默认事件,防止页面来回晃动
return false;
});
} else if ( obj.touch === "click" ) {
clickTouch();
} else if( obj.touch === "click&scroll" ) {
oHtml.attachEvent("onmousewheel",function(){
console.log(count);
if( count === 1 ){
//当鼠标向上滚动时
if( event.wheelDelta > 0 ) {
upRoll();
}
//当鼠标向下滚动时
if( event.wheelDelta < 0 ) {
downRoll();
}
}
//阻止浏览器滚动的默认事件,防止页面来回晃动
return false;
});
clickTouch();
}
}
//向上滚动时执行的函数
function upRoll(){
if( getElemProp(oContent, direction) >= 0 ) {
console.log("到顶了");
console.log(getElemProp(oContent,direction));
}
else {
elemDisplace(oContent, direction, 1, distance);
//如果鼠标不是在顶部往上滚动的话就将count++
count++;
}
}
//向下滚动时执行的函数
function downRoll() {
//判断是否滚动到底部
if( getElemProp(oContent, direction) <= -number*cHeight ) {
console.log("到底了");
}
else {
elemDisplace(oContent, direction, -1, distance);
//如果鼠标不是在顶部往上滚动的话就将count++
count++;
}
}
//给点击元素添加点击事件
function clickTouch(){
if(oControl_down && oControl_up){
eventBinding(oControl_up, 'click', function(){
if( count === 1 ) {
upRoll();
}
});
eventBinding(oControl_down, 'click', function(){
if( count === 1 ) {
downRoll();
}
});
} else {
alert("oControl_up或oControl_down未传入");
}
}
//让元素加速运动
function elemDisplace(elem, direction, speed, distance){
//记录元素当前的位置
var origin = parseInt( getElemProp(elem, direction) );
var pos;
//定义一个x用于停止动画,因为缓冲动画的speed会有一个误差
var x = distance/150;
//将distance转换成数字
var numDistance = parseInt(distance);
var Timer = setInterval(function(){
pos = parseInt( getElemProp(elem, direction) );
//判断元素是否位移到了指定的地方
if( Math.abs( pos - origin ) >= numDistance - 1.5 ){
if(speed > 0){
elem.style[direction] = origin + numDistance + 'px';
}else {
elem.style[direction] = origin - numDistance + 'px';
}
speed = 0;
count = 1;
clearInterval(Timer);
console.log("停止时:speed" + speed + " , pos" + pos);
}else {
//判断元素的位移方向,判断初始速度是否为1/-1,如果为1则置为2/-2
if(Math.abs( speed ) === 1) {
if(speed > 0 ) {
speed = 2;
} else {
speed = -2;
}
} else {
if(Math.abs( pos - origin ) <= numDistance/2 ){
//前二分之一路程加速
speed *= 1.1;
} else {
//后面减速
speed /= 1.1;
if( speed > -1 && speed < 0) {
speed = -1.01;
} else if ( speed < 1 && speed > 0) {
speed = 1.01;
}
//当速度大于剩余距离时手动将其速度降低,防止页面抖动
if( numDistance - Math.abs( pos - origin ) < Math.abs( speed ) && Math.abs( speed ) > 2 ){
if( speed < 0 ) {
speed = -2;
} else if ( speed > 0 ){
speed = 2;
}
}
}
}
elem.style[direction] = pos + speed + 'px';
console.log("运动时:pos - origin:" + Math.abs( pos - origin ) + " ,numDistance/2:" + numDistance/2 + ' ,' +
' speed:' + speed);
}
},15);
}
//获取元素属性
function getElemProp(elem, prop){
if(window.getComputedStyle){
return parseInt(window.getComputedStyle(elem, null)[prop]);
}else{
return parseInt(elem.currentStyle[prop]);
}
}
//给元素绑定事件
function eventBinding(elem, type, fn){
if(elem.addEventListener){
elem.addEventListener(type, fn, false);
}else if(elem.attachEvent){
elem.attachEvent('on' + type, function () {
fn.call(elem);
});
}else{
elem['on' + type] = fn;
}
}
}
注:使用的时候注意给需要滚动的元素设置定位属性
欢迎大家对方法不足的地方提出建议
原创文章
纯javaScript实现元素平滑滚动,改进前两个版本,支持鼠标滚轮滚动和点击元素滚动,滚动更顺畅的更多相关文章
- 如何让DbGrid支持鼠标滚轮滚动
如何让DbGrid支持鼠标滚轮滚动 在主窗体上加一个ApplicationEvents控件(控件在Additional面板中), 在它的OnMessage事件中加入下述代码,一切搞定-! proced ...
- jq点击改变元素样式、添加类,显示隐藏,图标旋转,再次点击还原;表格点击显示下拉详情
点击前 点击后 <tr> <td class="right" data-id="{$vo.id}" id="{$vo.id}&quo ...
- 横纵方向走马灯滚动,纯javascript代码
<body onload="beginmarquee()"> <table width="1024" border="0" ...
- 【javascript常见面试题】常见前端面试题及答案
转自:http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性.上 ...
- 纯javaScript、jQuery实现个性化图片轮播
纯javaScript实现个性化图片轮播 轮播原理说明<如上图所示>: 1. 画布部分(可视区域)属性说明:overflow:hidden使得超出画布部分隐藏或说不可见.position: ...
- 纯JavaScript实现页面行为的录制
在网上有个开源的rrweb项目,该项目采用TypeScript编写(不了解该语言的可参考之前的<TypeScript躬行记>),分为三大部分:rrweb-snapshot.rrweb和rr ...
- javascript日历控件——纯javascript版
平时只有下班时间能code,闲来写了个纯javascript版.引用该calendar.js文件,然后给要设置成日历控件的input的id设置成calendar,该input就会变成日历控件. < ...
- 青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 10(排行榜界面&界面管理)
继上一次介绍了<神奇的六边形>的完整游戏开发流程后(可点击这里查看),这次将为大家介绍另外一款魔性游戏<跳跃的方块>的完整开发流程. (点击图片可进入游戏体验) 因内容太多,为 ...
- 纯javascript联动的例子
有人想要学习下纯javascript联动的一些技巧,我这里就以日期的联动为例,附上一些代码至于复杂的省市区联动,不建议用纯javascript的,而是用ajax的方式,该不在此讨论范围内,想要了解aj ...
随机推荐
- CAShapeLayer的使用
CAShapeLayer的使用 1.CAShapeLayer 简介 1.CAShapeLayer继承至CALayer,可以使用CALayer的所有属性值 2.CAShapeLayer需要与贝塞尔曲线配 ...
- Thread Runnable 区别
[线程的并发与并行] 在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(co ...
- python dictionary的遍历
d = {'x':1, 'y':3, 'z':2} for k in d: print d[k] 直接遍历k in d的话,遍历的是dictionary的keys. 2 字典的键可以是任何不可变 ...
- spring 相关博客
Spring中使用Interceptor拦截器 spirng4 中文文档 ssm整合 Spring系列之Spring常用注解总结 Spring框架中context-param与servlet中in ...
- POJ3080 Blue Jeans —— 暴力枚举 + KMP / strstr()
题目链接:https://vjudge.net/problem/POJ-3080 Blue Jeans Time Limit: 1000MS Memory Limit: 65536K Total ...
- html5--6-16 CSS3中的文字与字体
html5--6-16 CSS3中的文字与字体 中文字体包很大,少量字体的话可以有其它方法. 有字库-首页-全球第一中文web font(在线字体)服务平台.web font.webfont.在线字体 ...
- html5--3.2 input元素(1)
html5--3.2 input元素(1) 学习要点 input元素及其属性 input元素 用来设置表单中的内容项,比如输入内容的文本框,按钮等 不仅可以布置在表单中,也可以在表单之外的元素使用 i ...
- 2014山东省“浪潮杯”第五届ACM省赛总结
一次比赛做一次总结,弱菜又来总结了…… 我这种大四的又死皮赖来混省赛了,貌似就我和山大威海的某哥们(不详其大名)了吧.颁奖前和他聊天,得知他去百度了,真是不错,ORZ之. 比赛流水账: 题目目前不知道 ...
- bzoj1017 [JSOI2008]魔兽地图DotR——DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1017 好难想的状态啊!f[i][j][k]表示i号物品有j个向上贡献,一共花了k钱的最大力量 ...
- 开启sqlplus中执行计划
在sqlplus中我们一般用Autotrace来查看执行计划,从而对于一些语句执行过程分析,开展优化工作.这里就演示一下如何将autotrace权限授予给普通的用户,以scott用户为例(set au ...