代码之家  ›  专栏  ›  技术社区  ›  HappyHands31

一个javascript函数,用于在单击时向元素及其之前的所有元素添加活动类。

  •  0
  • HappyHands31  · 技术社区  · 6 年前

    你好,如果有人愿意/能够帮助我解决这个问题:

    产品评级HTML小部件由5颗星组成。每颗星都由一个跨度元素表示。这是小部件的HTML代码:

    <span>*</span>
    <span>*</span>
    <span>*</span>
    <span>*</span>
    <span>*</span>
    </div>
    

    单击一个SPAN元素时,类活动应该添加到该SPAN元素和它之前的所有SPAN元素。此外,如果存在任何跨元素,那么应该从该元素之后的所有跨元素中删除类active。

    例如,单击第三个SPAN元素后,HTML代码应如下所示:

    <span class="active">*</span>
    <span class="active">*</span>
    <span class="active">*</span>
    <span>*</span>
    <span>*</span>
    </div>
    

    完成设置函数,注册单击事件处理程序并实现HTML小部件的逻辑。

    那么,如何添加这些事件处理程序呢?

    function setup() {
      // Write your code here.
    }
    
    // Example case. 
    document.body.innerHTML = `
    <div id='rating'>
      <span>*</span>
      <span>*</span>
      <span>*</span>
      <span>*</span>
      <span>*</span>
    </div>`;
    
    setup();
    
    document.getElementsByTagName("span")[2].click();
    console.log(document.body.innerHTML);
    

    以下是最新的jfiddle: https://jsfiddle.net/3dsyp2Lu/

    4 回复  |  直到 6 年前
        1
  •  2
  •   gavgrif    6 年前

    您可以使用范围上的数据属性来获取被单击的范围的索引,然后简单地迭代范围,如果索引小于被单击的索引,则应用活动类。

    另外,您并不需要jquery来完成这个任务,可以使用简单的JS来完成。

    $('.rating').click(function(){
      let rating = $(this).attr('data-index');
      let stars = document.querySelectorAll('.rating');
      
      stars.forEach(function(star, index){
        index <= rating
          ? star.classList.add('active')
          : star.classList.remove('active');
        })
      })
    .rating {
      font-size: 24px;
      cursor: pointer
    }
    
    .active {
      color: red;
      font-weight: bold;
     }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div>
      <span class="rating active" data-index="0">*</span>
      <span class="rating active" data-index="1">*</span>
      <span class="rating" data-index="2">*</span>
      <span class="rating" data-index="3">*</span>
      <span class="rating" data-index="4">*</span>
    </div>
        2
  •  1
  •   basic    6 年前

    如果您使用的是jquery,那么只需使用nextall和prevall来激活它们。

    例子:

    function setup() {
      
      $('span').on('click', function(e) {
          $(this).nextAll().removeClass('selected');
          $(this).addClass('selected').prevAll().addClass('selected');
      })
    
    }
    // Example case. 
    document.body.innerHTML = `
    <div id='rating'>
      <span>*</span>
      <span>*</span>
      <span>*</span>
      <span>*</span>
      <span>*</span>
    </div>`;
    
    setup();
    
    document.getElementsByTagName("span")[2].click();
    console.log(document.body.innerHTML);
    span:hover{
      cursor: pointer;
    }
    
    .selected {
      font-weight: bold;
      color: orange;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        3
  •  1
  •   Andy    6 年前

    如果您想在没有jquery的情况下编写它,这里有一种方法不需要向HTML添加数据属性。

    // Grab the rating element, and attach a click event to it
    const rating = document.querySelector('#rating');
    rating.addEventListener('click', handleClick, false);
    
    // Cache its span elements
    const spans = rating.querySelectorAll('span');
    
    function clearActive() {
    
      // Remove the active class from each span element
      spans.forEach(span => span.classList.remove('active'));
    }
    
    function addActive(el) {
    
      // If the element is a span
      if (el.tagName === 'SPAN') {
    
        // Grab the previous element sibling
        const { previousElementSibling: prev } = el;
    
        // Add an active class
        el.classList.add('active');
    
        // If there is a previous sibling call addActive again
        if (prev) addActive(prev);
      }
    }
    
    function handleClick(e) {
    
      // Clear all active classes, then add the active classes
      clearActive();
      addActive(e.target);
    }
    .active { color: red; }
    span:hover { cursor: pointer; }
    <div id="rating">
      <span>*</span>
      <span>*</span>
      <span>*</span>
      <span>*</span>
      <span>*</span>
    </div>
        4
  •  1
  •   Max    6 年前

    您不需要jquery。 你也不需要额外的课程。 您可以通过 el.previousElementSibling el.nextElementSibling 两个都将在命中最后一个元素后返回空值 在您的情况下,您可以使用一组 while 循环

    const selectedSpan = //whatever you choose to get the clicked span element
    selectedSpan.classList.add('active');
    let currentSpan = selectedSpan;
    while( currentSpan.previousElementSibling )
    {
        currentSpan = currentSpan.previousElementSibling;
        currentSpan.classList.add('active');
    }
    

    用同样的方法 .nextElementSibling