SVG环形评分描边颜色异常:所有元素颜色一致问题求助
SVG评分环形图颜色统一问题排查与修复
问题描述
开发电影搜索展示功能时,通过SVG实现评分环形图,期望根据电影vote_average计算出的百分比为每个SVG路径设置对应描边颜色,但所有SVG元素都被设置为同一个颜色,无法实现按评分差异化显示。
问题根源
- DOM更新时机错误:在
renderHtmlData的forEach循环中,每次迭代都执行movies.innerHTML = html,导致DOM被多次覆盖,且每次获取的circleStrokeRate仅为当前已渲染的环形图元素,而非最终全部元素。 - 颜色设置逻辑错误:每次循环调用
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
相关产品推荐
相关产品推荐

