博客列表 >原生js实现选项卡和轮播图

原生js实现选项卡和轮播图

Jason Pu?
Jason Pu?原创
2021年01月12日 15:58:04987浏览

一:前置知识

1.事件代理:
事件绑定者:ev.currentTarget
事件触发者:ev.target
思维:给母元素添加事件,通过ev.target解发事件的元素

2.dataset对象:自定义属性
dataset对象专用于访问自定义的标签属性,在自定义属性前面加上data-,便可以用“dataset.自定义标签名”,进行访问,如果自定义的标签是两个单词组成且中间有加”-“,访问时要省略掉”-“,并把第二个单词首字母进行大写

二:JS实战选项卡

思维:定义3个dataset,分别放在对应的主题和内容区标签里,利用事件绑定给相同的dataset自定义属性的classList添加active
html部分:

  1. <div class="box">
  2. <ul class="nav">
  3. <li data-index="1" class="active">财经</li>
  4. <li data-index="2">股票</li>
  5. <li data-index="3">理财</li>
  6. </ul>
  7. <ul data-index="1" class="content active">
  8. <li><a href="">道歉变自夸 全棉时代忘了本</a></li>
  9. <li><a href="">拉夏贝尔内斗激烈 一年五换总裁</a></li>
  10. <li><a href="">深圳华强北6亿缉私震荡波</a></li>
  11. </ul>
  12. <ul data-index="2" class="content">
  13. <li><a href="">[美股]小摩:价值股即将咸鱼翻身</a></li>
  14. <li><a href="">[港股]百度回港上市AB面</a></li>
  15. <li><a href="">猪肉价格浮沉启示 A股需坚守信仰</a></li>
  16. </ul>
  17. <ul data-index="3" class="content">
  18. <li><a href="">极致行情虐惨量化对冲基金</a></li>
  19. <li><a href="">数字人民币在上海扩大试点 已实现“双离线”支付</a></li>
  20. <li><a href="">[黄金] 国债收益率上攻叠加美指反弹 黄金出现急跌</a></li>
  21. </ul>
  22. </div>

css部分:

  1. *{
  2. margin: 0;
  3. padding: 0;
  4. box-sizing: border-box;
  5. list-style: none;
  6. text-decoration: none;
  7. }
  8. .box{
  9. margin: 30px;
  10. }
  11. a{
  12. color: #666;
  13. }
  14. a:hover{
  15. text-decoration: underline;
  16. color: red;
  17. }
  18. .box{
  19. width: 300px;
  20. height: 300px;
  21. margin: 30px;
  22. border-color: #F7F7F7;
  23. display: flex;
  24. flex-direction: column;
  25. }
  26. .nav{
  27. height: 36px;
  28. display: flex;
  29. border-left: 1px solid #DBDEE1;
  30. border-top: 1px solid #DBDEE1;
  31. border-right: 1px solid #DBDEE1;
  32. }
  33. .nav li{
  34. flex: auto;
  35. text-align: center;
  36. line-height: 36px;
  37. background-color: #F8F8F8;
  38. border-bottom: 1px solid #DBDEE1;
  39. border-left: 1px solid #DBDEE1;
  40. }
  41. .nav li:hover{
  42. border-bottom: none;
  43. background-color: white;
  44. }
  45. /* 默认所有选项卡只能显示active*/
  46. .content{
  47. padding: 20px;
  48. display: none;
  49. }
  50. .content.active{
  51. display: block;
  52. }

js实现:

  1. const nav = document.querySelector(".nav");
  2. const content=document.querySelectorAll(".content");
  3. nav.onmouseover = ev =>{
  4. Array.from(nav.children).forEach(lis=>lis.classList.remove("active"));
  5. ev.target.classList.add("active");
  6. // 根据自定义属性data-index找到对应的content并显示
  7. content.forEach(lis=>lis.classList.remove("active"));
  8. //filter方法虽然只返回了一个结果,但还是数组,所以要加[0]:
  9. let result = Array.from(content).filter(lis=>lis.dataset.index===ev.target.dataset.index)[0];
  10. result.classList.add("active");
  11. }

效果如下:
before:

onmouseover:

三.js事件代理实现轮播图,并实现自动播放,鼠标移入停止播放功能

html部分:

  1. <div class="container">
  2. <!-- 1. 图片组 -->
  3. <nav class="imgs">
  4. <a href="#"
  5. ><img src="banner/banner1.jpg" alt="" data-index="1" class="active"
  6. /></a>
  7. <a href="#"><img src="banner/banner2.jpg" alt="" data-index="2" /></a>
  8. <a href="#"><img src="banner/banner3.jpg" alt="" data-index="3" /></a>
  9. <a href="#"><img src="banner/banner4.jpg" alt="" data-index="4" /></a>
  10. </nav>
  11. <!-- 2. 与图片组对应的按钮组(一个个独立的,数量与图片数量是相同的) -->
  12. <nav class="btns">
  13. <!-- 这些小按钮应该是js根据图片数量动态来创建 -->
  14. <!-- <a href="#" data-index="1" class="active"></a>
  15. <a href="#" data-index="2"></a>
  16. <a href="#" data-index="3"></a>
  17. <a href="#" data-index="4"></a> -->
  18. </nav>
  19. <!-- 3. 翻页按钮(只有二个,分别在左右) -->
  20. <nav class="skip">
  21. <!-- &lt;: 实体符号 -->
  22. <a href="#" class="prev">&lt;</a>
  23. <a href="#" class="next">&gt;</a>
  24. </nav>
  25. </div>

基本js功能:

  1. //图片
  2. const imgs = document.querySelectorAll(".container > .imgs img");
  3. //按钮
  4. const btnList = document.querySelector(" .container > .btns");
  5. //小耳朵
  6. const skip = document.querySelector(".skip");
  7. //----------------------------生成小圆点-------------------------------------
  8. //生成和图片数量一致的小圆点:
  9. function antoCreateSpot(position,img){
  10. //使用文档片断:
  11. const frag = document.createDocumentFragment();
  12. for(let i=0;i<img.length;i++){
  13. const a = document.createElement("a");
  14. a.href="#";
  15. a.dataset.index = i+1;//data-index="i+1"
  16. if(i===0)a.classList.add("active");//为第一个添加active
  17. frag.appendChild(a);
  18. }
  19. position.appendChild(frag);
  20. };
  21. antoCreateSpot(btnList,imgs);//调用函数并实现生成小圆点
  22. // 获取一下生成的小圆点的所有元素:
  23. const spot=document.querySelectorAll(".container > .btns > *");

创建公共函数:

  1. //----------------------------公共函数区-------------------------------------
  2. //1.获取激活元素函数:
  3. function getActivedElement(elements){
  4. //contains():判断DOM元素的包含关系,返回布尔值
  5. let actived = [...elements].filter(img=>img.classList.contains("active"));
  6. return actived[0];//filter返回的是数组,所以要加[0]
  7. };
  8. //2.设置激活的元素:
  9. function setActiveElement(btnIndex){
  10. //同时遍历所有图片和按钮
  11. [imgs,spot].forEach(arr => {
  12. // 取消当前激活元素的状态:
  13. getActivedElement(arr).classList.remove("active");
  14. //根据当前用户点击的按钮的索引,重置应该激活的元素:
  15. arr.forEach(item =>{
  16. if(item.dataset.index === btnIndex){
  17. item.classList.add("active");
  18. }
  19. })
  20. });
  21. };

给小圆点添加事件:

  1. spot.forEach(btn=>
  2. btn.addEventListener("click",ev=>setActiveElement(ev.target.dataset.index))
  3. );

让两侧的小耳机变活:

  1. skip.addEventListener("click",skipImg);
  2. skip.children[1].addEventListener("click",skipImg);
  3. function skipImg(ev){
  4. // 获取当前被激活的图片:
  5. let currentImg = getActivedElement(imgs);
  6. //获取当前激活的图片包裹器的元素,因为图片包在a元素里面,所以要弄两次:
  7. let parentEle = currentImg.parentElement.parentElement;
  8. //获取当前激活元素的上一个兄弟节点:
  9. let preEle = currentImg.parentElement.previousElementSibling;
  10. //获取当前激活元素的下一个兄弟节点:
  11. let nextEle = currentImg.parentElement.nextElementSibling;
  12. //第一张图片:
  13. let firstImg = parentEle.firstElementChild.firstElementChild;
  14. //最后一张图片:
  15. let lastImg = parentEle.lastElementChild.lastElementChild;
  16. let activeImg = currentImg;
  17. //向前:
  18. if (ev.target.classList.contains("prev")){
  19. //向前图片使用完毕,自动到最后一张
  20. let activeImg=preEle !==null?preEle.firstElementChild:lastImg;
  21. setActiveElement(activeImg.dataset.index);//同步更新
  22. }
  23. //向后:
  24. if(ev.target.classList.contains("next")){
  25. //向后结束后自动到第一张:
  26. let activeImg=nextEle !==null?nextEle.firstElementChild:firstImg;
  27. setActiveElement(activeImg.dataset.index);
  28. }
  29. }

让轮播图自动动起来:

  1. let sk = null;
  2. const clickEvent = new Event("click");
  3. const box = document.querySelector(".container");
  4. const autonext = document.querySelector(".skip .next");
  5. box.addEventListener("mouseover",stop);
  6. box.addEventListener("mouseout",start);
  7. setTimeout(function (){
  8. start()},1000);
  9. function start(){
  10. sk = setInterval(function (){
  11. autonext.dispatchEvent(clickEvent)
  12. },2000);
  13. }
  14. function stop(){
  15. clearInterval(sk);
  16. }
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议