You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化jQuery代码避免图片点击切换时淡入淡出动画重复执行

问题修复方案

动画重复触发的根本原因

  • 多元素动画回调重复执行:你选择了多个元素绑定fadeOut事件,jQuery会为每个完成淡出动画的元素单独执行一次回调函数,导致替换元素属性、包裹链接的逻辑被重复执行多次,额外绑定了重复的点击事件
  • 旧事件未清理:仅修改元素ID不会移除之前绑定的点击事件,原#shi的点击事件始终保留在DOM元素上,触发时会和新ID绑定的事件叠加执行
  • 未做动画队列拦截:动画执行过程中没有锁机制,重复点击会导致动画队列堆叠,出现多次淡入淡出

修复方案

1. 核心逻辑优化点

  • 使用fadeOut().promise().done()替代直接传回调函数,保证所有元素动画完成后仅执行一次逻辑
  • 每次绑定点击事件前先调用.off('click')清理旧事件,避免事件叠加
  • 增加动画锁变量,动画执行过程中阻止点击事件触发
  • 用状态栈存储每一步的页面配置,点击返回时直接恢复上一级状态即可实现回退功能

2. 完整代码示例

HTML部分(新增返回按钮结构)

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- 新增返回按钮 -->
<button id="backBtn" style="display:none; margin: 10px 0 0 20px;">返回上一级</button>
<h1 id="ihi" class="ihc" style="color: #000000; font-family: Segoe, 'Segoe UI', 'DejaVu Sans', 'Trebuchet MS', Verdana, sans-serif; font-style: normal; font-weight: bold; text-align: center; font-size: 1.5em;">
  Select the brand.
</h1>
<hr>
<section class="isc" id="isi">
  <div class="grc" id="gri">
    <div class="gic" id="gsh"><img src="images/2021_images/Logos/SHI-SHC.svg" id="shi" class="shc" alt="S UK support" width="300" height="50"></div>
    <!--Row 1, column 1-->
    <div class="gic" id="gbp"><img src="images/2021_images/Logos/BPI-BPC.svg" id="bpi" class="bpc" alt="B support" width="300" height="50"></div>
    <!--Row 1, column 2-->
    <div class="gic" id="gth"><img src="images/2021_images/Logos/THI-THC.svg" id="thi" class="thc" alt="T support" width="300" height="50"></div>
    <!--Row 1, column 3-->
    <div class="gic" id="gem"><img src="images/2021_images/Logos/EMI-EMC.svg" id="emi" class="emc" alt="e support" width="300" height="50"></div>
    <!--Row 2, column 1-->
    <div class="gic" id="get"><img src="images/2021_images/Logos/ETI-ETC.svg" id="eti" class="etc" alt="E support" width="300" height="50"></div>
    <!--Row 2, column 2-->
    <div class="gic" id="gjm"><img src="images/2021_images/Logos/JMI-JMC.svg" id="jmi" class="jmc" alt="J support" width="300" height="50"></div>
    <!--Row 2, column 3-->
    <div class="gic" id="gbl3"><img src="images/2021_images/Logos/BLI-BLC.svg" id="bl3" class="blc" alt="blank 3" width="300" height="50"></div>
    <!--Row 3, column 1-->
    <div class="gic" id="gbl4"><img src="images/2021_images/Logos/BLI-BLC.svg" id="bl4" class="blc" alt="blank 4" width="300" height="50"></div>
    <!--Row 3, column 2-->
    <div class="gic" id="gbl5"><img src="images/2021_images/Logos/BLI-BLC.svg" id="bl5" class="blc" alt="blank 5" width="300" height="50"></div>
    <!--Row 3, column 3-->
  </div>
</section>

JS部分

$(function() {
  // 动画锁,避免动画执行过程中重复触发
  let isAnimating = false;
  // 状态栈,存储每一步的页面配置用于返回
  let stateStack = [];

  // 存储初始状态
  saveState();
  // 初始页隐藏返回按钮
  $('#backBtn').hide();

  var idlist = $("#shi,#bpi,#thi,#emi,#eti,#jmi,#bl4,#ihi,#umi,#bl3,#bl5");

  $("#shi").off('click').on('click', function() {
    if (isAnimating) return;
    isAnimating = true;
    // 操作前保存当前状态
    saveState();

    $(idlist).fadeOut(300).promise().done(function() {
      $("#gri").css("grid-gap", "160px 120px");
      // 先解绑旧事件再修改属性
      $("#shi").off('click').attr('src', "images/2021_images/Products/TVs/STVI-STVC.jpg").attr('id', "stvi").attr("height", "150").attr("alt", "STV Icon")
      $("#bpi").attr('src', "images/2021_images/Products/Audio/SAVI-SAVC.jpg").attr('id', "savi").attr("height", "150").attr("alt", "S link").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#thi").attr('src', "images/2021_images/Products/Audio/SPKI-SPKC.jpg").attr('id', "spki").attr("height", "150").attr("alt", "S link2").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#emi").attr('src', "images/2021_images/Products/Audio/SHFI-SHFC.jpg").attr('id', "shfi").attr("height", "150").attr("alt", "SHI link").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#eti").attr('src', "images/2021_images/Products/Audio/SRAI-SRAC.jpg").attr('id', "srai").attr("height", "150").attr("alt", "SAR link").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#jmi").attr('src', "images/2021_images/Products/SDA/SAPI-SAPC.jpg").attr('id', "sapi").attr("height", "150").attr("alt", "SAP link").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#bl3").attr('src', "images/2021_images/Logos/BLI-BLC.svg").attr('id', "bl1").attr("alt", "Blank 1")
      $("#bl4").attr('src', "images/2021_images/Products/SDA/SMWI-SMWC.jpg").attr("id", "smwi").attr("height", "150").attr("alt", "SMW").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#bl5").attr('src', "images/2021_images/Logos/BLI-BLC.svg").attr('id', "bl1").attr("alt", "Blank 1")
      $("#ihi").text("Which Sharp product do you need help with?").attr('id', "ihis")
      $("#umi").attr('src', "images/2021_images/Logos/SHI-SHC.svg").attr('id', "#shih")
      
      $(idlist).fadeIn(500, function() {
        isAnimating = false;
        // 操作后显示返回按钮
        $('#backBtn').show();
      });
    })
  });

  //第二阶段点击事件
  $(document).off('click', '#stvi').on('click', '#stvi', function() {
    if (isAnimating) return;
    isAnimating = true;
    saveState();

    $("#stvi,#savi,#spki,#shfi,#srai,#sapi,#smwc,#ihis").fadeOut(300).promise().done(function() {
      $("#gri").css("grid-gap", "100px 100px")
      $("#stvi").off('click').attr('src', "images/2021_images/Logos/IMI-QSC.svg").attr("id", "imi").attr("alt", "S Support").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#savi").attr('src', "images/2021_images/Logos/IMI-QSC.svg").attr("id", "faq").attr("alt", "S FAQ").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#spki").attr('src', "images/2021_images/Logos/IMI-QSC.svg").attr("id", "faa").attr("alt", "S A.FAQ").wrap("<a href='https://www.goingsomeplace.com'>")
      $("#shfi").attr('src', "images/2021_images/Logos/BLI-BLC.svg").attr("id", "bl1").attr("alt", "Blank 1").unwrap(["#shfi"])
      $("#srai").attr('src', "images/2021_images/Logos/BLI-BLC.svg").attr("id", "bl1").attr("alt", "Blank 1").unwrap(["#srai"])
      $("#sapi").attr('src', "images/2021_images/Logos/BLI-BLC.svg").attr("id", "bl1").attr("alt", "Blank 1").unwrap(["#sapi"])
      $("#smwi").attr('src', "images/2021_images/Logos/BLI-BLC.svg").attr("id", "bl1").attr("alt", "Blank 1").unwrap(["#smwi"])
      $("#ihis").text("Support - S")
      $("#umi").attr('src', "images/2021_images/Logos/BPI-BPC.svg").attr("id", "#bpih")
      
      $(this).fadeIn(300, function() {
        isAnimating = false;
      });
    })
  })

  // 返回按钮逻辑
  $('#backBtn').on('click', function() {
    if (isAnimating || stateStack.length <=1) return;
    isAnimating = true;
    // 弹出当前状态,恢复上一级状态
    stateStack.pop();
    let prevState = stateStack[stateStack.length -1];
    restoreState(prevState);

    // 回到初始页时隐藏返回按钮
    if (stateStack.length ===1) {
      $('#backBtn').hide();
    }
  })

  // 保存当前页面状态到栈
  function saveState() {
    let state = {
      gridGap: $('#gri').css('grid-gap'),
      title: $('#ihi, #ihis').text(),
      elements: []
    };
    $('#gri img').each(function() {
      let $el = $(this);
      state.elements.push({
        parent: $el.parent().attr('id'),
        id: $el.attr('id'),
        src: $el.attr('src'),
        alt: $el.attr('alt'),
        height: $el.attr('height'),
        hasLink: $el.parent().is('a')
      })
    })
    stateStack.push(state);
  }

  // 恢复到指定状态
  function restoreState(state) {
    let $imgs = $('#gri img');
    $('#gri').css('grid-gap', state.gridGap);
    $('#ihi, #ihis').attr('id', 'ihi').text(state.title);
    
    $imgs.each(function(index) {
      let item = state.elements[index];
      let $el = $(this);
      // 处理外层链接
      if (item.hasLink && !$el.parent().is('a')) {
        $el.wrap("<a href='https://www.goingsomeplace.com'>");
      } else if (!item.hasLink && $el.parent().is('a')) {
        $el.unwrap();
      }
      // 恢复元素属性,先清旧事件
      $el.off('click').attr({
        id: item.id,
        src: item.src,
        alt: item.alt,
        height: item.height
      })
    })

    $imgs.fadeIn(300, function() {
      isAnimating = false;
    })
  }
})

CSS部分(可选新增返回按钮样式)

#backBtn {
  padding: 6px 12px;
  background: #02AB9D;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.shic {
  width: 100%;
  background-color: #424750;
  padding-top: 0.5%;
  padding-bottom: 0.1%;
}

.shtc {
  font-size: 15px;
  font-family: 'Segoe UI';
  color: #FFFFFF;
  margin-left: 20%;
}


/*BRANDS*/

.isi {
  margin-bottom: 2%;
}

#gri {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  /* 3 columns */
  grid-template-rows: repeat(3, 60px);
  /* 2 rows  */
  grid-gap: 100px 100px;
  /* 50 pixels of space added between rows and 100 pixels added between columns  */
  justify-content: center;
  margin-top: 1%;
  border-bottom: #02AB9D;
  border-bottom-width: 2px;
}

.gic {
  width: 300;
  height: 50;
  justify-content: bottom;
}

内容的提问来源于stack exchange,提问作者D Sand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 03:48:03