博客列表 >懒加载及轮播图

懒加载及轮播图

小丑0o鱼
小丑0o鱼原创
2021年07月20日 19:27:52713浏览
  1. 懒加载原理及实现
  2. 1.懒加载原理
  3. 一张图片就是一个<img>标签,浏览器发起图片请求,请求是根据<img>的src属性加载图片,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给<img>的src赋值,这样浏览器就加载不到图片了,等到图片进入可视区域再给src赋值。
  4. 2.懒加载思路及实现
  5. 实现懒加载有四个步骤,如下:
  6. 1.加载loading定位图片
  7. 2.判断哪些图片要加载【重点】
  8. 3.隐形加载图片
  9. 4.替换真图片
  10. 懒加载原理
  11. 视口高度:document.documentElement.clientHeight
  12. 当前元素相对于其 offsetParent 元素的顶部的距离:HTMLElement.offsetTop
  13. 滚动条移动高度:document.documentElement.scrollTop
  14. 如上图所示,当图片距离顶部的距离offsetTop等于可视区域clientHeight和滚动区域高度scrollTop之和时说明图片马上就要进入可视区了,就是说当offsetTop<=clientHeight + scrollTop时,图片在可视区。
  15. 示例
  16. 懒加载
  17. css
  18. <style>
  19. .container {
  20. width: 500px;
  21. display: grid;
  22. grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  23. }
  24. .container img {
  25. width: 100%;
  26. }
  27. </style>
  28. html
  29. <div class="container">
  30. <img src="images/temp.jpg" alt="" data-src="images/img-1.jpg">
  31. <img src="images/temp.jpg" alt="" data-src="images/img-2.jpg">
  32. <img src="images/temp.jpg" alt="" data-src="images/img-3.jpg">
  33. <img src="images/temp.jpg" alt="" data-src="images/img-4.jpg">
  34. <img src="images/temp.jpg" alt="" data-src="images/img-5.jpg">
  35. <img src="images/temp.jpg" alt="" data-src="images/img-6.jpg">
  36. <img src="images/temp.jpg" alt="" data-src="images/img-7.jpg">
  37. <img src="images/temp.jpg" alt="" data-src="images/img-8.jpg">
  38. <img src="images/temp.jpg" alt="" data-src="images/img-9.jpg">
  39. <img src="images/temp.jpg" alt="" data-src="images/img-10.jpg">
  40. <img src="images/temp.jpg" alt="" data-src="images/img-11.jpg">
  41. <img src="images/temp.jpg" alt="" data-src="images/img-12.jpg">
  42. <img src="images/temp.jpg" alt="" data-src="images/img-13.jpg">
  43. <img src="images/temp.jpg" alt="" data-src="images/img-14.jpg">
  44. <img src="images/temp.jpg" alt="" data-src="images/img-15.jpg">
  45. <img src="images/temp.jpg" alt="" data-src="images/img-16.jpg">
  46. <img src="images/temp.jpg" alt="" data-src="images/img-17.jpg">
  47. <img src="images/temp.jpg" alt="" data-src="images/img-18.jpg">
  48. <img src="images/temp.jpg" alt="" data-src="images/img-19.jpg">
  49. <img src="images/temp.jpg" alt="" data-src="images/img-20.jpg">
  50. <img src="images/temp.jpg" alt="" data-src="images/img-21.jpg">
  51. <img src="images/temp.jpg" alt="" data-src="images/img-22.jpg">
  52. <img src="images/temp.jpg" alt="" data-src="images/img-23.jpg">
  53. <img src="images/temp.jpg" alt="" data-src="images/img-24.jpg">
  54. <img src="images/temp.jpg" alt="" data-src="images/img-25.jpg">
  55. <img src="images/temp.jpg" alt="" data-src="images/img-26.jpg">
  56. <img src="images/temp.jpg" alt="" data-src="images/img-27.jpg">
  57. <img src="images/temp.jpg" alt="" data-src="images/img-28.jpg">
  58. <img src="images/temp.jpg" alt="" data-src="images/img-29.jpg">
  59. <img src="images/temp.jpg" alt="" data-src="images/img-30.jpg">
  60. <img src="images/temp.jpg" alt="" data-src="images/img-31.jpg">
  61. <img src="images/temp.jpg" alt="" data-src="images/img-32.jpg">
  62. <img src="images/temp.jpg" alt="" data-src="images/img-33.jpg">
  63. <img src="images/temp.jpg" alt="" data-src="images/img-34.jpg">
  64. <img src="images/temp.jpg" alt="" data-src="images/img-35.jpg">
  65. <img src="images/temp.jpg" alt="" data-src="images/img-36.jpg">
  66. <img src="images/temp.jpg" alt="" data-src="images/img-37.jpg">
  67. <img src="images/temp.jpg" alt="" data-src="images/img-38.jpg">
  68. <img src="images/temp.jpg" alt="" data-src="images/img-39.jpg">
  69. <img src="images/temp.jpg" alt="" data-src="images/img-40.jpg">
  70. <img src="images/temp.jpg" alt="" data-src="images/img-41.jpg">
  71. <img src="images/temp.jpg" alt="" data-src="images/img-42.jpg">
  72. <img src="images/temp.jpg" alt="" data-src="images/img-43.jpg">
  73. <img src="images/temp.jpg" alt="" data-src="images/img-44.jpg">
  74. <img src="images/temp.jpg" alt="" data-src="images/img-45.jpg">
  75. <img src="images/temp.jpg" alt="" data-src="images/img-46.jpg">
  76. <img src="images/temp.jpg" alt="" data-src="images/img-47.jpg">
  77. <img src="images/temp.jpg" alt="" data-src="images/img-48.jpg">
  78. <img src="images/temp.jpg" alt="" data-src="images/img-49.jpg">
  79. <img src="images/temp.jpg" alt="" data-src="images/img-50.jpg">
  80. <img src="images/temp.jpg" alt="" data-src="images/img-51.jpg">
  81. <img src="images/temp.jpg" alt="" data-src="images/img-52.jpg">
  82. <img src="images/temp.jpg" alt="" data-src="images/img-53.jpg">
  83. <img src="images/temp.jpg" alt="" data-src="images/img-54.jpg">
  84. <img src="images/temp.jpg" alt="" data-src="images/img-55.jpg">
  85. <img src="images/temp.jpg" alt="" data-src="images/img-56.jpg">
  86. <img src="images/temp.jpg" alt="" data-src="images/img-57.jpg">
  87. <img src="images/temp.jpg" alt="" data-src="images/img-58.jpg">
  88. <img src="images/temp.jpg" alt="" data-src="images/img-59.jpg">
  89. <img src="images/temp.jpg" alt="" data-src="images/img-60.jpg">
  90. <img src="images/temp.jpg" alt="" data-src="images/img-61.jpg">
  91. <img src="images/temp.jpg" alt="" data-src="images/img-62.jpg">
  92. <img src="images/temp.jpg" alt="" data-src="images/img-63.jpg">
  93. <img src="images/temp.jpg" alt="" data-src="images/img-64.jpg">
  94. <img src="images/temp.jpg" alt="" data-src="images/img-65.jpg">
  95. <img src="images/temp.jpg" alt="" data-src="images/img-66.jpg">
  96. <img src="images/temp.jpg" alt="" data-src="images/img-67.jpg">
  97. <img src="images/temp.jpg" alt="" data-src="images/img-68.jpg">
  98. <img src="images/temp.jpg" alt="" data-src="images/img-69.jpg">
  99. <img src="images/temp.jpg" alt="" data-src="images/img-70.jpg">
  100. </div>
  101. js
  102. // 所有图片
  103. const imgs = document.querySelectorAll('.container > img');
  104. // 图片加载函数
  105. function imgLoad() {
  106. // 视口高度
  107. let viewHeight = document.documentElement.clientHeight;
  108. // 滚动距离
  109. let scrollTop = document.documentElement.scrollTop;
  110. imgs.forEach((img) => {
  111. // 判断是否进入视口
  112. if (img.offsetTop <= viewHeight + scrollTop) {
  113. setTimeout(() => {
  114. img.src = img.dataset.src;
  115. }, 500);
  116. }
  117. });
  118. }
  119. // 加载时
  120. window.addEventListener('load', imgLoad);
  121. // 滚动条
  122. window.addEventListener('scroll', imgLoad);
  123. // 视口变化时
  124. window.addEventListener('resize', imgLoad);
  125. 轮播图
  126. css
  127. /* 初始化 */
  128. * {
  129. margin: 0;
  130. padding: 0;
  131. box-sizing: border-box;
  132. }
  133. a {
  134. text-decoration: none;
  135. }
  136. /* 轮播图的容器 */
  137. .container {
  138. width: 62.5em;
  139. height: 22em;
  140. margin: 1em auto;
  141. /* 转为定位元素/定位父级 */
  142. position: relative;
  143. }
  144. /* 图片组 */
  145. .container > .imgs img {
  146. width: 100%;
  147. height: 100%;
  148. /* 默认全部隐藏 */
  149. display: none;
  150. /* 将所有的图片进行绝对定位,确保每一次只看到一张,所有图片共享这个容器 */
  151. position: absolute;
  152. left: 0;
  153. top: 0;
  154. }
  155. /* 设置默认显示的图片(第一张) */
  156. .container > .imgs img.active {
  157. display: block;
  158. }
  159. /* 按钮组(独立按钮) */
  160. .container > .btns {
  161. position: absolute;
  162. left: 0;
  163. right: 0;
  164. bottom: 0;
  165. /* 水平居中 */
  166. text-align: center;
  167. }
  168. .container > .btns a {
  169. /* 转成行内块元素: 即能水平排列,双支持宽度设置 */
  170. display: inline-block;
  171. padding: 0.5em;
  172. margin: 0 0.2em;
  173. background-color: #fff;
  174. border-radius: 50%;
  175. }
  176. .container > .btns a.active {
  177. background-color: #000;
  178. }
  179. /* 翻页按钮 */
  180. .container .skip a {
  181. position: absolute;
  182. width: 2.5rem;
  183. height: 5rem;
  184. line-height: 5rem;
  185. text-align: center;
  186. opacity: 0.3;
  187. top: 9rem;
  188. font-weight: lighter;
  189. font-size: 2rem;
  190. background-color: #ccc;
  191. }
  192. .container .skip .prev {
  193. left: 0;
  194. }
  195. .container .skip .next {
  196. right: 0;
  197. }
  198. .container .skip *:hover {
  199. opacity: 0.6;
  200. color: #666;
  201. }
  202. html
  203. <div class="container">
  204. <!-- 1. 图片组 -->
  205. <nav class="imgs">
  206. <a href="#"><img src="banner/banner1.jpg" alt="" data-index="1" class="active" /></a>
  207. <a href="#"><img src="banner/banner2.jpg" alt="" data-index="2" /></a>
  208. <a href="#"><img src="banner/banner3.jpg" alt="" data-index="3" /></a>
  209. <a href="#"><img src="banner/banner4.jpg" alt="" data-index="4" /></a>
  210. </nav>
  211. <!-- 2. 图片中下部的小按钮 -->
  212. <nav class="btns">
  213. </nav>
  214. <!-- 3. 翻页 -->
  215. <nav class="skip">
  216. <a href="#" class="prev">&lt;</a>
  217. <a href="#" class="next">&gt;</a>
  218. </nav>
  219. </div>
  220. javascript
  221. // 获得元素
  222. const imgs = document.querySelectorAll('.container >.imgs img');
  223. const btnGroup = document.querySelector('.container > .btns');
  224. const skips = document.querySelector('.container > .skip');
  225. // 创建小按钮的函数
  226. function createBtns(ele,imgLength) {
  227. // 临时父类
  228. let tempBtns = document.createDocumentFragment();
  229. for (let i = 0; i < imgLength; i++) {
  230. let a = document.createElement('a');
  231. a.href = '#';
  232. a.dataset.index = `${i + 1}`;
  233. if ( i === 0) {
  234. a.classList.add('active');
  235. }
  236. tempBtns.append(a);
  237. }
  238. ele.append(tempBtns);
  239. }
  240. // 创建按钮
  241. createBtns(btnGroup,imgs.length);
  242. const btns = document.querySelectorAll('.container > .btns > *');
  243. // 获得activeEle
  244. function getActiveEle(eles) {
  245. let activeEle = [...eles].filter((ele)=>ele.classList.contains('active'));
  246. return activeEle[0];
  247. }
  248. // 设置active元素
  249. function setActiveEle(Index) {
  250. [imgs,btns].forEach((items) =>{
  251. getActiveEle(items).classList.remove('active');
  252. items.forEach((item)=>{
  253. if (item.dataset.index == Index) {
  254. item.classList.add('active');
  255. }
  256. });
  257. });
  258. }
  259. // 小按钮点击事件
  260. btns.forEach((item)=>{item.addEventListener('click',(ev)=>{setActiveEle(ev.target.dataset.index)})});
  261. // 获得当前active元素index
  262. let currentEleIndex = getActiveEle(imgs).dataset.index;
  263. // 上页 下页
  264. skips.querySelector('.next').addEventListener('click', nextEle);
  265. skips.querySelector('.prev').addEventListener('click', prevEle);
  266. // 下页函数
  267. function nextEle(ev) {
  268. if ( ++currentEleIndex > imgs.length) {
  269. currentEleIndex = imgs[0].dataset.index;
  270. }
  271. setActiveEle(currentEleIndex);
  272. }
  273. // 上页函数
  274. function prevEle(ev){
  275. if ( --currentEleIndex < imgs[0].dataset.index) {
  276. currentEleIndex = imgs[imgs.length - 1].dataset.index;
  277. }
  278. setActiveEle(currentEleIndex);
  279. }
  280. // 轮播
  281. const container = document.querySelector('.container');
  282. container.addEventListener('mouseover', stopRun, false);
  283. container.addEventListener('mouseout', startRun, false);
  284. container.addEventListener('run', nextEle);
  285. // 定时器
  286. let timer = [];
  287. const evt = new Event('run');
  288. function startRun(ev) {
  289. timer = setInterval('container.dispatchEvent(evt)',2000);
  290. }
  291. function stopRun(ev) {
  292. clearInterval(timer);
  293. }
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议