I'm trying to implement a flip effect on multiple tiles every time a user clicks on it, its sort of the beginning of a dashboard type webpage. How do I make a click event work for multiple classes of the same name?

All of the tiles have the same class name but under different "box" divs, the jquery click event only seems to implement in the last tile added, while the other ones are kept static. I can't seem to figure whats causing this and I've been searching all over for an answer. This is the last revision of the click event code:

var i = 0,
abbrs = document.getElementsByClassName("tile"),
len = abbrs.length;

function addEvent(abbr) {
    abbr.addEventListener("click", function(event) {
        $(this).toggleClass("flip");
    })

}

for (i; i < len; i++){

    addEvent(abbrs[i]);
}

Here's the css code:


.box1 {
    padding-top:250px;
    padding-left:30px;
    position:absolute;
    perspective: 1000px;
    width: 300px;
    height:150px;
    background:none;


}

.box2 {
    padding-top:250px;
    padding-left:355px;
    position:absolute;
    perspective: 1000px;
    width: 300px;
    height:150px;
    background:none;

}

.box3 {
    padding-top:250px;
    padding-left:680px;
    position:absolute;
    perspective: 1000px;
    width: 300px;
    height:150px;
    background:none;

}

.box4 {
    padding-top:250px;
    padding-left:1005px;
    position:absolute;
    perspective: 1000px;
    width: 300px;
    height:150px;
    background:none;

}






.tile {

    position: relative;
    width: 100%;
    height:100%;
    transform-style: preserve-3d;
    transition: all 0.5s ease;
    background: yellow;
    border-radius: 10px;



}





.tile-front {

    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    background: yellow;
    color: grey;
    border-radius: 10px;


}

.bg-tile {
    padding-top:5px;
    text-align: center;
    font-family: Times;
    font-size: 20px;
}

.card-body {
    text-align: center;
    font-family: Times;
    font-size: 25px;

}

.card-footer{
    padding-top:10px;
    text-align: center;

}

.tile.flip{
    transform: rotateY(180deg);


}



.tile-back {

    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    background: blue;
    color: grey;
    border-radius: 10px;
    text-align: center;
    transform: rotateY(180deg);
}

and here's the html code:

<!DOCTYPE html>
<html>
    <head>
        <title>Dashboard</title>
        <meta charset="UTF-8">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
        <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

        <link rel="stylesheet" type="text/css" href="style.css" />


    </head>
    <body>


    <div class="box1">
        <div class="tile">

            <div class="card tile-front">

                <div class="bg-tile">

                    <i class="material-icons m_emote">account_box</i>

                </div>

                <div class="card-body">

                    <p>5 Users</p>

                </div>

                <div class="card-footer text-muted m_desc">

                    Online

                </div>

            </div>

            <div class="card tile-back">

                <div class="card-body">

                    <p>User online correspond to people connected on your network</p>

                </div>

            </div>

        </div>

    </div>

    <div class="box2">
        <div class="tile">

            <div class="card tile-front">

                <div class="bg-tile">

                    <i class="material-icons m_emote">account_box</i>

                </div>

                <div class="card-body">

                    <p>5 Users</p>

                </div>

                <div class="card-footer text-muted m_desc">

                    Online

                </div>

            </div>

            <div class="card tile-back">

                <div class="card-body">

                    <p>User online correspond to people connected on your network</p>

                </div>

            </div>

        </div>

    </div>


    <div class="box3">
        <div class="tile">

            <div class="card tile-front">

                <div class="bg-tile">

                    <i class="material-icons m_emote">account_box</i>

                </div>

                <div class="card-body">

                    <p>5 Users</p>

                </div>

                <div class="card-footer text-muted m_desc">

                    Online

                </div>

            </div>

            <div class="card tile-back">

                <div class="card-body">

                    <p>User online correspond to people connected on your network</p>

                </div>

            </div>

        </div>

    </div>



    <div class="box4">
        <div class="tile">

            <div class="card tile-front">

                <div class="bg-tile">

                    <i class="material-icons m_emote">account_box</i>

                </div>

                <div class="card-body">

                    <p>5 Users</p>

                </div>

                <div class="card-footer text-muted m_desc">

                    Online

                </div>

            </div>

            <div class="card tile-back">

                <div class="card-body">

                    <p>User online correspond to people connected on your network</p>

                </div>

            </div>

        </div>

    </div>



        <script src="dashboard.js"> </script>

    </body>
</html>

I can't seem to figure out where the root of the problem is.

3 Answers

1
M8RTAL On Best Solutions

Consider this Codepen for a pure javascript solution.

<p class="target">flip me</p>
<p class="target">flip me</p>
<p class="target">flip me</p>

.flipped {
  color: red;
}

const targets = document.getElementsByClassName('target');
for (var i = 0; i < targets.length; i++) {
    targets[i].addEventListener('click', function(){
        this.classList.toggle("flipped");
    })
}

Or consider this for a jQuery solution.

<p class="target">flip me</p>
<p class="target">flip me</p>
<p class="target">flip me</p>

.flipped {
  color: red;
}

$('.target').on('click', function() {
  $(this).toggleClass('flipped');
});

EDIT:

After looking at your given code I just realized that you position absolute divs via very large paddings which is not the correct way to do. Rather use top|right|bottom|left for positioning (see here for docs). After changing the css your example works fully even with the messy javascript. Look here

1
Parth Raval On

Note: here is the basic snippet that you need to do. by clicking all class listed call function to call show the effects. if you don't want to show effects then don't add class.

function callMe(){
    if ($(this).hasClass('flip')){
        $(this).removeClass('flip');//removes flip class
    } else {
         $(this).addClass('flip');//add flip class
    }
}

$(".class1, .class2").click(callMe); //add classes here needs to give effects and call functions
.flip{
  color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="class1">Class 1</div>
<span class="class2">Class 2</span>

0
Community On

I think that replacing the snippet you provided with this code should do it for you:

    $(document).ready(function() {
        $(".tile").click(function() {         
            $(".tile").toggleClass("flip");
        });
    });

Depending on where the code actually lives in your project, you might not need the $(document).ready() event listener that wraps the "on click" event listener.