javascript 多重评级 svg 明星点击

时间:2021-02-10 15:33:12

标签: javascript css svg

我有一个评级明星动画,点击应该使父级(跨度)激活一个类。 我有多个评级,我有 1 到 5 星评级,半评级也应该有效。

目前我可以增加。 但我不能从说 4 回到 1

看看我的演示,以获得一个“完整”的工作示例

这是一个 js css 挑战:-)

JS

var ratingElemOne = $('.ratingOne input[name="starOne"]');
 
ratingElemOne.change(function (e) {
        if (this.checked) {
            $(this).parent().addClass("active");
        }
    });
 

var ratingElemTwo = $('.ratingTwo input[name="starTwo"]');

ratingElemTwo.change(function () {
    if (this.checked) {
        $(this).parent().addClass("active");
    }
});

HTML

<div class="col-8 md-col-8 pt2 relative">
  <svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <symbol id="starOne" viewBox="0 0 28 28" preserveAspectRatio="xMaxYMax meet">
      <title>Star Rating</title>
      <path class="starOne" d="M13.996,22.501 L22.649,27.997 L20.352,17.637 L27.996,10.667 L17.930,9.768 L13.996,-0.003 L10.063,9.768 L-0.003,10.667 L7.641,17.637 L5.345,27.997 L13.996,22.501 Z" />
    </symbol>
  </svg>

  <p>Value for money?</p>
  <div class="rating ratingOne">
    <fieldset class="rating-fieldset">
      <span>
        <input type="checkbox" id="starOne5" class="rating-checkbox" value="5" name="starOne" /><label class="full" for="star5" title="Awesome - 5 stars">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
        <input type="checkbox" id="star4half" class="rating-checkbox" value="4.5" name="starOne" /><label class="half" for="star4half" title="Pretty good - 4.5 stars" name="star">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
      </span>
      <span>
        <input type="checkbox" id="star4" class="rating-checkbox" value="4" name="starOne" /><label class="full" for="star4" title="Pretty good - 4 stars">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
        <input type="checkbox" id="star3half" class="rating-checkbox" value="3.5" name="starOne" /><label class="half" for="star3half" title="Meh - 3.5 stars">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
      </span>
      <span>
        <input type="checkbox" id="star3" class="rating-checkbox" value="3" name="starOne" /><label class="full" for="star3" title="Meh - 3 stars" name="star">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
        <input type="checkbox" id="star2half" class="rating-checkbox" value="2.5" name="starOne" /><label class="half" for="star2half" title="Kinda bad - 2.5 stars">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
      </span>
      <span>
        <input type="checkbox" id="star2" class="rating-checkbox" value="2" name="starOne" /><label class="full" for="star2" title="Kinda bad - 2 stars">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
        <input type="checkbox" id="star1half" class="rating-checkbox" value="1.5" name="starOne" /><label class="half" for="star1half" title="Meh - 1.5 stars">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
      </span>
      <span>
        <input type="checkbox" id="star1" class="rating-checkbox" value="1" name="starOne" /><label class="full" for="star1" title="Sucks big time - 1 star">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
        <input type="checkbox" id="starhalf" class="rating-checkbox" value="0.5" name="starOne" /><label class="half" for="starhalf" title="Sucks big time - 0.5 stars">
          <svg role="img" aria-label="rating">
            <use xlink:href="#starOne"></use>
          </svg>
        </label>
      </span>
      <small>Rate Now</small>
    </fieldset>
  </div>
</div>

https://jsfiddle.net/davidesitua/mq2xfp9L/

1 个答案:

答案 0 :(得分:0)

如果您使用自定义元素(所有现代浏览器都支持)在所有 SVG 客户端创建所有 SVG 会更容易:

  • 从星形图标复制仅 d 路径
  • https://yqnn.github.io/svg-path-editor/ 中的 d 路径编辑为 100x100 视图框/网格
  • 通过在路径前添加 M0 0h100v100h-100v-100 使其成为
  • 0 0 N 100 视图框中创建了一个新的 SVG 文件以适合所有星星..见下文
  • 添加了背景矩形设置金色颜色分级
  • 使用逆星,每个星都在 x 偏移处
  • 添加了矩形 覆盖所有半星
  • 在每个“半星”上设置内联事件 onclickonmouseover

<star-rating stars=5 rating="3.5"
             bgcolor="green" nocolor="grey" color="gold"></star-rating>
<star-rating stars=7 rating="50%"
             bgcolor="rebeccapurple" nocolor="beige" color="goldenrod"></star-rating>
<script>
  document.addEventListener("click", (evt) => console.log(evt.target.getAttribute("n")))

  customElements.define("star-rating", class extends HTMLElement {
    set rating( rate ) {
      if (!String(rate).includes("%")) rate = Number(rate) / this.stars * 100 + "%";
      this.querySelector("#rating").setAttribute("width", rate);
    }
    connectedCallback() {
      let { bgcolor, stars, nocolor, color, rating } = this.attributes;
      this.stars = ~~stars.value || 5;
      this.innerHTML = 
        `<svg viewBox="0 0 ${this.stars*100} 100" style="cursor:pointer;width:300px">`
      + `<rect width="100%" height="100" fill="${nocolor.value}"/>`
      + `<rect id="rating"  height="100" fill="${color.value}"  />`
        + Array(  this.stars     ).fill()
               .map((i, n) => `<path fill="${bgcolor.value}" d="M${ n*100 } 0h102v100h-102v-100m91 42a6 6 90 00-4-10l-22-1a1 1 90 01-1 0l-8-21a6 6 90 00-11 0l-8 21a1 1 90 01-1 1l-22 1a6 6 90 00-4 10l18 14a1 1 90 010 1l-6 22a6 6 90 008 6l19-13a1 1 90 011 0l19 13a6 6 90 006 0a6 6 90 002-6l-6-22a1 1 90 010-1z"/>`)
               .join("")
        + Array(  this.stars * 2 ).fill()
               .map((i, n) => `<rect x="${ n*50 }" n="${n}" opacity="0" width="50" height="100"`
                  + ` onclick="dispatchEvent(new Event('click'))" `
                  + ` onmouseover="this.closest('star-rating').rating = ${(n+1)/2}"/>`)
              .join("") 
      + "</svg>";

      this.rating = rating.value;
    }
  });
</script>

相关问题