简体   繁体   中英

How to make different instances of the same button respond independently to mouse events

I have 2 buttons with the same html structure on the same page. I have some js code to set the width depending on the text length of the button text. I need the js code to affect each individual button.

Please see the codepen here: https://codepen.io/gianpiero-di-lullo/pen/gOYxoVr

I've inserted them in an each() loop

$(".LIbtnWrapper").each(function(){

    var frontW = $(".LIbtnFront h1").width(),
      frontH = $(".LIbtnFront h1").height(),
      backW = $(".LIbtnBack h1").width(),
      backH = $(".LIbtnBack h1").height();

    if(frontW > backW) {
      $(".LIbtnBack h1").width(frontW);
    } else {
       $(".LIbtnFront h1").width(backW);
    }
})

I expect each button to set their own frontFace and backface width based on their text length and also behave independently on mouse events

The problem is there's no relation between your callback context and the way you're targeting the inner elements.

$(".LIbtnWrapper").each(function(){
    var frontW = $(".LIbtnFront h1").width(),

The selector doesn't know that you mean the h1 in the element being iterated over - you're using a general selector, so it will just use the width of the first one it finds in the DOM matching the selector.

Instead, tightly couple your selectors to your callback context.

$(".LIbtnWrapper").each(function(){
    var frontW = $(this).find("h1").width(), //<-- h1 inside current iterator element

You can use $(this) inside each to select the processing element and find() to select the child:

var a = $(".LIbtnWrapper");
$.each(a,function(){
    var front = $(this).find(".LIbtnFront").find("h1");
    var back = $(this).find(".LIbtnBack ").find("h1");

    var frontW = front.width(),
      frontH = front.height(),
      backW = back.width(),
      backH = back.height();

    if(frontW > backW) {
      back.width(frontW);
    } else {
       front.width(backW);
    }
})

This is about context, and the element is each .LIbtnWrapper - the context. So you have to find the child element from that for the buttons.

More about context here https://stackoverflow.com/a/16422612/125981

 $(".LIbtnWrapper").each(function(index, element) { let bf = $(element).find(".LIbtnFront").find("h1"); let bb = $(element).find(".LIbtnBack").find("h1"); let frontW = bf.width(), frontH = bf.height(), backW = bb.width(), backH = bb.height(); console.log(frontW, frontH, backW, backH); if (frontW > backW) { bb.width(frontW); } else { bf.width(backW); } }); TweenLite.set(".LIbtnWrapper", { perspective: 1000 }); TweenLite.set(".LIbtn", { transformStyle: "preserve-3d" }); TweenLite.set(".LIbtnBack", { rotationX: -90, transformOrigin: "50% top", y: "100%" }); TweenLite.set([".LIbtnBack", ".LIbtnFront"], { backfaceVisibility: "hidden" }); $(".LIbtnWrapper").hover( function() { TweenLite.to($(this).find(".LIbtn"), .3, { rotationX: 90, ease: Power4.easeOut }); }, function() { TweenLite.to($(this).find(".LIbtn"), .5, { rotationX: 0, ease: Power4.easeOut }); } ); $(".LIbtnWrapper") .mouseup(function() { TweenLite.to($(this), .1, { transformOrigin: "center", scale: "1" }); $(".LIbtnFace h1").css({ color: "#fff" }); }) .mousedown(function() { TweenLite.to($(this), .04, { transformOrigin: "center", scale: ".96" }); $(".LIbtnFace h1").css({ color: "#00B1A7" }); }); 
 body { background-color: black; margin: 20px; font-family: Arial, sans-serif; padding: 20px 0px } .container { width: 80%; display: flex } .LIbtnWrapper { position: relative; float: left; margin: auto; cursor: pointer; -webkit-font-smoothing: antialiased; } .LIbtnFace { position: absolute; overflow: hidden; } .LIbtnFront, .LIbtnBack { background-color: rgba(0 0 0 0); } .LIbtn-large { font-size: 30px; } .LIbtn-medium { font-size: 20px; } .LIbtn-small { font-size: 10px; } .LIbtnFace h1 { margin: auto; padding: 15px; border: solid 6px #fff; color: white; white-space: nowrap; text-align: center; } .LIbtnFace.LIbtnBack h1 { border-color: #00B1A7; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script> <div class="container"> <div class="LIbtnWrapper"> <div class="LIbtn"> <div class="LIbtnFace LIbtnFront"> <h1 class="LIbtn-large">FRONT</h1> </div> <div class="LIbtnFace LIbtnBack"> <h1 class="LIbtn-large">THIS IS THE BACK</h1> </div> </div> </div> <div class="LIbtnWrapper"> <div class="LIbtn"> <div class="LIbtnFace LIbtnFront"> <h1 class="LIbtn-large">ANOTHER FRONT</h1> </div> <div class="LIbtnFace LIbtnBack"> <h1 class="LIbtn-large">BACK</h1> </div> </div> </div> </div> 

jQuery's .each takes two arguments: index and element

$('.LIbtnWrapper').each(function(index, element){
    // log the current element in this iteration
    console.log('the current element: ', element);

    // get child element with context of this/element
    var thisH1 = $('.LIbtnFront h1', element);
    console.log('the child h1 of the current element', thisH1);
});

This is the "jQuery" way of accessing the current element and its children as shown in the api examples.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM