jQuery 및 CSS를 사용하여 숫자를 별표 평점 표시로 전환


101

나는 jquery 플러그인을 살펴보고 그 플러그인을 어떻게 수정하여 숫자 (예 : 4.8618164)를 5 개로 채워진 별 4.8618164 개로 바꾸는 지 궁금합니다. / JS / CSS.

이것은 이미 사용 가능한 번호의 별 등급 만 표시 / 표시하며 새 등급 제출을 허용하지 않습니다.


답변:


255

다음은 매우 작고 간단한 이미지 하나와 자동으로 생성 된 스팬 요소 하나만 사용하는 솔루션입니다.

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();
});

산출

푸가 아이콘 세트 이미지 (www.pinvoke.com)
(출처 : ulmanen.fi )

데모

http://www.ulmanen.fi/stuff/stars.php

이것은 아마도 당신의 필요에 맞을 것입니다. 이 방법을 사용하면 3/4 또는 별의 너비를 계산할 필요가 없습니다. 단지 플로트를 주면 별이 제공됩니다.


별이 어떻게 표시되는지에 대한 작은 설명이 순서대로있을 수 있습니다.

스크립트는 두 개의 블록 수준 범위 요소를 만듭니다. 두 범위 모두 초기에 80px * 16px의 크기와 배경 이미지 stars.png를 얻습니다. 범위는 중첩되어 있으므로 범위의 구조는 다음과 같습니다.

<span class="stars">
    <span></span>
</span>

외부 범위는 취득 background-position의를 0 -16px. 그러면 외부 범위의 회색 별이 보입니다. 외부 범위의 높이가 16px 및 repeat-x이므로 회색 별 5 개만 표시됩니다.

반면에, 내측 스팬은 보유 background-position0 0어느 만 노란색 별을 볼 수있다.

물론 이것은 star_yellow.png 및 star_gray.png라는 두 개의 개별 이미지 파일에서 작동합니다. 그러나 별의 높이가 고정되어 있으므로 쉽게 하나의 이미지로 결합 할 수 있습니다. 이것은 CSS 스프라이트 기술을 사용 합니다.

이제 범위가 중첩되면 자동으로 서로 겹쳐집니다. 기본적으로 두 범위의 너비가 80px이면 노란색 별이 회색 별을 완전히가립니다.

그러나 내부 범위의 너비를 조정하면 노란색 별의 너비가 감소하여 회색 별이 나타납니다.

접근성 측면에서 보면 부동 소수점 수를 내부 범위 안에두고으로 숨기면 text-indent: -9999pxCSS가 꺼진 사람들이 최소한 별 대신 부동 소수점 수를 볼 수 있도록하는 것이 더 현명했을 것입니다.

그게 말이 되길 바랍니다.


업데이트 됨 2010/10/22

이제 훨씬 더 간결하고 이해하기 어렵습니다! 하나의 라이너로 압착 할 수도 있습니다.

$.fn.stars = function() {
    return $(this).each(function() {
        $(this).html($('<span />').width(Math.max(0, (Math.min(5, parseFloat($(this).html())))) * 16));
    });
}

@Tatu, 이것이 어떻게 작동 하는지 조금 더 구체화 할 가능성 이 있습니다. jQuery에 대한 내 지식은 완전히 이해하기에는 약간 짧습니다. CSS가 x 방향 및 16 * 5 = 80 비트로 반복되는 방식과 노란색 별 이미지의 너비를 조정하는 방법을 이해하고 있지만 두 이미지를 서로 겹쳐서 하나의 별 위에 다른 별이있는 단일 이미지? -16px는 회색 별을 노란색과 같은 수준으로 끌어 올립니까?
paxdiablo

업데이트 해 주셔서 감사합니다, @Tatu, 이제 나에게 훨씬 더 의미가 있습니다. 불행히도 나는 이미 당신에게 +1을 주었으므로 다시는 할 수 없지만 설명이 더 많은 (잘 얻은) 담당자를 얻을 수 있기를 바랍니다. 건배.
paxdiablo

2
@paxdiablo 및 기타, 지원에 감사드립니다. 이 기술은 대부분의 사람들에게 놀라움으로 다가오는 것처럼 보이기 때문에 적절한 jQuery 플러그인으로 만들어야합니다. :)
Tatu Ulmanen

@Tatu, 대단히 감사합니다. 기존의 별 다섯 개짜리 플러그인은 모두 등급을 입력 할 수있는 형식을 원하는 것 같지만 숫자 표시를 변경하는 데는 과도합니다.
vfilby 2010

7
또는 더 작은 : jsbin.com/IBIDalEn/2/edit(PS 는 JS에서 불필요한 항목을 제거하고 CSS 선택기를 축소하고 사용 max-width).
Roko C. Buljan

30

최신 브라우저 만 지원해야하는 경우 다음을 수행 할 수 있습니다.

  • 이미지가 없습니다 .
  • 대부분 정적 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>

이 솔루션의 가장 큰 단점은 다음과 같습니다.

  1. 올바른 너비를 생성하려면 요소 내부에 별이 필요합니다.
  2. 의미 론적 마크 업이 없습니다. 예를 들어 요소 내부의 텍스트 로 점수 를 선호합니다 .
  3. 클래스를 가질 수있는만큼의 점수 만 허용합니다 ( 의사 요소에 대한 정확한 설정을 위해 Javascript를 사용할 없기 때문입니다 width).

이 문제를 해결하기 위해 위의 솔루션을 쉽게 조정할 수 있습니다. :before:after비트 (우리가 약간의 JS 필요하므로)에 DOM 실제 요소가 될 필요가있다.

후자는 독자를위한 연습 문제로 남겨집니다.


3
저는이 솔루션을 확장하여 100의 10 분의 1에 맞지 않는 부동 및 동적으로 생성 된 점수를 수용합니다. Codepen . 저를 얻기를위한 감사가 시작 : D
cameck을

이 꽤 달콤한 스크립트입니다
닉 사업부

1
완벽한 솔루션. 당신은 내 하루를 만들었습니다. @Jeroen 감사합니다 ... 계속 흔들어주세요.
Prabhu Nandan Kumar

22

이 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>

스크린 샷


닫는 </ SCRIPT> 태그 : 없음을 그냥 메모
롭 Stocki

7

별의 5 개의 개별 이미지 (빈, 1/4 전체, 절반 전체, 3/4 전체 및 전체)를 가지지 않고 4를 곱한 등급의 잘 리거나 라우팅 된 값에 따라 DOM에 이미지를 삽입하면됩니다 분기에 대한 전체 숫자를 얻으려면)?

예를 들어, 4.8618164에 4를 곱하고 반올림하면 19는 4/4/3/4 별이됩니다.

또는 (나처럼 게으르다면) 21 개 (별 0 개부터 별 5 개까지 1/4 씩 증가) 중에서 하나의 이미지를 선택하고 앞서 언급 한 값에 따라 단일 이미지를 선택합니다. 그런 다음 하나의 계산에 이어 DOM에서 이미지 변경이 수행됩니다 (5 개의 다른 이미지를 변경하려고 시도하는 대신).


5

클라이언트 측 렌더링 지연을 피하기 위해 완전히 JS를 사용하지 않았습니다. 이를 위해 다음과 같은 HTML을 생성합니다.

<span class="stars" title="{value as decimal}">
    <span style="width={value/5*100}%;"/>
</span>

접근성을 돕기 위해 제목 속성에 원시 등급 값을 추가하기도합니다.


4

프로토 타입없이 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

데모

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;
 }

0

여기에 .5 정확도로 제한되는 JSX 및 글꼴 굉장한 사용 방법이 있습니다.

       <span>
          {Array(Math.floor(rating)).fill(<i className="fa fa-star"></i>)}
          {(rating) - Math.floor(rating)==0 ? ('') : (<i className="fa fa-star-half"></i>)}
       </span>

첫 번째 행은 별표 전체를, 두 번째 행은 별표 절반 (있는 경우)입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.