【问题标题】:event does not refire after firing once? [duplicate]触发一次后事件不会重新触发? [复制]
【发布时间】:2021-01-04 08:15:43
【问题描述】:

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

但是,在第一次触发之后,正如我上面评论的那样,当click0.3s 之后触发时,我会在前面添加一个.shape-top.interactive 元素,以使这些事件能够重新触发,但是@ 没有任何反应987654327@(.hover没有加),结果mouseleaveclick也别开火了。

这里哪里出错了?

参见下面的 sn-p:

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>

【问题讨论】:

  • 可能您在点击时删除了所有.shape-top-interactive,所以他们正在失去听众?
  • 事件委托中的问题,请参阅下面的答案:)

标签: javascript jquery event-handling event-delegation


【解决方案1】:

您在此处为您的 shapeeck 添加一个新的 html:

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

但是这个元素没有绑定任何点击监听器,这就是为什么它们不会被触发,你要么需要调用你的事件监听器,要么将它外包给一个函数。

【讨论】:

    【解决方案2】:

    试试这样:

    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>

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

    【讨论】:

      【解决方案3】:

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

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

      参见下面的工作 sn-p

      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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-04
        相关资源
        最近更新 更多