1

I have done attaching 3 events mouseenter mouseleave click, and they all fire in the first attempt.

However, after this first time firing, as I commented above, I prepend a .shape-top.interactive element when click is fired after 0.3s in order to make these events be able to refire, but then nothing happen with mouseenter (the .hover is not added), then as a result mouseleave click do not fire too.

Where does it go wrong here?

see snippet below :

var shape_placed = `<div class="shape-top placed"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>`;
var shape_top = `<div class="shape-top interactive"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>`;

$(".shape-top.interactive").on({
    "mouseover": function(){
        $(this).css({"transform": "", "transition": ""}).addClass('hover');
    },
    "mouseout": function(){
        $(this).removeClass('hover').css({"transform": "translate(0px,0px)", "transition": "all 0.2s ease-in-out"});
        setTimeout(function() {$(this).css({"transform": "", "transition": ""});}, 0);
    },
    "click": function(){
        $(this).css({"transform": "translate(0,-94px)","transition": "transform 0.3s ease-in-out"});
        setTimeout(function() {
            $('.shape-deck').find('.shape-top.interactive').remove();
            $('.shape-deck').prepend(shape_top); // a .shape-top.interactive element is prepended but the event does not fire
            $('.shape-slot').html('').append(shape_placed);
        }, 300);
    }
});
.shape-deck{
    width: 63px;
    height: 63px;
    display: inline-block;
    margin: 2px 20px 2px 0px;
  }  

  .shape-top{
    background-color: #f8f8f5;
    border-radius: 5px;
    width: 63px;
    height: 63px;
    display: flex;
    align-items: center;
    justify-content: center;
    }

  .shape-top.interactive{
    z-index: 5;
    cursor: pointer;
  }
  
  .shape-top.static{
    z-index: 3;
    box-shadow: rgba(108,108,108,.56) 0 3px 2px 0;
  }

  .shape-top,.shape-middle,.shape-bottom{
    position: absolute;
    user-select: none;
  }

  .shape-slot{
    background-color: #d6d6d0;
    border-radius: 5px;
    width: 63px;
    height: 63px;
  }
  
  .hover{
    box-shadow: rgba(108,108,108,.56) 0 3px 2px 0;
    width: 67px;
    height: 67px;
    transform: translate(-4px,-5px);
    transition: all 0.2s ease-in-out;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="shape-slot-container" style="position: relative; display: block; padding-top: 20px; margin-left: 30px">
<div class="shape-slot"></div>
</div>

<div class="shape-deck-container" style="position: relative; display: block; padding-top: 20px; margin-left: 30px">
<div class="shape-deck">
<div class="shape-top interactive"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>


</div>
Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52
Godgog Arsenal
  • 107
  • 1
  • 8

3 Answers3

1

You prepend a new html to your shapedeck here:

  $('.shape-deck').prepend(shape_top); // a .shape-top.interactive element is prepended but the event does not fire
        

However this element does not have any click listener bound to it, which is why they are not fired, you either need to recall your event listener or outsource it to a function.

Tobias
  • 845
  • 10
  • 19
1

Try like this:

var shape_placed = `<div class="shape-top placed"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>`;
var shape_top = `<div class="shape-top interactive"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>`;

addMouseHandlers();

function addMouseHandlers() {
  $(".shape-top.interactive").off("mouseover").off("mouseout").off("click").on({
    "mouseover": function() {
      $(this).css({
        "transform": "",
        "transition": ""
      }).addClass('hover');
    },
    "mouseout": function() {
      $(this).removeClass('hover').css({
        "transform": "translate(0px,0px)",
        "transition": "all 0.2s ease-in-out"
      });
      setTimeout(function() {
        $(this).css({
          "transform": "",
          "transition": ""
        });
      }, 0);
    },
    "click": function() {
      $(this).css({
        "transform": "translate(0,-94px)",
        "transition": "transform 0.3s ease-in-out"
      });
      setTimeout(function() {
        $('.shape-deck').find('.shape-top.interactive').remove();
        $('.shape-deck').prepend(shape_top); // a .shape-top.interactive element is prepended but the event does not fire
        $('.shape-slot').html('').append(shape_placed);
        
        addMouseHandlers();
      }, 300);
    }
  });
};
.shape-deck {
  width: 63px;
  height: 63px;
  display: inline-block;
  margin: 2px 20px 2px 0px;
}

.shape-top {
  background-color: #f8f8f5;
  border-radius: 5px;
  width: 63px;
  height: 63px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.shape-top.interactive {
  z-index: 5;
  cursor: pointer;
}

.shape-top.static {
  z-index: 3;
  box-shadow: rgba(108, 108, 108, .56) 0 3px 2px 0;
}

.shape-top,
.shape-middle,
.shape-bottom {
  position: absolute;
  user-select: none;
}

.shape-slot {
  background-color: #d6d6d0;
  border-radius: 5px;
  width: 63px;
  height: 63px;
}

.hover {
  box-shadow: rgba(108, 108, 108, .56) 0 3px 2px 0;
  width: 67px;
  height: 67px;
  transform: translate(-4px, -5px);
  transition: all 0.2s ease-in-out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="shape-slot-container" style="position: relative; display: block; padding-top: 20px; margin-left: 30px">
  <div class="shape-slot"></div>
</div>

<div class="shape-deck-container" style="position: relative; display: block; padding-top: 20px; margin-left: 30px">
  <div class="shape-deck">
    <div class="shape-top interactive"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>


  </div>

Move your code to a function so that you can remove and add the event handlers again after the new element has been added.

sbgib
  • 5,580
  • 3
  • 19
  • 26
1

The problem is in the event delegation , once you remove the clicked node and then perpend it again the event is not attached to it , so in your case ; multi event handler , just set parent as event listener , and delegate event to .interactive div as folow

$(".shape-deck-container").on({ //events}, ".shape-top.interactive" )

See below working snippet

var shape_placed = `<div class="shape-top placed"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>`;
var shape_top = `<div class="shape-top interactive"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>`;

let shape_events = { "mouseover": function() {
    $(this).css({
      "transform": "",
      "transition": ""
    }).addClass('hover');
  },
  "mouseout": function() {
    $(this).removeClass('hover').css({
      "transform": "translate(0px,0px)",
      "transition": "all 0.2s ease-in-out"
    });
    setTimeout(function() {
      $(this).css({
        "transform": "",
        "transition": ""
      });
    }, 0);
  },
  "click": function() {
    $(this).css({
      "transform": "translate(0,-94px)",
      "transition": "transform 0.3s ease-in-out"
    });
    setTimeout(function() {
      $('.shape-deck').find('.shape-top.interactive').remove();
      $('.shape-deck').prepend(shape_top); // a .shape-top.interactive element is prepended but the event does not fire
      $('.shape-slot').html('').append(shape_placed);
    }, 300);
  }
}

$(".shape-deck-container").on( shape_events, ".shape-top.interactive");
.shape-deck {
  width: 63px;
  height: 63px;
  display: inline-block;
  margin: 2px 20px 2px 0px;
}

.shape-top {
  background-color: #f8f8f5;
  border-radius: 5px;
  width: 63px;
  height: 63px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.shape-top.interactive {
  z-index: 5;
  cursor: pointer;
}

.shape-top.static {
  z-index: 3;
  box-shadow: rgba(108, 108, 108, .56) 0 3px 2px 0;
}

.shape-top,
.shape-middle,
.shape-bottom {
  position: absolute;
  user-select: none;
}

.shape-slot {
  background-color: #d6d6d0;
  border-radius: 5px;
  width: 63px;
  height: 63px;
}

.hover {
  box-shadow: rgba(108, 108, 108, .56) 0 3px 2px 0;
  width: 67px;
  height: 67px;
  transform: translate(-4px, -5px);
  transition: all 0.2s ease-in-out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="shape-slot-container" style="position: relative; display: block; padding-top: 20px; margin-left: 30px">
  <div class="shape-slot"></div>
</div>

<div class="shape-deck-container" style="position: relative; display: block; padding-top: 20px; margin-left: 30px">
  <div class="shape-deck">
    <div class="shape-top interactive"><svg style="width: 80%; height: 80%" viewbox="0 0 63 63" xmlns="http://www.w3.org/2000/svg"> <ellipse cx="31.5" cy="31.5" fill="#ff7f00" id="svg_1" rx="30" ry="30" stroke="null" stroke-width="1.5"></ellipse> </svg></div>


  </div>
Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52