JS封装移动端触摸滑动插件应用于导航banner【精装版】
自己封装了一个小插件,一个小尝试。 可用于类似于京东导航等效果,效果多样化,很方便。 欢迎大家提点意见。
mrChenSwiper( {parent, child, type, parentN, childN, goli,lisname} );
mrChenSwipe({
parent : 父盒子 [父盒子的高度会继承父级] , 必填
child : 子盒子 [ul,子盒子需要用ul>li>a], 必填
type : 滑动方向 [vertical || level], 必填
parentN : 垂直-父盒子宽度 ~ 默认值200 || 水平-父盒子高度 ~ 默认值200, 选填
childN : 垂直-li高度 ~ 默认值40 || 水平-li宽度 ~ 默认值80, 选填
goli : 是否开启点击导航 [true || false], 选填
lisname : 选中标签类名 ~ 默认值 'current' 选填
})
注意:请传入原生DOM对象。
| 0 | function mrChenSwipe(obj) { |
| 1 | /* |
| 2 | startD //开始的坐标 |
| 3 | moveD //滑动时的坐标 |
| 4 | goD //改变的距离 |
| 5 | lis //获取所有li |
| 6 | distance //吸附距离 |
| 7 | maxPosition //最小定位区间 |
| 8 | minSwipe //滑动最小定位区间 |
| 9 | maxSwipe //滑动最大定位区间 |
| 10 | currSwipe //当前定位 |
| 11 | xy //XY |
| 12 | */ |
| 13 | |
| 14 | var parent = obj.parent, |
| 15 | child = obj.child, |
| 16 | type = obj.type, |
| 17 | goli = obj.goli, |
| 18 | lisname = obj.lisname || 'current', |
| 19 | startD = 0, |
| 20 | moveD = 0, |
| 21 | goD = 0, |
| 22 | lis = child.querySelectorAll('li'), |
| 23 | lisLength = lis.length, |
| 24 | distance = 100, |
| 25 | maxPosition = 0, |
| 26 | minSwipe, maxSwipe, currSwipe = 0, |
| 27 | xy; |
| 28 | |
| 29 | |
| 30 | /*加过渡*/ |
| 31 | var addTransition = function(elm) { |
| 32 | |
| 33 | elm.style.webkitTransition = 'all 0.2s'; /*兼容*/ |
| 34 | |
| 35 | elm.style.transition = 'all 0.2s'; |
| 36 | |
| 37 | }; |
| 38 | |
| 39 | /*删除过渡*/ |
| 40 | var removeTransition = function(elm) { |
| 41 | |
| 42 | elm.style.webkitTransition = 'none'; /*兼容*/ |
| 43 | |
| 44 | elm.style.transition = 'none'; |
| 45 | |
| 46 | }; |
| 47 | |
| 48 | //设置定位 |
| 49 | var setTranslate = function(elm, direction, num) { |
| 50 | |
| 51 | if (direction == 'y') { |
| 52 | |
| 53 | elm.style.webkitTransform = 'translateY(' + num + 'px)'; /*兼容*/ |
| 54 | |
| 55 | elm.style.transform = 'translateY(' + num + 'px)'; |
| 56 | |
| 57 | } |
| 58 | |
| 59 | if (direction == 'x') { |
| 60 | |
| 61 | elm.style.webkitTransform = 'translateX(' + num + 'px)'; /*兼容*/ |
| 62 | |
| 63 | elm.style.transform = 'translateX(' + num + 'px)'; |
| 64 | |
| 65 | } |
| 66 | |
| 67 | }; |
| 68 | |
| 69 | |
| 70 | |
| 71 | //判断如果为上下滑动,获取宽高 |
| 72 | //垂直 |
| 73 | if (type == 'vertical') { |
| 74 | |
| 75 | //默认宽度 |
| 76 | parentN = obj.parentN || 200; |
| 77 | |
| 78 | //li默认高度 |
| 79 | childN = obj.childN || 40; |
| 80 | |
| 81 | parent.style.width = parentN + 'px'; |
| 82 | |
| 83 | parent.style.height = '100%'; |
| 84 | |
| 85 | var parentWH = parent.offsetHeight; |
| 86 | |
| 87 | var childWH = childN * lisLength; |
| 88 | |
| 89 | //获取定位最小区间 |
| 90 | minPosition = parentWH - childWH; |
| 91 | |
| 92 | minSwipe = minPosition - distance; |
| 93 | |
| 94 | maxSwipe = maxPosition + distance; |
| 95 | |
| 96 | setTranslate(child, 'y', 0); |
| 97 | |
| 98 | goV(); |
| 99 | |
| 100 | } |
| 101 | |
| 102 | //水平 |
| 103 | if (type == 'level') { |
| 104 | |
| 105 | //默认高度 |
| 106 | parentN = obj.parentN || 200; |
| 107 | |
| 108 | //li默认宽度 |
| 109 | childN = obj.childN || 80; |
| 110 | |
| 111 | //父盒子默认100%宽度 |
| 112 | parent.style.width = document.documentElement.clientWidth + 'px'; |
| 113 | |
| 114 | parent.style.height = parentN + 'px'; |
| 115 | |
| 116 | //子盒子宽度 |
| 117 | child.style.width = lisLength * childN + 'px'; |
| 118 | |
| 119 | child.style.height = parentN + 'px'; |
| 120 | |
| 121 | var parentWH = parent.offsetWidth; |
| 122 | |
| 123 | var childWH = childN * lisLength; |
| 124 | |
| 125 | //获取定位最小区间 |
| 126 | minPosition = parentWH - childWH; |
| 127 | |
| 128 | minSwipe = minPosition - distance; |
| 129 | |
| 130 | maxSwipe = maxPosition + distance; |
| 131 | |
| 132 | setTranslate(child, 'x', 0); |
| 133 | |
| 134 | goL(); |
| 135 | |
| 136 | } |
| 137 | |
| 138 | //水平初始化 |
| 139 | |
| 140 | function goL() { |
| 141 | |
| 142 | var i = 0; |
| 143 | |
| 144 | for (i; i < lisLength; i += 1) { |
| 145 | |
| 146 | lis[i].style.width = childN + 'px'; |
| 147 | |
| 148 | lis[i].style.height = '100%'; |
| 149 | |
| 150 | lis[i].style.textAlign = 'center'; |
| 151 | |
| 152 | lis[i].style.lineHeight = parentN + 'px'; |
| 153 | |
| 154 | lis[i].style.float = 'left'; |
| 155 | |
| 156 | aStyle(lis[i]); |
| 157 | |
| 158 | } |
| 159 | |
| 160 | } |
| 161 | |
| 162 | //垂直初始化 |
| 163 | |
| 164 | function goV() { |
| 165 | |
| 166 | var i = 0; |
| 167 | |
| 168 | for (i; i < lisLength; i += 1) { |
| 169 | |
| 170 | lis[i].style.width = '100%'; |
| 171 | |
| 172 | lis[i].style.height = childN + 'px'; |
| 173 | |
| 174 | lis[i].style.textAlign = 'center'; |
| 175 | |
| 176 | lis[i].style.lineHeight = childN + 'px'; |
| 177 | |
| 178 | aStyle(lis[i]); |
| 179 | |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | //给a设置style |
| 184 | |
| 185 | function aStyle(dom) { |
| 186 | |
| 187 | dom.querySelector('a').style.display = 'block'; |
| 188 | |
| 189 | dom.querySelector('a').style.height = '100%'; |
| 190 | |
| 191 | dom.querySelector('a').style.color = '#333'; |
| 192 | |
| 193 | dom.querySelector('a').style.textDecoration = 'none'; |
| 194 | |
| 195 | } |
| 196 | |
| 197 | //子盒子绑定滑动事件 |
| 198 | child.addEventListener('touchstart', function(e) { |
| 199 | |
| 200 | if (type == 'vertical') { |
| 201 | |
| 202 | startD = e.touches[0].clientY; |
| 203 | |
| 204 | } |
| 205 | |
| 206 | if (type == 'level') { |
| 207 | |
| 208 | startD = e.touches[0].clientX; |
| 209 | |
| 210 | } |
| 211 | |
| 212 | }) |
| 213 | |
| 214 | |
| 215 | //滑动中 |
| 216 | child.addEventListener('touchmove', function(e) { |
| 217 | |
| 218 | if (type == 'vertical') { |
| 219 | |
| 220 | moveD = e.touches[0].clientY; |
| 221 | |
| 222 | xy = 'y'; |
| 223 | |
| 224 | } |
| 225 | |
| 226 | if (type == 'level') { |
| 227 | |
| 228 | moveD = e.touches[0].clientX; |
| 229 | |
| 230 | xy = 'x'; |
| 231 | } |
| 232 | |
| 233 | goD = moveD - startD + currSwipe; |
| 234 | |
| 235 | removeTransition(child); |
| 236 | |
| 237 | if (goD > minSwipe && goD < maxSwipe) { |
| 238 | |
| 239 | setTranslate(child, xy, goD); |
| 240 | |
| 241 | } |
| 242 | |
| 243 | }) |
| 244 | |
| 245 | //滑动结束 |
| 246 | window.addEventListener('touchend', function() { |
| 247 | |
| 248 | //最终定位 |
| 249 | if (goD > maxPosition) { |
| 250 | |
| 251 | currSwipe = maxPosition; |
| 252 | |
| 253 | addTransition(child); |
| 254 | |
| 255 | setTranslate(child, xy, currSwipe); |
| 256 | |
| 257 | } else if (goD < minPosition) { |
| 258 | |
| 259 | currSwipe = minPosition; |
| 260 | |
| 261 | console.log(minPosition); |
| 262 | |
| 263 | addTransition(child); |
| 264 | |
| 265 | setTranslate(child, xy, currSwipe); |
| 266 | } else { |
| 267 | |
| 268 | currSwipe = goD; |
| 269 | |
| 270 | } |
| 271 | |
| 272 | startD = 0; |
| 273 | moveD = 0; |
| 274 | goD = 0; |
| 275 | |
| 276 | }) |
| 277 | |
| 278 | |
| 279 | //如果开启单机索引 |
| 280 | if (goli) { |
| 281 | |
| 282 | //循环绑定点击事件 |
| 283 | for (var j = 0; j < lisLength; j += 1) { |
| 284 | |
| 285 | lis[j].index = j; |
| 286 | |
| 287 | tap(lis[j], function(e) { |
| 288 | |
| 289 | if (type == 'level') { |
| 290 | xy = 'x'; |
| 291 | } |
| 292 | |
| 293 | if (type == 'vertical') { |
| 294 | xy = 'y'; |
| 295 | } |
| 296 | |
| 297 | //找到父元素 |
| 298 | var li = e.target.parentNode; |
| 299 | |
| 300 | for (var n = 0; n < lisLength; n += 1) { |
| 301 | |
| 302 | lis[n].className = ''; |
| 303 | |
| 304 | } |
| 305 | |
| 306 | li.className = lisname; |
| 307 | |
| 308 | //计算位置 |
| 309 | var tapGoD = -li.index * childN; |
| 310 | |
| 311 | if (tapGoD > minPosition) { |
| 312 | |
| 313 | currSwipe = tapGoD; |
| 314 | |
| 315 | addTransition(child); |
| 316 | |
| 317 | setTranslate(child, xy, currSwipe); |
| 318 | |
| 319 | } else { |
| 320 | |
| 321 | currSwipe = minPosition; |
| 322 | |
| 323 | setTranslate(child, xy, currSwipe); |
| 324 | |
| 325 | } |
| 326 | |
| 327 | }) |
| 328 | |
| 329 | } |
| 330 | |
| 331 | } |
| 332 | |
| 333 | //封装单机事件 |
| 334 | |
| 335 | function tap(dom, callback) { |
| 336 | |
| 337 | /*判断dom是不是一个对象 如果是才给他绑定事件*/ |
| 338 | if (typeof dom == 'object') { |
| 339 | |
| 340 | /*判断是否滑动过*/ |
| 341 | var isMove = false; |
| 342 | |
| 343 | /*记录刚刚触摸到屏幕的时候的时间*/ |
| 344 | var time = 0; |
| 345 | |
| 346 | dom.addEventListener('touchstart', function(e) { |
| 347 | |
| 348 | /*刚刚触摸到屏幕的时候的时间*/ |
| 349 | time = Date.now(); |
| 350 | |
| 351 | }); |
| 352 | |
| 353 | dom.addEventListener('touchmove', function(e) { |
| 354 | |
| 355 | /*设置为true*/ |
| 356 | isMove = true; |
| 357 | |
| 358 | }); |
| 359 | |
| 360 | window.addEventListener('touchend', function(e) { |
| 361 | |
| 362 | /* |
| 363 | * tap事件的要求 |
| 364 | *1.没有滑动过 |
| 365 | *2.响应时间在150ms以内 |
| 366 | * */ |
| 367 | if (!isMove && (Date.now() - time) < 150) { |
| 368 | |
| 369 | /*为了提高响应的速度*/ |
| 370 | callback && callback(e); |
| 371 | |
| 372 | } |
| 373 | |
| 374 | isMove = false; |
| 375 | time = 0; |
| 376 | |
| 377 | }); |
| 378 | |
| 379 | } |
| 380 | }; |
| 381 | } |
插件下载地址:百度网盘 欢迎共同探讨!

浙公网安备 33010602011771号