事件触发一次后不会重新触发?

时间:2021-01-04 08:15:43

标签: javascript jquery event-handling event-delegation

我已经附加了 3 个事件 mouseenter mouseleave click,它们都在第一次尝试时触发。

但是,在第一次触发之后,正如我上面评论的那样,当 .shape-top.interactiveclick 之后触发时,我会在前面添加一个 0.3s 元素,以使这些事件能够重新触发,但是 mouseenter 没有任何反应(未添加 .hover),因此 mouseleave click 也不会触发。

这里哪里出错了?

见下面的片段:

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>

3 个答案:

答案 0 :(得分:1)

你在这里为你的 shapeeck 添加一个新的 html:

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

然而,这个元素没有绑定任何点击监听器,这就是它们没有被触发的原因,你要么需要调用你的事件监听器,要么把它外包给一个函数。

答案 1 :(得分:1)

试试这个:

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>

将您的代码移动到一个函数中,以便您可以在添加新元素后再次删除和添加事件处理程序。

答案 2 :(得分:1)

问题出在事件委托中,一旦您删除单击的节点然后再次将其挂起,事件就不会附加到它上面, 所以在你的情况下;多事件处理程序,只需将父级设置为事件侦听器,并将事件委托给 .interactive div 如下

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

见下面的工作片段

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>

相关问题