jQuery - 设置和重置转换延迟

jQuery - Set and reset a transition delay

这在第一次迭代时效果很好,但后续迭代和单击 close 功能不会重置延迟计数。

超时计时器显然需要在每次点击时清除或重置,但我无法让它始终如一地工作。我一直在尝试使用 clearTimeout() 函数。

$("#btn").on('click', function() {
  $("#msg").prop("class", "alert active");
  removeActive();
});

function removeActive() {
  $("#msg").on("transitionend", function() {
    setTimeout(function() {
      $("#msg").removeClass("active");
    }, 3000)
  });
}

$("#close").on("click", function() {
  $("#msg").removeClass("active");
});
.alert {
  position: fixed;
  right: 20px;
  bottom: -100px;
  display: flex;
  padding: 10px;
  width: auto;
  max-width: calc(100% - 40px);
  background: #3dc0f1;
  color: #fff;
  transition: all ease-in-out 0.3s;
  z-index: 10;
}

.alert.active {
  bottom: 20px;
}

#msg-tx {
  padding: 10px 20px 10px 10px;
}

#close {
  display: flex;
  align-items: center;
  padding: 10px;
  border-radius: 5px;
  transition: all ease-in-out 0.3s;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn" type="submit">Go</button>

<div id="msg" class="alert">
  <p id="msg-tx">Hello There</p>
  <div id="close">X</div>
</div>

多次单击“开始”按钮导致超时变得不一致。

问题是在 transitionend 上添加了超时 - 删除它并且一切正常(可能调整超时以补偿)。

为什么会出现这种情况:考虑:

  1. 单击以添加 class 警报开始转换
  2. transition end 移除 active 以开始向下移动它
  3. 转换结束(下移)发生并再次进入超时
  4. 点击添加class活跃
  5. 之前的超时开始并在完成向下移动(第 3 步)后 3 秒取消活动,然后第 4 步的 3 秒结束

$("#btn").off().on('click', function() {
  $("#msg").prop("class", "alert active");
  removeActive();
});

function removeActive() {
  //$("#msg").off().on("transitionend", function() {
    setTimeout(function() {
      $("#msg").removeClass("active");
    }, 3000)
  //});
}

$("#close").off().on("click", function() {
  $("#msg").removeClass("active");
});
.alert {
  position: fixed;
  right: 20px;
  bottom: -100px;
  display: flex;
  padding: 10px;
  width: auto;
  max-width: calc(100% - 40px);
  background: #3dc0f1;
  color: #fff;
  z-index: 10;
  transition: all ease-in-out 0.3s;
}

.alert.active {
  bottom: 20px;
}

#msg-tx {
  padding: 10px 20px 10px 10px;
}

#close {
  display: flex;
  align-items: center;
  padding: 10px;
  border-radius: 5px;
  transition: all ease-in-out 0.3s;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn" type="submit">Go</button>

<div id="msg" class="alert">
  <p id="msg-tx">Hello There</p>
  <div id="close">X</div>
</div>

备选方案:

  • 删除 setTimeout 中的过渡结束处理程序
  • 使用.once代替.on(完成前点击可能会出现类似问题)

您可以创建一个变量来保持超时并在设置新超时时清除它。

示例:

var timeout;

$("#btn").on('click', function() {
  $("#msg").addClass("alert active");
  removeActive();
});

function removeActive() {
  $("#msg").on("transitionend", function() {
    clearTimeout(timeout);
    timeout = setTimeout(function() {
      $("#msg").removeClass("active");
    }, 3000);
  });
}

$("#close").on("click", function() {
  $("#msg").removeClass("active");
});
.alert {
  position: fixed;
  right: 20px;
  bottom: -100px;
  display: flex;
  padding: 10px;
  width: auto;
  max-width: calc(100% - 40px);
  background: #3dc0f1;
  color: #fff;
  transition: all ease-in-out 0.3s;
  z-index: 10;
}

.alert.active {
  bottom: 20px;
}

#msg-tx {
  padding: 10px 20px 10px 10px;
}

#close {
  display: flex;
  align-items: center;
  padding: 10px;
  border-radius: 5px;
  transition: all ease-in-out 0.3s;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn" type="submit">Go</button>

<div id="msg" class="alert">
  <p id="msg-tx">Hello There</p>
  <div id="close">X</div>
</div>

通过动画另一个 属性 来依赖 CSS 延迟(在这种情况下进行翻译)并使 jQuery 代码更容易。

$("#btn").on('click', function() {
  $("#msg").removeClass("active");
  setTimeout(function() {      
    $("#msg").addClass("active");
   }, 200)
});

$("#close").on("click", function() {
  $("#msg").removeClass("active");
});
.alert {
  position: fixed;
  right: 20px;
  bottom: -100px;
  display: flex;
  padding: 10px;
  width: auto;
  max-width: calc(100% - 40px);
  background: #3dc0f1;
  color: #fff;
  transition: all ease-in-out 0.2s;
  z-index: 10;
}

.alert.active {
  bottom: 20px;
  transform:translateY(calc(100% + 40px));
  transition: bottom ease-in-out 0.3s,transform 0.3s 3s;
}

#msg-tx {
  padding: 10px 20px 10px 10px;
}

#close {
  display: flex;
  align-items: center;
  padding: 10px;
  border-radius: 5px;
  transition: all ease-in-out 0.3s;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn" type="submit">Go</button>

<div id="msg" class="alert">
  <p id="msg-tx">Hello There</p>
  <div id="close">X</div>
</div>