Programing

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

lottogame 2020. 8. 19. 22:29
반응형

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


나는 jquery 플러그인을 살펴보고 그 플러그인을 어떻게 수정하여 숫자 (예 : 4.8618164)를 5 개로 채워진 4.8618164 개의별로 바꾸는 지 궁금합니다. 기본적으로 jQuery를 사용하여 5 개 미만의 숫자를 별표 5 개로 채워진별로 해석 / 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();
});

산출

푸가 아이콘 세트 이미지 (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 개만 표시됩니다.

반면에 내부 범위 에는 노란색 별만 보이게하는 a background-position0 0있습니다.

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

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

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

접근성 측면에서 보면, 내부 범위 안에 float 숫자를 남겨두고으로 숨기는 것이 현명했을 것입니다 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>

The biggest downsides of this solution are:

  1. You need the stars inside the element to generate correct width;
  2. There's no semantic markup, e.g. you'd prefer the score as text inside the element;
  3. It only allows for as many scores as you'll have classes (because we can't use Javascript to set a precise width on a pseudo-element).

To fix this the solution above can be easily tweaked. The :before and :after bits need to become actual elements in the DOM (so we need some JS for that).

The latter is left as an excercise for the reader.


Try this jquery helper function/file

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>

스크린 샷


Why not just have five separate images of a star (empty, quarter-full, half-full, three-quarter-full and full) then just inject the images into your DOM depending on the truncated or rouded value of rating multiplied by 4 (to get a whole numner for the quarters)?

For example, 4.8618164 multiplied by 4 and rounded is 19 which would be four and three quarter stars.

Alternatively (if you're lazy like me), just have one image selected from 21 (0 stars through 5 stars in one-quarter increments) and select the single image based on the aforementioned value. Then it's just one calculation followed by an image change in the DOM (rather than trying to change five different images).


I ended up going totally JS-free to avoid client-side render lag. To accomplish that, I generate HTML like this:

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

여기에 .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>

첫 번째 행은 별표 전체를, 두 번째 행은 별표 반쪽 (있는 경우)

참고 URL : https://stackoverflow.com/questions/1987524/turn-a-number-into-star-rating-display-using-jquery-and-css

반응형