原生js实现网页淘宝产品展示效果,鼠标移入小图展示对应大图(事件委托、事件传播、冒泡机制)【含完整代码】

原生js实现淘宝网页的产品展示框效果

淘宝网页产品展示模块如下:
当鼠标移入小图,在上方会相应地展示大图
在这里插入图片描述

实现效果

当鼠标移入小图,在上方会相应地展示大图;且当鼠标移出,图片停留在移入时显示的图片,不会改变。
本文实现效果如下(鼠标移入即改变,不用点击):
在这里插入图片描述

实现思路

定义图片列表,为列表添加鼠标移入事件onmouseover(注意:此处不能使用onmouseenter,因为此方法不支持冒泡机制),当鼠标移入列表,判断移入的是具体哪张图,把这张图渲染到大图上。
此例子利用了事件委托,即批量添加事件监听。

如果给每一张小图都添加一个鼠标移入事件,会造成代码的重复冗余,因为每一张图片的鼠标移入事件都是一样的,还会造成内存浪费。因此,我们给这些图片的父元素添加一个鼠标移入事件,通过e.target获取具体触发事件的元素

批量添加事件监听(事件委托原理)

当需要给每个子元素添加事件监听时,可以委托给父元素添加事件监听,然后通过e.target( )获取具体被点击的子元素。

原理:事件传播(冒泡)机制

什么是事件传播

当嵌套元素的最内元素被点击,实际上嵌套元素的最外层也被点击了

事件的传播是:先从外到内(捕获阶段),然后再从内到外(冒泡阶段)
举例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #big{
      
      width: 300px;height: 300px;background-color: cornflowerblue;}
        #small{
      
      width: 200px;height: 200px;background-color: coral;}
    </style>
</head>
<body>
    <div id="big">
        <div id="small">这是小方块</div>
        这是大方块
    </div>
</body>
<script>
    var small = document.getElementById("small");
    var big = document.getElementById("big");
    // 子元素点击事件
    small.onclick = function(){
      
      
        console.log("您点击了小方块");
    }
    // 父元素点击事件
    big.onclick=function(){
      
      
        console.log("您点击了大方块");
    }
</script>
</html>

我们分别定义了大小方块自己的点击事件,然后点击了小方块,却同时触发了大方块的点击事件,这就是事件传播,也叫冒泡(由内到外触发)。
在这里插入图片描述

e.target 事件源元素

e.target:最早触发事件的元素,具体触发的事件的元素

    <ul>
        <li>列表项一</li>
        <li>列表项二</li>
    </ul>
    
    <script>
        var ul = document.querySelector('ul');
        //给父元素添加点击事件
        ul.onclick = function(e){
      
      
            // 输出被点击的源元素,即如果点击的是li,则会输出li
            console.log(e.target); 
        }
    </script>

e.currentTarget 事件委托元素

e.currentTarget:添加了事件的父元素

    <ul>
        <li>列表项一</li>
        <li>列表项二</li>
    </ul>
    
    <script>
        var ul = document.querySelector('ul');
        //给ul添加点击事件,则e.currentTarget == ul
        ul.onclick = function(e){
      
      
            // 若点击的源元素不是ul
            if(e.target !== e.currentTarget){
      
      
                console.log(e.target); // 输出被点击的li列表项
            }    
        }
    </script>

使用事件委的注意事项
1、不能委托不冒泡的事件给父元素
因为事件委托利用了冒泡机制,不冒泡的事件不能用事件委托。
如:onmouseenter不冒泡,onmouseover冒泡。
2、只能有一层嵌套关系

 <!--下面的两层嵌套,当给ul添加点击事件,若点击的是span,则e.target只能获取span,无法对li做处理-->
     <ul>
         <li><span>1</span></li>
         <li><span>2</span></li>
     </ul>

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>淘宝商品展示图</title>
    <style type="text/css">
        * {
      
      
            padding: 0;
            margin: 0;
        }
        body {
      
      
            text-align: center;
        }
        body > img:nth-child(1) {
      
      
            border-radius: 15px;
            padding: 5px;
            border: 5px solid orange;
        }
        #bigImg{
      
      
            width: 500px;
        }
        .smallImg{
      
      
            width: 100px;
        }
        ul {
      
      
            list-style: none;
            display: inline-block;
        }
        ul li {
      
      
            float: left;
            width: 100px;
            height: 100px;
            margin: 5px;
            border: 1px solid rgb(121, 120, 120);
            border-radius: 5px;
        }
        ul li.active {
      
      
            border: 2px solid orange;
            border-radius: 5px;
        }
    </style>
</head>

<body>
    <!-- 大图,默认展示第一张 -->
    <img src="徽章/1.webp" id="bigImg" />
		<br />
		<br />
        <!-- 小图列表 -->
		<ul>
			<li class="active">
				<a href="">
					<img src="徽章/1.webp" width="50" class="smallImg" />
				</a>
			</li>
			<li >
				<a href="">
					<img src="徽章/2.webp" width="50" class="smallImg" />
				</a>
			</li>
			<li>
				<a href="">
					<img src="徽章/3.webp" width="50" class="smallImg" />
				</a>
			</li>
			<li>
				<a href="">
					<img src="徽章/4.webp" width="50" class="smallImg" />
				</a>
			</li>
			<li>
				<a href="">
					<img src="徽章/5.webp" width="50" class="smallImg" />
				</a>
			</li>
		</ul>
</body>
<script>
    // 获取列表元素
    var ul = document.querySelector("ul");
    // 获取列表下的列表项数组
    var liArr = document.querySelectorAll("ul>li");
    // 获取大图的dom元素
    var bigImg = document.getElementById("bigImg");

    // 给列表,即父级元素添加鼠标移入事件,onmouseover支持冒泡
    ul.onmouseover = function(e){
      
      
        // 如果鼠标移入的元素不是父元素,而是具体的子元素
        if(e.target != e.currentTarget){
      
      
            // 遍历所有li
            for(var i = 0 ; i < liArr.length; i++){
      
      
                // 如果e.target 等于 li或li的子节点,设li的class为active,并且更改图片地址
                if(e.target == liArr[i] || e.target == liArr[i].children[0] || e.target == liArr[i].children[0].children[0]){
      
      
                    liArr[i].className = "active";
                    // 更改对应的图片地址
                    bigImg.src = liArr[i].children[0].children[0].getAttribute("src");
                }else{
      
      
                    // 不是移入的节点,去掉active效果
                    liArr[i].className = "";
                }
            }
        }
    }

</script>
</html>

猜你喜欢

转载自blog.csdn.net/qq_40261601/article/details/129162354