You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SVG环形评分描边颜色异常:所有元素颜色一致问题求助

SVG评分环形图颜色统一问题排查与修复

问题描述

开发电影搜索展示功能时,通过SVG实现评分环形图,期望根据电影vote_average计算出的百分比为每个SVG路径设置对应描边颜色,但所有SVG元素都被设置为同一个颜色,无法实现按评分差异化显示。

问题根源

  1. DOM更新时机错误:在renderHtmlData的forEach循环中,每次迭代都执行movies.innerHTML = html,导致DOM被多次覆盖,且每次获取的circleStrokeRate仅为当前已渲染的环形图元素,而非最终全部元素。
  2. 颜色设置逻辑错误:每次循环调用setStrokeColor时,传入当前电影的评分百分比,而该函数会遍历所有已存在的环形图元素,统一添加当前电影对应的颜色类。最终所有环形图都会被最后一个电影的评分颜色覆盖。

修复方案

最直接高效的方式是在生成HTML字符串时,直接根据当前电影的评分给SVG路径添加对应的颜色类,避免事后遍历DOM修改样式。同时将DOM更新操作移到循环结束后,减少不必要的DOM重绘。

修改后的代码示例

调整renderHtmlData函数

const inputSearch = document.getElementById("input-search")
const searchForm = document.getElementById("search-form")
const movies = document.getElementById("movies")
let dataArray = []
let tooltipModal

// 渲染电影数据到DOM
function renderHtmlData() {
    let html = ""

    dataArray.forEach(movie => {
        let urlImg = "https://www.themoviedb.org/t/p/w440_and_h660_face/"

        if(movie.poster_path === null) {
            urlImg = "img/no_image.jpeg"
        } else {
            urlImg = `https://www.themoviedb.org/t/p/w440_and_h660_face/${movie.poster_path}`
        }

        // 根据评分计算百分比并匹配对应颜色类
        const percent = movie.vote_average * 10;
        let circleClass = "circle";
        if (percent < 40) {
            circleClass += " circle-red";
        } else if (percent < 70) {
            circleClass += " circle-darkorange";
        } else {
            circleClass += " circle-lime";
        }

        html += `
            <article class="movie-container">
                <div class="poster-container">
                    <img 
                        src="${urlImg}" 
                        class="video-img"
                    >
                    <div class="tooltip-disable swing-in-right-fwd" data-modalid="${movie.id}">
                        <p class="add-watchlist">
                        <i class="fa-regular fa-eye"></i>
                            Watchlist
                        </p>
                        <p class="add-favorites">
                            <i class="fa-regular fa-star"></i>
                            Favorites
                        </p>
                    </div>
                    <button id="more-btn" data-btnid="${movie.id}">...</button>
                </div>
                <div class="movie-details">
                    <div class="col col-rating">
                        <span class="movie-rating">${movie.vote_average.toFixed(1)}</span>

                        <svg viewBox="0 0 36 36" class="circular-chart">
                            <path class="${circleClass}"
                                stroke-dasharray="${percent}, 100"
                                d="M18 2.0845
                                a 15.9155 15.9155 0 0 1 0 31.831
                                a 15.9155 15.9155 0 0 1 0 -31.831"
                            />
                        </svg>

                    </div>                          
                    <div class="col col2">
                        <h3>${movie.title}</h3>
                        <p class="movie-date">${movie.release_date}</p>
                    </div>
                </div>
            </article>
        `
    })

    // 循环结束后统一更新DOM,提升性能
    movies.innerHTML = html
    tooltipModal = document.querySelectorAll(".tooltip-disable")    
}

移除不必要的代码

删除原setStrokeColor函数,以及renderHtmlData中与该函数相关的调用和变量声明(circleStrokeRate)。

额外修正:API请求URL错误

原fetch请求中的URL存在语法错误,api_key=\"APIKEY&\应改为api_key=APIKEY&(移除多余的转义引号),否则请求会失败:

// 搜索电影
searchForm.addEventListener("submit", async function (e) {
    e.preventDefault()

    const res = await fetch(`
        https://api.themoviedb.org/3/search/movie?api_key=APIKEY&
        page=1&include_adult=true&query=${inputSearch.value}
    `)
    const data = await res.json()
    dataArray = data.results

    renderHtmlData()
})

内容的提问来源于stack exchange,提问作者Ricardo Ribeiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:30:53