1

I plan to display the title whenever the user clicks on the icon, and by clicking again, in addition to hiding the title, the background color will also change so that the user knows which box he has clicked on before.

For this purpose, I wrote a script code that shows and hides the title well, but the background color does not change.

In summary: I want the .background class to be added to the .box_mini class when the title is hidden.

I used to use this code to add a new class to the previous class:

$(document).ready(function () {
    $('.box_mini').click(function () {
        $(this).toggleClass('background');
    });
});

But I don't know what to do here?

My codes are as follows:

let mini = document.querySelector(".box_mini");

document.querySelectorAll('.box_icon').forEach(eye => {
    eye.addEventListener("click", function() {
    let excerpt = this.parentNode.querySelector(".title_box");
    if (this.classList.contains("bi-play-circle-fill")) {
        this.classList = "bi bi-power box_icon";
        excerpt.style.display = "block";
    } else {
        this.classList = "bi bi-play-circle-fill box_icon";
        excerpt.style.display = "none"
        
         $(mini).ready(function () {
                $(this).toggleClass('background');
            });
      }
  });
});   
 .box_main {
        display: flex;
        justify-content: space-around;
    }

    .box_mini {
        width: 250px;
        height: 200px;
        background: #5ec7ff;
        box-shadow: 0 0 4px #000;
        transition: all 0.5s ease;
    }

    .box_icon {
        font-size: 25px;
        margin: 10px 45% 6px;
        color: #7f7f7f;
    }

    .title_box {
        font-size: 45px;
        margin: 25px 0;
        color: #f9ff4d;
        text-align: center;
        display: none;
    }

    .background{
        background: #c9e955;
        transition: all 0.5s ease;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" rel="stylesheet" />
<section class="box_main">
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

</section>
Developer
  • 230
  • 8
  • 1
    `document.querySelector(".box_mini")` - that selects only the first element with that class. `$(mini).ready(function ()` - that makes no sense to begin with. Why should an arbitrary div element fire any "ready" event? – CBroe Feb 13 '23 at 11:30
  • 1
    `$(mini).ready(function () { $(this).toggleClass('background'); })` -> `$(this).closest(".box_mini").toggleClass('background');` remove the dodgy ready and use .closest to get the parent .box_mini – freedomn-m Feb 13 '23 at 11:35
  • 1
    I would stick with native JS _or_ jQuery. Mixing them up makes for confusing code. – Andy Feb 13 '23 at 11:39
  • 1
    Maybe I don't understand what exactly you want, but why are you using a `forEach()`...? – Juan Feb 13 '23 at 11:43
  • 2
    @Juan you can only assign an event handler to a single element in vanilla-javascript - so you need the foreach after `document.querySelectorAll` to loop through each element in the returned collection to assign the event handler. It's not like jquery which handles both collections and single elements (collections with one item) the same same. Here's an example: https://stackoverflow.com/a/40956816/2181514 – freedomn-m Feb 13 '23 at 11:58
  • In principle I did not see why a forEach should be used in a solution supposed to use JQuery. But with your details on Vanilla JS it's clearer. – Juan Feb 13 '23 at 12:33

2 Answers2

2

I think you are mixing up jQuery with native js too much.

Why not just stick to jQuery like this?


Edit, I would set cursor:pointer; to your .bi class, to highlight clickable context.

$('body').on('click','.bi-play-circle-fill',function(){
  $(this).next('.title_box').show();
  $(this).removeClass('bi-play-circle-fill').addClass('bi-power');
  $(this).parent().addClass('background');
});

$('body').on('click','.bi-power',function(){
  $(this).next('.title_box').hide();
  $(this).removeClass('bi-power').addClass('bi-play-circle-fill');
  $(this).parent().removeClass('background');
});
.box_main {
        display: flex;
        justify-content: space-around;
    }

    .box_mini {
        width: 250px;
        height: 200px;
        background: #5ec7ff;
        box-shadow: 0 0 4px #000;
        transition: all 0.5s ease;
    }

    .box_icon {
        font-size: 25px;
        margin: 10px 45% 6px;
        color: #7f7f7f;
    }

    .title_box {
        font-size: 45px;
        margin: 25px 0;
        color: #f9ff4d;
        text-align: center;
        display: none;
    }

    .background{
        background: #c9e955;
        transition: all 0.5s ease;
    }
    
    .bi{
      cursor: pointer;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" rel="stylesheet" />
<section class="box_main">
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>
  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

  <div class="box_mini">
    <i class="bi bi-play-circle-fill  box_icon"></i>
    <h1 class="title_box">Title BOX</h1>
  </div>

</section>
toffler
  • 1,231
  • 10
  • 27
1

I tried to keep this very similar to what you had previously. Looks like you weren't getting the parent .box_mini class to change the background colour.

let mini = document.querySelector(".box_mini");


document.querySelectorAll('.box_icon').forEach(eye => {
eye.addEventListener("click", function() {
let excerpt = this.parentNode.querySelector(".title_box");
let parent = $(this).parent();
if (this.classList.contains("bi-play-circle-fill")) {
    this.classList = "bi bi-power box_icon";
    excerpt.style.display = "block";
    parent.toggleClass('background');
} else {
    this.classList = "bi bi-play-circle-fill box_icon";
    excerpt.style.display = "none"
    parent.toggleClass('background');
  }

  });
});  
dgal1992
  • 11
  • 1
  • I reiterate my comment posted on the original question. Why use a `forEach`..? While class change interventions are only performed on the clicked element...? – Juan Feb 13 '23 at 11:54