布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <div id="app"> <div id="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"><img src="./img/1.jpg"></div> <div class="swiper-slide"><img src="./img/2.jpg"></div> <div class="swiper-slide"><img src="./img/3.jpg"></div> <div class="swiper-slide"><img src="./img/4.jpg"></div> <div class="swiper-slide"><img src="./img/5.jpg"></div> </div> <div class="swiper-pagination"> <span class="active"></span> <span></span> <span></span> <span></span> <span></span> </div> </div> </div>
|
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
| * { margin: 0; padding: 0; }
ul { list-style: none; } html, body, #app { width: 100%; height: 100%; overflow: hidden; } #swiper-container{ width: 100%; height: 176px; position: relative;
.swiper-wrapper{ width: 500%; overflow: hidden;
.swiper-slide{ width: 20%; float: left; img{ width: 100%; display: block; } } } .swiper-pagination{ position: absolute; width: 100%; height: 10px; left:0; bottom: 10px; line-height: 10px; text-align: center; span{ display: inline-block; width: 10px; height: 10px; background: #fff; border-radius: 50%; margin-right: 4px; } .active{ background: darkorange; } } }
|
可拖拽
为包裹图片的容器开启定位
1 2 3
| .swiper-wrapper { position: absolute; }
|
接下来使用js动态改变这个容器的位置即可。
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
| const app = document.querySelector('#app')
const container = document.querySelector('#swiper-container') const wrapper = container.querySelector('.swiper-wrapper')
app.addEventListener('touchstart', function (e) { e.preventDefault() })
container.addEventListener('touchstart', function (e) { this.x = e.touches[0].clientX
this.left = wrapper.offsetLeft })
container.addEventListener('touchmove', function (e) { this._x = e.touches[0].clientX const newLeft = this._x - this.x + this.left wrapper.style.left = newLeft + 'px' })
|
拖拽切换
向左划动切换右边的一张图片,向右滑动切换左边的一张图片。
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
| const len = container.querySelectorAll('.swiper-slide')
let index = 0
const dots = container.querySelectorAll('.swiper-pagination span')
container.addEventListener('touchend', function (e) { this._x = e.changedTouches[0].clientX if (this._x < this.x) { index++ } if (this._x > this.x) { index-- } if (index < 0) { index = 0 } if (index > len.length - 1) { index = len.length - 1 }
const newLeft = -index * container.offsetWidth wrapper.style.left = newLeft + 'px'
dots.forEach(function (dot) { dot.classList.remove('active') }) dots[index].classList.add('active') })
|
优化-过渡效果
当按下时移除过度样式,抬起时添加样式即可。
1 2 3 4 5 6 7 8
| container.addEventListener('touchstart', function (e) { wrapper.style.transition = 'none' }) container.addEventListener('touchend', function (e) { wrapper.style.transition = 'all .5s' }
|
元素初始化设置
为元素设置初始高度宽度以及动态创建导航点的个数
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
| function init() { window.onload = function () { const h = slides[0].offsetHeight container.style.height = h + 'px' } wrapper.style.width = slides.length * 100 + '%' slides.forEach((item) => { item.style.width = 100 / slides.length + '%' }) for (var i = 0; i < slides.length; i++) { const span = document.createElement('span') if (i == 0) { span.className = 'active' } pagination.appendChild(span) } dots = container.querySelectorAll('.swiper-pagination span') } init()
|
无缝滚动
无缝滚动采用的方案是新插入一组一模一样的图片,当向左滑动(第一张)时迅速切换到第二组的第一张。
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
| wrapper.innerHTML += wrapper.innerHTML const slidesNew = container.querySelectorAll('.swiper-slide')
container.addEventListener('touchstart', function (e) { wrapper.style.transition = 'none' this.touchStartTime = Date.now() if (index == 0) { index = slides.length const newLeft = -index * container.offsetWidth wrapper.style.left = newLeft + 'px' } if (index == slidesNew.length - 1) { index = slides.length - 1 const newLeft = -index * container.offsetWidth wrapper.style.left = newLeft + 'px' } this.x = e.touches[0].clientX
this.left = wrapper.offsetLeft })
|
自动播放
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
| function autoRun() { clearInterval(timer) timer = setInterval(function () { index++ wrapper.style.transition = 'all .5s' const newLeft = -index * container.offsetWidth wrapper.style.left = newLeft + 'px'
dots.forEach(function (dot) { dot.classList.remove('active') }) dots[index % slides.length].classList.add('active') }, 1000) } autoRun()
wrapper.addEventListener('transitionend', (e) => { if (index === slidesNew.length - 1) { wrapper.style.transition = 'none' index = slides.length - 1 const newLeft = -index * container.offsetWidth wrapper.style.left = newLeft + 'px' } })
|
封装及优化后的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 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
| import '../style/index.less'
const app = document.querySelector('#app')
const container = document.querySelector('#swiper-container') const wrapper = container.querySelector('.swiper-wrapper')
const slides = container.querySelectorAll('.swiper-slide')
var index = 0
let dots = null
const pagination = container.querySelector('.swiper-pagination')
let timer = null
wrapper.innerHTML += wrapper.innerHTML const slidesNew = container.querySelectorAll('.swiper-slide')
let isHori = true let isFirst = true
container.addEventListener('touchstart', function (e) { wrapper.style.transition = 'none' this.touchStartTime = Date.now() if (index == 0) { index = slides.length } if (index == slidesNew.length - 1) { index = slides.length - 1 } container.switchSlide(index, false) this.x = e.touches[0].clientX this.y = e.touches[0].clientY
this.left = wrapper.offsetLeft clearInterval(timer) })
container.addEventListener('touchmove', function (e) { this._x = e.touches[0].clientX this._y = e.touches[0].clientY
const disY = Math.abs(this._y - this.y) const disX = Math.abs(this._x - this.x) if (isFirst) { isFirst = false if (disY > disX) { isHori = false } if (disY < disX) { isHori = true } } if (isHori) { e.preventDefault() } else { return } const newLeft = this._x - this.x + this.left wrapper.style.left = newLeft + 'px' })
container.addEventListener('touchend', function (e) { isFirst = true
if (!isHori) return this._x = e.changedTouches[0].clientX const disX = Math.abs(this._x - this.x) this.touchEndTime = Date.now()
if ( disX > container.offsetWidth / 2 || this.touchEndTime - this.touchStartTime <= 300 ) { if (this._x < this.x) { index++ } if (this._x > this.x) { index-- } }
if (index < 0) { index = 0 } if (index > slidesNew.length - 1) { index = slidesNew.length - 1 } this.switchSlide(index) this.autoRun() })
wrapper.addEventListener('transitionend', (e) => { if (index === slidesNew.length - 1) { index = slides.length - 1 container.switchSlide(index, false) } })
container.init = function () { window.onload = function () { const h = slidesNew[0].offsetHeight container.style.height = h + 'px' } wrapper.style.width = slidesNew.length * 100 + '%' slidesNew.forEach((item) => { item.style.width = 100 / slidesNew.length + '%' }) for (var i = 0; i < slides.length; i++) { const span = document.createElement('span') if (i == 0) { span.className = 'active' } pagination.appendChild(span) } dots = container.querySelectorAll('.swiper-pagination span') } container.init()
container.autoRun = function () { clearInterval(timer) timer = setInterval(function () { index++ container.switchSlide(index) }, 1000) } container.autoRun()
container.switchSlide = function (i, isTransition) { if (isTransition === undefined) { isTransition = true } if (isTransition) { wrapper.style.transition = 'all .5s' } else { wrapper.style.transition = 'none' }
const newLeft = -i * container.offsetWidth wrapper.style.left = newLeft + 'px'
dots.forEach(function (dot) { dot.classList.remove('active') }) dots[i % slides.length].classList.add('active') index = i }
|