用原生JavaScript封装一个rater组件

131 阅读1分钟

安装环境

npm install -g http-server

启动http服务

http-server .

index.html

<!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>Rating App</title>
    <style>
        .star-rater .star {
            font-size: 5rem;
            color: gray;
        }
    </style>
</head>
<body>
    <h2>Rating App</h2>
    <!-- div.star-rate#star-1 -->
    <div class="star-rater" id="rater-1" data-rating="1" role="rater">
        <span class="star" data-value="1">&#9733;</span>
        <span class="star" data-value="2">&#9733;</span>
        <span class="star" data-value="3">&#9733;</span>
        <span class="star" data-value="4">&#9733;</span>
        <span class="star" data-value="5">&#9733;</span>
    </div>
    <div class="star-rater" id="rater-1" data-rating="3" role="rater">
        <span class="star" data-value="1">&#9733;</span>
        <span class="star" data-value="2">&#9733;</span>
        <span class="star" data-value="3">&#9733;</span>
        <span class="star" data-value="4">&#9733;</span>
        <span class="star" data-value="5">&#9733;</span>
    </div>
    <script type="module" src="js/main.js"></script>
</body>
</html>
  • type=module,这样,浏览器就能解析代码中的module语法。

main.js

import { Rater } from "./rater.js";
document.addEventListener('DOMContentLoaded',function(){
    // const raters=document.querySelectorAll(['role=rater']);
    const raters=document.querySelectorAll('.star-rater');
    raters.forEach(rater=>{
        new Rater(rater);
    });
});
  • 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。

rater.js

export function Rater(ratingElement) {

    const resetRating=ev=>{
        const numRating=ratingElement.getAttribute('data-rating');
        highlightRating(numRating);
    }//根据传入的data-rating值 初始化点亮星星的个数

    const ratingHover=ev=>{
        const currentHover=ev.currentTarget.getAttribute('data-value');
        highlightRating(currentHover);
    }//hover时 点亮
    
    const stars = ratingElement.querySelectorAll('.star');
    const highlightRating=(numRating)=>{
        stars.forEach(star=>{
            star.style.color=
                numRating >= star.getAttribute('data-value')?'yellow':'gray';
        })
    }//点亮星星

    const setRating=ev=>{
        const currentClick=ev.currentTarget.getAttribute('data-value');
        // highlightRating(currentClick);
        ratingElement.setAttribute('data-rating',currentClick);
    }//根据点击的星星 重新set data-rating
    
    resetRating();
    stars.forEach(star=>{
        star.addEventListener('click',setRating)
        star.addEventListener('mouseover',ratingHover);
    })
    //mouseout恢复默认星星数
    ratingElement.addEventListener('mouseout',resetRating);
}

实现效果

image.png