使用 jquery 的简单 dom 遍历

Simple dom traversal using jquery

我正在使用之前的开发人员星级评级代码。我需要修改它,因为它没有按照开发人员预期的方式运行。如果你看,里面有 label 个带有星星的元素。你可以看到第一个label有1个span,而第5个label有5个spans.

它现在如何工作的一个例子是你点击第 5 个 input 开发者在 label 中有 5 颗星,但要让它按预期工作 我实际上还需要修改其他标签跨度。所以,假设用户选择 3 星,我需要改变标签 1、2 和 3 内的 span。要选择 4 星,我需要改变标签内的 span 1、2、3 和 4。

我正在考虑一个 jquery/javascript 遍历标签(可能带有 id)的解决方案。因此,如果他们单击输入 4,javascript 解决方案将遍历标签 1、2、3 和 4 内的所有跨度并更新 css。不过我不确定该怎么做。

<div class="rating-selector">
    <label>
        <input type="radio" name="rating" value="1" />
        <span class="icon">★</span>
    </label>
    <label>
        <input type="radio" name="rating" value="2" />
        <span class="icon">★</span>
        <span class="icon">★</span>
    </label>
    <label>
        <input type="radio" name="rating" value="3" />
        <span class="icon">★</span>
        <span class="icon">★</span>
        <span class="icon">★</span>   
    </label>
    <label>
        <input type="radio" name="rating" value="4" />
        <span class="icon">★</span>
        <span class="icon">★</span>
        <span class="icon">★</span>
        <span class="icon">★</span>
    </label>
    <label>
        <input type="radio" name="rating" value="5" />
        <span class="icon">★</span>
        <span class="icon">★</span>
        <span class="icon">★</span>
        <span class="icon">★</span>
        <span class="icon">★</span>
    </label>
</div>

有一个更简单的纯CSS解决方案:

.rating-selector {
  display: inline-block;
  border: 0;
  direction: rtl;
}

input[name="rating"] {
  display: none;
}

input[name="rating"]~label {
  color: grey
}

input[name="rating"]:checked~label {
  color: gold
}
<fieldset class="rating-selector">
  <input type="radio" name="rating" value="5" id="rating-5" />
  <label for="rating-5">★</label>
  <input type="radio" name="rating" value="4" id="rating-4" />
  <label for="rating-4">★</label>
  <input type="radio" name="rating" value="3" id="rating-3" />
  <label for="rating-3">★</label>
  <input type="radio" name="rating" value="2" id="rating-2" />
  <label for="rating-2">★</label>
  <input type="radio" name="rating" value="1" id="rating-1" />
  <label for="rating-1">★</label>
</fieldset>

您可以使用 .closest("label").index() 找到父 <label> 索引。然后,使用 :lt() selector 抓取它前面的每个项目。

const highlightPrevious = (elem) => {
  let $this = $(elem);
  $(".rating-selector label span").css("color", "");                 //reset styling
  let idx = $this.index();                                           //get index of selected label
  $(`.rating-selector label:lt(${idx+1}) span`).css("color", "red"); //style all label spans up to and including the selected index
};

$('label')
  .click(function() { highlightPrevious(this); })
  .mouseover(function() { $(this).click() });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="rating-selector">
  <label>
    <input type="radio" name="rating" value="1" />
    <span class="icon">★</span>
  </label>
  <label>
    <input type="radio" name="rating" value="2" />
    <span class="icon">★</span>
    <span class="icon">★</span>
  </label>
  <label>
    <input type="radio" name="rating" value="3" />
    <span class="icon">★</span>
    <span class="icon">★</span>
    <span class="icon">★</span>   
  </label>
  <label>
    <input type="radio" name="rating" value="4" />
    <span class="icon">★</span>
    <span class="icon">★</span>
    <span class="icon">★</span>
    <span class="icon">★</span>
  </label>
  <label>
    <input type="radio" name="rating" value="5" />
    <span class="icon">★</span>
    <span class="icon">★</span>
    <span class="icon">★</span>
    <span class="icon">★</span>
    <span class="icon">★</span>
  </label>
</div>