[javascript] jQuery 및 CSS를 사용하여 숫자를 별표 평점 표시로 전환
나는 jquery 플러그인을 살펴보고 그 플러그인을 어떻게 수정하여 숫자 (예 : 4.8618164)를 5 개로 채워진 별 4.8618164 개로 바꾸는 지 궁금합니다. / JS / CSS.
이것은 이미 사용 가능한 번호의 별 등급 만 표시 / 표시하며 새 등급 제출을 허용하지 않습니다.
답변
다음은 매우 작고 간단한 이미지 하나와 자동으로 생성 된 스팬 요소 하나만 사용하는 솔루션입니다.
CSS
span.stars, span.stars span {
display: block;
background: url(stars.png) 0 -16px repeat-x;
width: 80px;
height: 16px;
}
span.stars span {
background-position: 0 0;
}
영상
(출처 : ulmanen.fi )
참고 : 위 이미지에 핫 링크 하지 마십시오 ! 파일을 자신의 서버에 복사하고 거기에서 사용하십시오.
jQuery
$.fn.stars = function() {
return $(this).each(function() {
// Get the value
var val = parseFloat($(this).html());
// Make sure that the value is in 0 - 5 range, multiply to get width
var size = Math.max(0, (Math.min(5, val))) * 16;
// Create stars holder
var $span = $('<span />').width(size);
// Replace the numerical value with stars
$(this).html($span);
});
}
별을 반 또는 1/4 별 크기로만 제한하려면 행 앞에 다음 행 중 하나를 추가하십시오 var size
.
val = Math.round(val * 4) / 4; /* To round to nearest quarter */
val = Math.round(val * 2) / 2; /* To round to nearest half */
HTML
<span class="stars">4.8618164</span>
<span class="stars">2.6545344</span>
<span class="stars">0.5355</span>
<span class="stars">8</span>
용법
$(function() {
$('span.stars').stars();
});
산출
(출처 : ulmanen.fi )
데모
이것은 아마도 당신의 필요에 맞을 것입니다. 이 방법을 사용하면 3/4 또는 별의 너비를 계산할 필요가 없습니다. 단지 플로트를 주면 별이 제공됩니다.
별이 어떻게 표시되는지에 대한 작은 설명이 순서대로있을 수 있습니다.
스크립트는 두 개의 블록 수준 범위 요소를 만듭니다. 두 범위 모두 초기에 80px * 16px의 크기와 배경 이미지 stars.png를 얻습니다. 범위는 중첩되어 있으므로 범위의 구조는 다음과 같습니다.
<span class="stars">
<span></span>
</span>
외부 범위는 취득 background-position
의를 0 -16px
. 그러면 외부 범위의 회색 별이 보입니다. 외부 범위의 높이가 16px 및 repeat-x
이므로 회색 별 5 개만 표시됩니다.
반면에, 내측 스팬은 보유 background-position
중 0 0
어느 만 노란색 별을 볼 수있다.
물론 이것은 star_yellow.png 및 star_gray.png라는 두 개의 개별 이미지 파일에서 작동합니다. 그러나 별의 높이가 고정되어 있으므로 쉽게 하나의 이미지로 결합 할 수 있습니다. 이것은 CSS 스프라이트 기술을 사용 합니다.
이제 범위가 중첩되면 자동으로 서로 겹쳐집니다. 기본적으로 두 범위의 너비가 80px이면 노란색 별이 회색 별을 완전히가립니다.
그러나 내부 범위의 너비를 조정하면 노란색 별의 너비가 감소하여 회색 별이 나타납니다.
접근성 측면에서 보면 부동 소수점 수를 내부 범위 안에두고으로 숨기면 text-indent: -9999px
CSS가 꺼진 사람들이 최소한 별 대신 부동 소수점 수를 볼 수 있도록하는 것이 더 현명했을 것입니다.
그게 말이 되길 바랍니다.
업데이트 됨 2010/10/22
이제 훨씬 더 간결하고 이해하기 어렵습니다! 하나의 라이너로 압착 할 수도 있습니다.
$.fn.stars = function() {
return $(this).each(function() {
$(this).html($('<span />').width(Math.max(0, (Math.min(5, parseFloat($(this).html())))) * 16));
});
}
답변
최신 브라우저 만 지원해야하는 경우 다음을 수행 할 수 있습니다.
- 이미지가 없습니다 .
- 대부분 정적 CSS;
- jQuery 또는 Javascript가 거의 없습니다.
숫자를 class
예를 들어 class='stars-score-50'
.
먼저 “렌더링 된”마크 업 데모 :
body { font-size: 18px; }
.stars-container {
position: relative;
display: inline-block;
color: transparent;
}
.stars-container:before {
position: absolute;
top: 0;
left: 0;
content: '★★★★★';
color: lightgray;
}
.stars-container:after {
position: absolute;
top: 0;
left: 0;
content: '★★★★★';
color: gold;
overflow: hidden;
}
.stars-0:after { width: 0%; }
.stars-10:after { width: 10%; }
.stars-20:after { width: 20%; }
.stars-30:after { width: 30%; }
.stars-40:after { width: 40%; }
.stars-50:after { width: 50%; }
.stars-60:after { width: 60%; }
.stars-70:after { width: 70%; }
.stars-80:after { width: 80%; }
.stars-90:after { width: 90%; }
.stars-100:after { width: 100; }
Within block level elements:
<div><span class="stars-container stars-0">★★★★★</span></div>
<div><span class="stars-container stars-10">★★★★★</span></div>
<div><span class="stars-container stars-20">★★★★★</span></div>
<div><span class="stars-container stars-30">★★★★★</span></div>
<div><span class="stars-container stars-40">★★★★★</span></div>
<div><span class="stars-container stars-50">★★★★★</span></div>
<div><span class="stars-container stars-60">★★★★★</span></div>
<div><span class="stars-container stars-70">★★★★★</span></div>
<div><span class="stars-container stars-80">★★★★★</span></div>
<div><span class="stars-container stars-90">★★★★★</span></div>
<div><span class="stars-container stars-100">★★★★★</span></div>
<p>Or use it in a sentence: <span class="stars-container stars-70">★★★★★</span> (cool, huh?).</p>
그런 다음 약간의 코드를 사용하는 데모 :
$(function() {
function addScore(score, $domElement) {
$("<span class='stars-container'>")
.addClass("stars-" + score.toString())
.text("★★★★★")
.appendTo($domElement);
}
addScore(70, $("#fixture"));
});
body { font-size: 18px; }
.stars-container {
position: relative;
display: inline-block;
color: transparent;
}
.stars-container:before {
position: absolute;
top: 0;
left: 0;
content: '★★★★★';
color: lightgray;
}
.stars-container:after {
position: absolute;
top: 0;
left: 0;
content: '★★★★★';
color: gold;
overflow: hidden;
}
.stars-0:after { width: 0%; }
.stars-10:after { width: 10%; }
.stars-20:after { width: 20%; }
.stars-30:after { width: 30%; }
.stars-40:after { width: 40%; }
.stars-50:after { width: 50%; }
.stars-60:after { width: 60%; }
.stars-70:after { width: 70%; }
.stars-80:after { width: 80%; }
.stars-90:after { width: 90%; }
.stars-100:after { width: 100; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Generated: <div id="fixture"></div>
이 솔루션의 가장 큰 단점은 다음과 같습니다.
- 올바른 너비를 생성하려면 요소 내부에 별이 필요합니다.
- 의미 론적 마크 업이 없습니다. 예를 들어 요소 내부의 텍스트 로 점수 를 선호합니다 .
- 클래스를 가질 수있는만큼의 점수 만 허용합니다 ( 의사 요소에 대한 정확한 설정을 위해 Javascript를 사용할 수 없기 때문입니다
width
).
이 문제를 해결하기 위해 위의 솔루션을 쉽게 조정할 수 있습니다. :before
및 :after
비트 (우리가 약간의 JS 필요하므로)에 DOM 실제 요소가 될 필요가있다.
후자는 독자를위한 연습 문제로 남겨집니다.
답변
이 jquery 도우미 함수 / 파일을 사용해보십시오
jquery.Rating.js
//ES5
$.fn.stars = function() {
return $(this).each(function() {
var rating = $(this).data("rating");
var fullStar = new Array(Math.floor(rating + 1)).join('<i class="fas fa-star"></i>');
var halfStar = ((rating%1) !== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
var noStar = new Array(Math.floor($(this).data("numStars") + 1 - rating)).join('<i class="far fa-star"></i>');
$(this).html(fullStar + halfStar + noStar);
});
}
//ES6
$.fn.stars = function() {
return $(this).each(function() {
const rating = $(this).data("rating");
const numStars = $(this).data("numStars");
const fullStar = '<i class="fas fa-star"></i>'.repeat(Math.floor(rating));
const halfStar = (rating%1!== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
const noStar = '<i class="far fa-star"></i>'.repeat(Math.floor(numStars-rating));
$(this).html(`${fullStar}${halfStar}${noStar}`);
});
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Star Rating</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="js/jquery.Rating.js"></script>
<script>
$(function(){
$('.stars').stars();
});
</script>
</head>
<body>
<span class="stars" data-rating="3.5" data-num-stars="5" ></span>
</body>
</html>
답변
별의 5 개의 개별 이미지 (빈, 1/4 전체, 절반 전체, 3/4 전체 및 전체)를 가지지 않고 4를 곱한 등급의 잘 리거나 라우팅 된 값에 따라 DOM에 이미지를 삽입하면됩니다 분기에 대한 전체 숫자를 얻으려면)?
예를 들어, 4.8618164에 4를 곱하고 반올림하면 19는 4/4/3/4 별이됩니다.
또는 (나처럼 게으르다면) 21 개 (별 0 개부터 별 5 개까지 1/4 씩 증가) 중에서 하나의 이미지를 선택하고 앞서 언급 한 값에 따라 단일 이미지를 선택합니다. 그런 다음 하나의 계산에 이어 DOM에서 이미지 변경이 수행됩니다 (5 개의 다른 이미지를 변경하려고 시도하는 대신).
답변
클라이언트 측 렌더링 지연을 피하기 위해 완전히 JS를 사용하지 않았습니다. 이를 위해 다음과 같은 HTML을 생성합니다.
<span class="stars" title="{value as decimal}">
<span style="width={value/5*100}%;"/>
</span>
접근성을 돕기 위해 제목 속성에 원시 등급 값을 추가하기도합니다.
답변
프로토 타입없이 jquery를 사용하여 js 코드를
$( ".stars" ).each(function() {
// Get the value
var val = $(this).data("rating");
// Make sure that the value is in 0 - 5 range, multiply to get width
var size = Math.max(0, (Math.min(5, val))) * 16;
// Create stars holder
var $span = $('<span />').width(size);
// Replace the numerical value with stars
$(this).html($span);
});
또한 범위의 데이터 등급 이름으로 데이터 속성을 추가했습니다.
<span class="stars" data-rating="4" ></span>
답변
2 개의 이미지로만 할 수 있습니다. 빈 별 1 개, 채워진 별 1 개.
채워진 이미지를 다른 이미지 위에 오버레이합니다. 등급 번호를 백분율로 변환하여 필터 이미지의 너비로 사용합니다.
.containerdiv {
border: 0;
float: left;
position: relative;
width: 300px;
}
.cornerimage {
border: 0;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
}
img{
max-width: 300px;
}