JS网页特效
2020年6月30日元素偏移量offset系列(就是查看元素位置)
- offset翻译过来就是偏移量,我们是用offset系列相关属性可以动态地得到该元素的位置(偏移),大小等
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小
- 返回的数值没有单位
1 2 3 4 5 |
element.offsetParent //返回该元素带有定位的父元素, 没有父元素就返回body 注意返回的是(元素) element.offsetTop //返回元素相对于父元素上方的偏移量 element.offsetLeft //返回元素相对于父元素左方的偏移量 element.offsetWidth //返回元素 边框 padding 内容区 的宽度和 不带单位 element.offsetHeight //返回元素 边框 padding 内容区 的高度和 不带单位 |
offset与style区别
- offset可以得到任意样式表的样式值
- 获取的数值没有单位
- offsetWidth 包含 padding+border+offsetWidth
- offsetWidth 等属性是只读属性,只能获取不能赋值
- style只能得到行内样式表的样式
- style.widht获得的数值带有单位
- style.widht 获得不包括 padding 和 border
- style.widht 是可读可写的属性
小案例 (获取鼠标在元素上的位置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <style> div { width: 100px; height: 100px; background: red; } </style> <div></div> <script> var $div = document.querySelector('div'); $div.addEventListener('mousemove', function (event) { $widht = event.pageX - $div.offsetTop $height = event.pageY - $div.offsetLeft console.log($widht ,$height); }) </script> </body> </html> |
小案例(鼠标拖动元素效果)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <style> div { width: 100px; height: 100px; background: red; position: absolute; top: 0; left: 0; } </style> <div></div> <script> var $div = document.querySelector('div'); //鼠标按键按下事件 $div.addEventListener('mousedown', function (event) { var $widht = event.pageX - $div.offsetLeft //获取鼠标在元素内部X坐标 var $height = event.pageY - $div.offsetTop //获取鼠标在元素内部Y坐标 //移动事件 $div.addEventListener('mousemove', $move = function (event) { $div.style.top = event.pageY - $height + 'px'; //元素的页面位置 - 鼠标在元素内部 = 需要移动的距离 $div.style.left = event.pageX - $widht + 'px'; //元素的页面位置 - 鼠标在元素内部 = 需要移动的距离 }) //鼠标按键抬起事件 $div.addEventListener('mouseup', function (event) { $div.removeEventListener('mousemove', $move) }) //鼠标移出元素事件 $div.addEventListener('mouseout', function (event) { $div.removeEventListener('mousemove', $move) }) }) </script> </body> </html> |
小案例(手机端触摸拖动)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> div{ position: absolute; top: 0; left: 0; width: 100px; height: 100px; background: pink; } </style> </head> <body> <div></div> <script> var div = document.querySelector('div') //获取事件元素 var mouseTop = 0 //获取鼠标初始点击在 屏幕 中 Y轴位置 var mouseLeft = 0 //获取鼠标初始点击在 屏幕 中 X轴位置 var divMouseTop = 0 //获取鼠标初始点击在 Div 中 Y轴位置 var divMouseLeft = 0 //获取鼠标初始点击在 Div 中 X轴位置 div.addEventListener('touchstart',function (event) { mouseTop = event.targetTouches[0].pageY mouseLeft = event.targetTouches[0].pageX divMouseTop = mouseTop -div.offsetTop divMouseLeft = mouseLeft-div.offsetLeft }) div.addEventListener('touchmove',function (event) { mouseTop = event.targetTouches[0].pageY mouseLeft = event.targetTouches[0].pageX div.style.top = mouseTop-divMouseTop+'px' div.style.left = mouseLeft-divMouseLeft+'px' console.log(mouseLeft,mouseTop) event.preventDefault() //阻止默认行为 要不然整个屏幕也会一起拖动 }) </script> </body> </html> |
小案例(放大镜)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <style> * { padding: 0px; margin: 0px; } .img{ margin-left: 200px; margin-top: 200px; position: relative; width: 398px; height: 398px; border: 1px solid #ccc; } .img > img{ width: 398px; height: 398px; } .img-region{ position: absolute; top: 0; left: 0; width: 300px; height: 300px; background: #FEDE4F; opacity: .5; border: 1px solid #ccc; cursor: move; } .big{ position: absolute; left: 410px; top: 0; width: 500px; height: 500px; background-color: pink; z-index: 999; border: 1px solid #ccc; overflow: hidden; } .big img{ position: absolute; top: 0; left: 0; } </style> <div class="img"> <img src="https://www.zfajax.com/wp-content/uploads/2020/06/68836f52ffaaad96.jpg" alt=""> <div class="img-region"></div> <div class="big" > <img src="https://www.zfajax.com/wp-content/uploads/2020/06/68836f52ffaaad96.jpg" alt="" class="big-img"> </div> </div> <script> var img = document.querySelector('.img'); //获得图片外层的相框 ,(相框大小) 等于 (小图片大小) var imgRegion = document.querySelector('.img-region'); //获得遮挡罩 var big = document.querySelector('.big'); //获得大图显示区域 var bigImg = document.querySelector('.big-img'); //获得大图 (大图大小) 大于 (大图显示区域) img.addEventListener('mousemove',imgRegionMove = function(event){ imgMousePosY = event.pageY - img.offsetTop; //(鼠标所在位置) 通过 (相框所在位置) 减去 (鼠标在页面的位置) 得到 imgMousePosX = event.pageX - img.offsetLeft; //(鼠标所在位置) 通过 (相框所在位置) 减去 (鼠标在页面的位置) 得到 imgRegionYhalf = imgRegion.offsetHeight / 2 //遮挡罩高度 / 2 遮挡罩一半高度 imgRegionXhalf = imgRegion.offsetWidth / 2 //遮挡罩宽度 / 2 遮挡罩一半宽度 maxY = img.offsetHeight -imgRegion.offsetHeight //遮挡罩最大移动距离 (外层的相框) 减去 (遮挡罩) maxX = img.offsetWidth -imgRegion.offsetWidth //遮挡罩最大移动距离 (外层的相框) 减去 (遮挡罩) moveY = imgMousePosY - imgRegionYhalf //(鼠标所在位置) 减去 (遮挡罩一半高度) 得到 遮挡罩偏移距离 减去了一半鼠标就在遮挡罩中央 moveX = imgMousePosX - imgRegionXhalf //(鼠标所在位置) 减去 (遮挡罩一半宽度) 得到 遮挡罩偏移距离 减去了一半鼠标就在遮挡罩中央 //如果遮挡罩的Y偏移距离 小于 0 给默认值 大于 遮挡罩最大移动距离 if (moveY <= 0) { moveY = 0; }else if(moveY >= maxY){ moveY = maxY } //如果遮挡罩的X偏移距离 小于 0 给默认值 大于 遮挡罩最大移动距离 if (moveX <= 0) { moveX = 0; }else if(moveX >= maxX){ moveX = maxX } imgRegion.style.top = moveY+'px' //遮挡罩偏移 imgRegion.style.left = moveX+'px' //遮挡罩偏移 var bigMaxX = bigImg.offsetWidth - big.offsetWidth; //大图片最大移动距离 var bigMaxY = bigImg.offsetHeight - big.offsetHeight; //大图片最大移动距离 //公式 大图片的移动距离 = 遮挡罩偏移距离 * 大图片最大移动距离 / 遮挡罩最大移动距离 var bigX = moveX * bigMaxX / maxX ; var bigY = moveY * bigMaxY / maxY ; bigImg.style.left = -bigX + 'px'; bigImg.style.top = -bigY + 'px'; }) img.addEventListener('mouseout',imgRegionMove = function(event) { img.removeEventListener('mousemove',imgRegionMove) }) </script> </body> </html> |
元素可视区域client系列
- client翻译过来就是客户端,我们是用client系类的相关属性来获取元素可视区的相关信息,通过相关属性可以动态得到该元素的边框大小,元素大小
- client和offset的区别 offset带边框 client不带边框
1 2 3 4 |
div.clientTop //返回元素的上边框大小 div.clientLeft //返回元素的左边框大小 div.clientWidth //返回 内容 和 padding 的 总和值 不带border边框 div.clientHeight //返回 内容 和 padding 的 总和值 不带border边框 |
元素滚动scroll系列
scroll翻译过来就是滚动的,我们使用scroll系列的相关属性可以动态的得到该元素的大小,滚动距离等.
1 2 3 4 |
div.scrollTop //上方卷去(隐藏)的大小 , (例子)页面向下滚动 (可视窗口顶边) 和 (dom文档顶边) (之间的距离) div.scrollLeft //左方卷去(隐藏)的大小 , (例子)页面向下滚动 (可视窗口顶边) 和 (dom文档顶边) (之间的距离) div.scrollWidth //返回 内容 和padding的总和 ,如果内容超出定义的宽度和高度,(内容+padding+超出内容) 的 总和 ,这就是和client最大的区别 div.scrollHeight //返回 内容 和padding的总和 ,如果内容超出定义的宽度和高度,(内容+padding+超出内容) 的 总和 ,这就是和client最大的区别 |
如何快速获取页面滚动值 document就是页面
1 2 |
window.pageYOffset //获取页面上方卷去(隐藏)的大小 window.pageXOffset //获取页面左方卷去(隐藏)的大小 |
页面被卷去的头部兼容性解决方案
- 声明DTD <!DOCTYPE html> 使用 document.documentElement.scrollTop
- 未明DTD <!DOCTYPE html> 使用 document.body.scrollTop
- 新方法 window.pageYoffset 和 window.pageXoffset IE9 开始支持
1 2 3 4 5 6 7 8 9 10 11 |
/** * 使用时候 getScroll().left * @returns {{top: number, left: number}} */ function getScroll(){ return{ left: window.pageXOffset || document.documentElement.scrollWidth || document.body.scrollLeft || 0, top : window.pageYOffset || document.documentElement.scrollHeight || document.body.scrollTop || 0, } } |
javaScript简单动画效果函数封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/** * 自定义简单动画函数 */ function animate(obj, target ,callbackFunction) { /** * 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器 * 解决方案就是 让我们元素只有一个定时器执行 * 先清除以前的定时器,只保留当前的一个定时器执行 */ clearInterval(obj.timer); obj.timer = setInterval(function() { //每一个目标对象添加timer 属性节约内存空间 if (obj.offsetLeft == target) { clearInterval(obj.timer); // 停止动画 本质是停止定时器 if(callbackFunction){ //回调函数 callbackFunction() } } var step = (target - obj.offsetLeft) / 10 //添加缓动动画效果 (目标位置 - 已经移动的位置) / 10 step = step > 0 ? Math.ceil(step) : Math.floor(step) //需要判断正负值来取整, 要不然会移动不到目标位置 obj.style.left = obj.offsetLeft + step + 'px'; }, 15); } |
简单动画效果函数(应用1 鼠标浮动移出菜单)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .sliderbar { position: fixed; left: 0; top: 100px; width: 40px; height: 40px; text-align: center; line-height: 40px; cursor: pointer; color: #fff; } .con { position: absolute; right: 0; top: 0; width: 200px; height: 40px; background-color: purple; z-index: -1; } </style> </head> <body> <div class="sliderbar"> <span>→</span> <div class="con">问题反馈</div> </div> <script> // 1. 获取元素 var sliderbar = document.querySelector('.sliderbar'); var con = document.querySelector('.con'); // 当我们鼠标经过 sliderbar 就会让 con这个盒子滑动到左侧 sliderbar.addEventListener('mouseenter', function() { animate(con, 0, function() { sliderbar.children[0].innerHTML = '←'; }); }) // 当我们鼠标离开 sliderbar 就会让 con这个盒子滑动到右侧 sliderbar.addEventListener('mouseleave', function() { animate(con, -160, function() { sliderbar.children[0].innerHTML = '→'; }); }) /** * 自定义简单动画函数 */ function animate(obj, target ,callbackFunction) { /** * 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器 * 解决方案就是 让我们元素只有一个定时器执行 * 先清除以前的定时器,只保留当前的一个定时器执行 */ clearInterval(obj.timer); obj.timer = setInterval(function() { //每一个目标对象添加timer 属性节约内存空间 if (obj.offsetLeft == target) { clearInterval(obj.timer); // 停止动画 本质是停止定时器 if(callbackFunction){ //回调函数 callbackFunction() } } var step = (target - obj.offsetLeft) / 10 //添加缓动动画效果 (目标位置 - 已经移动的位置) / 10 step = step > 0 ? Math.ceil(step) : Math.floor(step) //需要判断正负值来取整, 要不然会移动不到目标位置 obj.style.left = obj.offsetLeft + step + 'px'; }, 15); } </script> </body> </html> |
简单动画效果函数(应用2 无缝轮播图)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { padding: 0px; margin: 0px; } .current{ background: #ffffff; } .focus { margin: 200px auto; position: relative; width: 721px; height: 455px; border: 3px solid red; } a{ text-decoration: none; } .focus ul { position: absolute; top: 0; left: 0; width: 700%; } li { list-style: none; } .focus ul li { float: left; } .circle { position: absolute; bottom: 10px; left: 50px; } .circle li { float: left; width: 8px; height: 8px; border: 2px solid rgba(255, 255, 255, 0.5); margin: 0 3px; border-radius: 50%; cursor: pointer; } .focus .arrow-l, .focus .arrow-r { display: none; position: absolute; top: 50%; margin-top: -20px; width: 24px; height: 40px; background: rgba(0, 0, 0, .3); text-align: center; line-height: 40px; color: #fff; font-family: 'icomoon'; font-size: 18px; z-index: 2; } .focus .arrow-r { right: 0; } </style> </head> <body> <div class="focus fl"> <!--左侧按钮开始 --> <a href="javascript:;" class="arrow-l" style="display: none;"><</a> <!--侧按钮开始结束--> <a href="javascript:;" class="arrow-r" style="display: none;">></a> <!--右侧按钮结束--> <!--图片滚动列表开始--> <ul > <li> <a href="#"><img src="https://www.zfajax.com/wp-content/uploads/2020/06/focus.jpg" alt=""></a> </li> <li> <a href="#"><img src="https://www.zfajax.com/wp-content/uploads/2020/06/focus1.jpg" alt=""></a> </li> <li> <a href="#"><img src="https://www.zfajax.com/wp-content/uploads/2020/06/focus2.jpg" alt=""></a> </li> <li> <a href="#"><img src="https://www.zfajax.com/wp-content/uploads/2020/06/focus3.jpg" alt=""></a> </li> </ul> <!--图片滚动列表结束--> <!--小圆圈选项开始--> <ol class="circle"></ol> <!--小圆圈选项结束--> </div> </body> <script> /** * 当页面全部加载完毕 */ window.addEventListener('load', function () { /** * dom元素变量 * @type {Element} */ var arrow_l = document.querySelector('.arrow-l'); //下一页 var arrow_r = document.querySelector('.arrow-r'); //上一页 var focus = document.querySelector('.focus'); //轮播图显示区域 var focusWidth = focus.clientWidth; //轮播图显示区域宽度 ,去除边框 var ul = focus.querySelector('ul'); //获取图片列表ul var ol = focus.querySelector('.circle'); //获取小圆圈点击选项; /** * 控制变量 * @type {number} */ var num = 0; //点击右侧按钮, 图片滚动一张 var circle = 0; //circle 控制小圆圈的播放 记录的是 索引值 var flag = true; // flag 节流阀 /** * 鼠标经过显示上一页 下一页 停止轮播 */ focus.addEventListener('mouseenter', function () { arrow_l.style.display = 'block'; arrow_r.style.display = 'block'; clearInterval(timer); timer = null; //清除定时器变量 }); /** * 离开隐藏上一页 下一页 停止轮播 */ focus.addEventListener('mouseleave', function () { arrow_l.style.display = 'none'; arrow_r.style.display = 'none'; timer = setInterval(function () { //手动调用点击事件 arrow_r.click(); }, 2000); }); /** * 自动播放轮播图 * @type {number} */ var timer = setInterval(function () { //手动调用点击事件 arrow_r.click(); }, 2000); /** * 动态添加小圆圈,并且绑定点击事件 */ for (var i = 0; i < ul.children.length; i++) { var li = document.createElement('li'); //创建 li 元素 li.setAttribute('index', i); //记录当前小圆圈的索引号 通过自定义属性来做 ol.appendChild(li); //把小li插入到ol 里面 /** * 小圆圈的排他思想 我们可以直接在生成小圆圈的同时直接绑定点击事件 */ li.addEventListener('click', function () { circleChange() //清除所有小圆圈样式 this.className = 'current'; //给点击的元素添加选中样式 var index = this.getAttribute('index'); //获取点击元素的索引 num = circle = index; //当我们点击了某个小li 就要把这个li 的索引号给 num he circle animate(ul, -index * focusWidth); //动画移动 }) } /** * 1.把ol里面的第一个小li设置类名为 current 因为是从第一张开始的 * 2.克隆第一张图片(li)放到ul 最后面为了无缝视觉效果 */ ol.children[0].className = 'current'; ul.appendChild(ul.children[0].cloneNode(true)); /** * 播放下一张图片 */ arrow_r.addEventListener('click', function () { if (flag) { flag = false; /** * 如果走到了最后复制的一张图片,此时 我们的ul 要快速复原 left 改为 0 , 索引是从0开始计数 长度是从1开始计数 */ if (num == ul.children.length - 1) { ul.style.left = 0; //先跳转到第一页 num = 0; } num++; circle++; //然后开始过度动画 animate(ul, -(num * focusWidth), function () { flag = true; // 打开节流阀 }); /** * 如果小圆圈走到了走后一个 */ if (circle == ol.children.length) { console.log(circle); circle = 0; } circleChange(); ol.children[circle].className = 'current'; } }); /** * 播放上一张图片 */ arrow_l.addEventListener('click', function () { if (flag) { flag = false; /** * 如果走到第一个,再次点击就从最后一个给他播放 */ if (num == 0) { num = ul.children.length - 1; //因为实现无缝视觉效果,所以第一个图片会多复制到最后一份 , 索引是从0开始计数 长度是从1开始计数 ul.style.left = -(num * focusWidth) + 'px'; //先跳转到克隆页 } num--; circle--; animate(ul, -num * focusWidth, function () { flag = true; }); // 点击左侧按钮,小圆圈跟随一起变化 可以再声明一个变量控制小圆圈的播放 // 如果circle < 0 说明第一张图片,则小圆圈要改为第4个小圆圈(3) /** * 如果小于0 小圆圈的值就变成最后一个索引,索引是从0开始计数 长度是从1开始计数 * 如果大于0 就等于本身 * @type {number} */ circle = circle < 0 ? ol.children.length - 1 : circle; circleChange(); ol.children[circle].className = 'current'; } }); /** * 清除所有小圆圈的样式 */ function circleChange() { for (var i = 0; i < ol.children.length; i++) { ol.children[i].className = ''; } } }) /** * 自定义简单动画函数 */ function animate(obj, target, callbackFunction) { /** * 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器 * 解决方案就是 让我们元素只有一个定时器执行 * 先清除以前的定时器,只保留当前的一个定时器执行 */ clearInterval(obj.timer); obj.timer = setInterval(function () { //每一个目标对象添加timer 属性节约内存空间 if (obj.offsetLeft == target) { clearInterval(obj.timer); // 停止动画 本质是停止定时器 if (callbackFunction) { //回调函数 callbackFunction() } } var step = (target - obj.offsetLeft) / 10 //添加缓动动画效果 (目标位置 - 已经移动的位置) / 10 step = step > 0 ? Math.ceil(step) : Math.floor(step) //需要判断正负值来取整, 要不然会移动不到目标位置 obj.style.left = obj.offsetLeft + step + 'px'; }, 15); } </script> </html> |
小案例(手机端Touch事件无缝轮播图 手机端轮播图)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{ margin: 0px; padding: 0px; } body { width: 100%; min-width: 320px; max-width: 1080px; margin: 0 auto; font-family: -apple-system, Helvetica, sans-serif; font-size: 14px; line-height: 1.5; color: #666666; } .focus{ position: relative; overflow: hidden; } .focus ul{ width: 500%; margin-left: -100%; } .focus ul li{ width: 20%; float: left; list-style: none; } .focus ul li img{ width: 100%; vertical-align: top; } .focus ol{ position: absolute; bottom: 10px; right: 20px; z-index: 2; } .focus ol li{ width: 11px; height: 11px; background: white; border-radius: 5px; margin-left: 5px; float: left; list-style: none; } .focus ol .current{ width: 30px; } </style> </head> <body> <!--轮播图开始--> <div class="focus"> <ul class="focus-img-list"> <!-- 此时 图片索引是这样 --> <li><img data-index="-1" src="https://www.zfajax.com/wp-content/uploads/2020/07/focus3.jpg" alt=""></li> <!--实际中间内容开始--> <li><img data-index="0" src="https://www.zfajax.com/wp-content/uploads/2020/07/focus1.jpg" alt=""></li> <li><img data-index="1" src="https://www.zfajax.com/wp-content/uploads/2020/07/focus2.jpg" alt=""></li> <li><img data-index="2" src="https://www.zfajax.com/wp-content/uploads/2020/07/focus3.jpg" alt=""></li> <!--实际中间内容结束--> <li><img data-index="3" src="https://www.zfajax.com/wp-content/uploads/2020/07/focus1.jpg" alt=""></li> </ul> <!-- 小圆点 --> <ol class="focus-ol"> </ol> </div> <!--轮播图结束--> <script> window.addEventListener('load', function() { /** * DOM元素变量 */ var focus = document.querySelector('.focus'); //获取轮播图相框 var focusImgList = document.querySelector('.focus-img-list') //获取播放的图片列表 var focusOl = document.querySelector('.focus-ol') //获取小圆点 var focusClientWidth = focus.clientWidth; //获取相框宽度 ,不代边框 /** * 控制变量 */ var index = 0; //图片索引位置 var translatex = 0; //播放的图片列表移动位置 var timer = null; //事件循环函数控制变量 var startX = 0; //手指触摸的位置 var moveX = 0; //手指触摸后移动的距离 var flag = false; //节流阀 /** * 为了实现无缝效果, * 将第一个元素拷贝到最后 * 将最后的元素拷贝到第一 */ focusImgList.appendChild(focusImgList.children[0].cloneNode(true)); focusImgList.insertBefore(focusImgList.children[focusImgList.children.length - 2].cloneNode(true) , focusImgList.children[0] ); /** * 给 ul 和 li 动态添加宽度 */ focusImgList.style.width = 100 * focusImgList.children.length +'%' focusImgList.querySelectorAll('li').forEach(function (value) { value.style.width = 100 / focusImgList.children.length + '%' }) /** * 自动填小圆圈元素 */ for (i = 0; i < (focusImgList.children.length - 2); i++) { var li = document.createElement('li'); //创建 li 元素 if (i == 0) { li.className = 'current'; } focusOl.appendChild(li); //把小li插入到ol 里面 } //执行自动轮播方法 autoRotation(); /** * 判断css3 过渡动画事件是否完成 */ focusImgList.addEventListener('transitionend', function() { /** * 无缝滚动 * 为了方便理解,我在html 上给你做了索引标记 自己理解吧 * 如果索引超出 以当前项目为例 index 3 */ if (index >= (focusImgList.children.length - 2)) { index = 0; translateXAnimation( 'none') } /** * 如果index小于0 */ if (index < 0) { index = focusImgList.children.length -3; translateXAnimation( 'none') } focusOl.querySelector('.current').classList.remove('current'); //把ol里面的li , 带有current的类名移除 focusOl.children[index].classList.add('current'); //给当前的小圆圈,加上样式 }); /** * 触摸事件 */ focusImgList.addEventListener('touchstart', function(e) { startX = e.targetTouches[0].pageX; //计算触摸位置 clearInterval(timer); //触摸的时候停止自动播放 }); /** * 触摸移动事件 */ focusImgList.addEventListener('touchmove', function(e) { flag = true; // 如果用户手指移动过我们再去判断否则不做判断效果 moveX = e.targetTouches[0].pageX - startX; //计算手指移动距离 var touchMoveTranslatex = -(index * focusClientWidth) + moveX; //盒子当前距离加+手指移动距离 translateXAnimation('none', touchMoveTranslatex) e.preventDefault(); }); /** * 手指离开事件 */ focusImgList.addEventListener('touchend', function(e) { //节流阀 if (flag) { /** * 获取移动距离的绝对值 * 如果移动距离大于 50 就开始移动 * 如果移动距离小于 50 就回弹 */ if (Math.abs(moveX) > 50) { /** * 如果是正值 从左向右滑动 上一张 * 如果是负值 从右向左滑动 下一张 */ if (moveX > 0) { index--; } else { index++; } transitionTime = 'all .3s'; } else { transitionTime = 'all .1s'; } translateXAnimation(transitionTime); clearInterval(timer); autoRotation(); } }); /** * 时间循环 自动播放 */ function autoRotation(){ timer = setInterval(function() { index++; translateXAnimation('all .3s') }, 2000); } /** * 动画方法开始 */ function translateXAnimation() { translatex = -(index * focusClientWidth); focusImgList.style.transition = arguments[0]; if (arguments[1] === undefined ) { focusImgList.style.transform = 'translateX(' + translatex + 'px)'; } else { focusImgList.style.transform = 'translateX(' + arguments[1] + 'px)'; } } }) </script> </body> </html> |