防止多次点击.click()

4

我正在尝试使用jquery制作自己的幻灯片。一切都好,但当用户多次点击箭头以获取下一张图片时,它开始出现奇怪的问题:

$( document ).ready(function() {
    $("#arrow-right").click(function(){
        nextPrevius(1);
    });
    $("#arrow-left").click(function(){
        nextPrevius(-1);
    });
});

function nextPrevius(value){
    var id = parseInt($(".activo").attr("id"));
    if(id+value<1){
        $(".activo").fadeOut("slow", function() {
            $("#5").fadeIn("slow");
        });
        $(".activo").removeClass("activo");        
        $("#5").addClass("activo");
    }
    else if(id+value>5){
        $(".activo").fadeOut("slow", function() {
            $("#1").fadeIn("slow");
        });
        $(".activo").removeClass("activo");
        $("#1").addClass("activo");
    }
    else{
        $(".activo").fadeOut("slow", function() {
            $("#"+(id+value)).fadeIn("slow");
        });
        $(".activo").removeClass("activo");
        $("#"+(id+value)).addClass("activo");
    }
}
body{
    margin: 0;
}
#slider{
    width: 100%;
    height: 250px;
    position: relative;
}
.activo{
    display: block;
}
.contenido-slider{
    background-color: #d0d2ff;
    width: 100%;
    height: 250px;

}
.contenido-slider span{
    position: absolute;
    top: 45%;
    left: 50%;
}
#arrow-left{
    position: absolute;
    top: 50%;
    left: 2%;
    cursor: pointer;
}
#arrow-right{
    position: absolute;
    top: 50%;
    right: 2%;
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="css/style.css">
    <link rel="stylesheet" href="css/font-awesome.min.css">
 
    <title>Slider</title>
  </head>
    <body>

        <section id="slider">
            <div id="1" class="activo contenido-slider">
                <span>1</span>
            </div>
            <div id="2" class="contenido-slider" style="display:none">
                <span>2</span>
            </div>
            <div id="3" class="contenido-slider" style="display:none">
                <span>3</span>
            </div>
            <div id="4" class="contenido-slider" style="display:none">
                <span>4</span>
            </div>
            <div id="5" class="contenido-slider" style="display:none">
                <span>5</span>
            </div>
            <div id="arrow-left">Prev</div>
            <div id="arrow-right">next</div>
        </section>

        <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
        <script src="js/global.js"></script>
    </body>
</html>

我知道可以使用以下方式:

$(this).removeAttr('disabled');

但是这不是一个按钮,当我使用按钮并设置禁用属性时,光标会变为禁止信号,我不想要这个。

如何防止多次点击?

我已经在互联网上读了很多信息,也在这个论坛上看了很多,但我不能防止多次点击。


你可以像这样做:https://jsfiddle.net/Ln637521/ - Hackerman
可能是您的动画出了问题。可能需要调用 stop() - epascarello
您可以通过为禁用按钮添加CSS来更改“禁止”光标为任何其他光标。 - Abhijith
6个回答

2

请尝试使用我修改后的Javascript代码:

$( document ).ready(function()
{
    $("#arrow-right").click(function() {
        nextPrevius(1);
    });

    $("#arrow-left").click(function() {
        nextPrevius(-1);
    });
});

function nextPrevius(value)
{
    // Just for safe, check if there is an active slider.

    if ($(".activo").length <= 0) return;

    // Get the ID of the current active slider.

    var id = parseInt($(".activo").attr("id"));

    // Get the number of total sliders.

    var totalSliders = $(".contenido-slider").length;

    // Get the ID of the next element we need to fade-in.

    var nextId = id + value;

    if (nextId < 1)
        nextId = totalSliders;
    else if (nextId > totalSliders)
        nextId = 1;

    // Hide the current active slider and fade-in the needed one.

    $(".contenido-slider.activo").removeClass("activo").fadeOut("slow", function()
    {
        $("#" + nextId).fadeIn("slow").addClass("activo");
    });
}
body{
    margin: 0;
}
#slider{
    width: 100%;
    height: 250px;
    position: relative;
}
.activo{
    display: block;
}
.contenido-slider{
    background-color: #d0d2ff;
    width: 100%;
    height: 250px;

}
.contenido-slider span{
    position: absolute;
    top: 45%;
    left: 50%;
}
#arrow-left{
    position: absolute;
    top: 50%;
    left: 2%;
    cursor: pointer;
}
#arrow-right{
    position: absolute;
    top: 50%;
    right: 2%;
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html lang="es">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="css/style.css">
        <link rel="stylesheet" href="css/font-awesome.min.css">
 
        <title>Slider</title>
    </head>
    <body>
        <section id="slider">
            <div id="1" class="activo contenido-slider">
                <span>1</span>
            </div>
            <div id="2" class="contenido-slider" style="display:none">
                <span>2</span>
            </div>
            <div id="3" class="contenido-slider" style="display:none">
                <span>3</span>
            </div>
            <div id="4" class="contenido-slider" style="display:none">
                <span>4</span>
            </div>
            <div id="5" class="contenido-slider" style="display:none">
                <span>5</span>
            </div>
            <div id="arrow-left">Prev</div>
            <div id="arrow-right">next</div>
        </section>

        <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
        <script src="js/global.js"></script>
    </body>
</html>


我想知道为什么你的程序能够完美地运行,因为我也想要这样的结果。 - KaSkuLL
谢谢,我只是对 nextPrevious() 方法进行了微小的更改,以检查是否有活动元素。 - Shidersz
我做了另一个小的改进,所以在淡入/淡出进行时没有任何带有活动类的元素。 - Shidersz
1
@D.Smania,你可以将其适应为行内使用,检查我的答案,然后可以根据导航按钮的 id 确定方向。 - darklightcode
@darklightcode 我稍后会给它一个评论。我也喜欢不依赖硬编码元素数量的想法,可以像这样获取 $(".contenido-slider").length。谢谢! - Shidersz

1
我已经为您制作了一个导航功能,并进行了以下改进:
  • 严格的导航仅限于“向左”和“向右”
  • 防止在导航按钮上发送垃圾信息
  • 您可以使用.contenido-slider添加无限幻灯片
  • 您可以调整幻灯片淡入淡出速度

HTML中,我从.contenido-slider中删除了display:none

CSS中,我更改了此部分:

.contenido-slider {
  background-color: #d0d2ff;
  width: 100%;
  height: 250px;
  display: none;
}

.contenido-slider.activo {
  display: block;
}

$(document).ready(function() {
  $("#arrow-right").click(navigation('right'));
  $("#arrow-left").click(navigation('left'));
});

function navigation(direction) {

  return function(e) {

    /**
     * Accept only "left" or "right"
     */

    if (typeof direction === 'undefined' || ['left', 'right'].indexOf(direction) === -1) {
      direction = 'left'; // previous
    }

    var slider = $("#slider");
    var preventSpamClass = 'animation-in-progress';

    if (!slider.hasClass(preventSpamClass)) {

      slider.addClass(preventSpamClass)

      var activeClass = 'activo';
      var elements = slider.children('.contenido-slider');
      var current = slider.children('.' + activeClass);
      var currentIndex = +current.index();
      var duration = 250;

      if (direction === 'left') {

        if (currentIndex - 1 < 0) {

          var nextElement = elements.last();

        } else {

          var nextElement = current.prev();

        }

      } else {

        if (currentIndex + 1 >= elements.length) {

          var nextElement = elements.first();

        } else {

          var nextElement = current.next();

        }

      }

      current.css({opacity: 1}).stop(true).animate({
        opacity: 0
      }, {
        duration: duration,
        complete: function() {
          current.removeClass(activeClass);

          nextElement.addClass(activeClass);

          nextElement.css({opacity: 0}).stop(true).animate({
            opacity: 1
          }, {
            duration: duration,
            complete: function() {
              slider.removeClass(preventSpamClass)
            }
          })

        }
      })

    }


  }

}
body {
  margin: 0;
}

#slider {
  width: 100%;
  height: 250px;
  position: relative;
}

.activo {
  display: block;
}

.contenido-slider {
  background-color: #d0d2ff;
  width: 100%;
  height: 250px;
  display: none;
}

.contenido-slider.activo {
  display: block;
}

.contenido-slider span {
  position: absolute;
  top: 45%;
  left: 50%;
}

#arrow-left {
  position: absolute;
  top: 50%;
  left: 2%;
  cursor: pointer;
}

#arrow-right {
  position: absolute;
  top: 50%;
  right: 2%;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html lang="es">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="css/style.css">
  <link rel="stylesheet" href="css/font-awesome.min.css">

  <title>Slider</title>
</head>

<body>

  <section id="slider">
    <div id="1" class="activo contenido-slider">
      <span>1</span>
    </div>
    <div id="2" class="contenido-slider">
      <span>2</span>
    </div>
    <div id="3" class="contenido-slider">
      <span>3</span>
    </div>
    <div id="4" class="contenido-slider">
      <span>4</span>
    </div>
    <div id="5" class="contenido-slider">
      <span>5</span>
    </div>
    <div id="arrow-left">Prev</div>
    <div id="arrow-right">next</div>
  </section>

  <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
  <script src="js/global.js"></script>
</body>

</html>


0
添加一个变量并检查动画是否仍在运行:
var isAnimating = 0;

$("#arrow-right").click(function(){
    if (!isAnimating) {
      isAnimating = 1;
      nextPrevius(1);
    }
});

然后在每个 fadeIn 事件中添加回调函数:

$("#5").fadeIn("slow", function(){
   isAnimating = 0;
});

或者您可以向箭头添加自定义类,以识别单击的按钮/箭头,并在淡入事件中从箭头中删除该类。 - Abhijith

0

替换

 $( document ).ready(function() {
    $("#arrow-right").click(function(){
        nextPrevius(1);
    });
    $("#arrow-left").click(function(){
        nextPrevius(-1);
    });
});

使用以下内容

$( document ).ready(function() {
        $(document).one('click', '#arrow-right',function().   {
        nextPrevius(1);
    });
    $(document).one('click', '#arrow-left', function(){
        nextPrevius(-1);
    });
});

0
解决方案是对此代码进行一些逻辑处理,让我一步一步地带你了解, 首先,您需要了解这里发生了什么: 一旦您单击,就会触发nextPrevius函数,其中包含fadeIn函数,因此,只有在动画完成后,nextPrevius才会结束,因此,如果您多次单击,则会依次触发多个动画,有一个超级简单的解决方案,使用布尔值,让我向您展示需要做什么:
var LagProtector=false;
function nextPrevius(value){
    if(LagProtector==false){
        LagProtector=true;
        var id = parseInt($(".activo").attr("id"));
        if(id+value<1){
            $(".activo").fadeOut("slow", function() {
                $("#5").fadeIn("slow");
            });
            $(".activo").removeClass("activo");        
            $("#5").addClass("activo");
        }
        else if(id+value>5){
            $(".activo").fadeOut("slow", function() {
                $("#1").fadeIn("slow");
            });
            $(".activo").removeClass("activo");
            $("#1").addClass("activo");
        }
        else{
            $(".activo").fadeOut("slow", function() {
                $("#"+(id+value)).fadeIn("slow");
            });
            $(".activo").removeClass("activo");
            $("#"+(id+value)).addClass("activo");
        }
        LagProtector=false;
    }
}

基本上我所做的是创建了一个名为LagProtector的布尔值,然后将所有负责滑块动画的代码放在if语句中进行检查,以确保LagProtector是否已被触发。如果没有被触发,则将其设置为true,并在函数结束时将其设置为false,以便忽略在动画仍在运行时完成的点击操作。简单易行。

刚刚使用你的示例修改了我的代码,但是我仍然遇到了同样的问题。 - KaSkuLL
那是因为该函数的内部代码编写得不正确。 - orr burgel

0
您可以使用动画来隐藏/显示被点击的div,例如:

$(document).ready(function() {
  $("#arrow-right").click(function() {
    nextPrevius(1);
  });
  $("#arrow-left").click(function() {
    nextPrevius(-1);
  });
});

function nextPrevius(value) {
  var buttons = $('#arrow-left,#arrow-right');

  buttons.hide();
  setTimeout(function() {
    buttons.show();
  }, 1000);

  var id = parseInt($(".activo").attr("id"));
  if (id + value < 1) {
    $(".activo").fadeOut("slow", function() {
      $("#5").fadeIn("slow");
    });
    $(".activo").removeClass("activo");
    $("#5").addClass("activo");
  } else if (id + value > 5) {
    $(".activo").fadeOut("slow", function() {
      $("#1").fadeIn("slow");
    });
    $(".activo").removeClass("activo");
    $("#1").addClass("activo");
  } else {
    $(".activo").fadeOut("slow", function() {
      $("#" + (id + value)).fadeIn("slow");
    });
    $(".activo").removeClass("activo");
    $("#" + (id + value)).addClass("activo");
  }
}
body {
  margin: 0;
}

#slider {
  width: 100%;
  height: 250px;
  position: relative;
}

.activo {
  display: block;
}

.contenido-slider {
  background-color: #d0d2ff;
  width: 100%;
  height: 250px;
}

.contenido-slider span {
  position: absolute;
  top: 45%;
  left: 50%;
}

#arrow-left {
  position: absolute;
  top: 50%;
  left: 2%;
  cursor: pointer;
}

#arrow-right {
  position: absolute;
  top: 50%;
  right: 2%;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html lang="es">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="css/style.css">
  <link rel="stylesheet" href="css/font-awesome.min.css">

  <title>Slider</title>
</head>

<body>

  <section id="slider">
    <div id="1" class="activo contenido-slider">
      <span>1</span>
    </div>
    <div id="2" class="contenido-slider" style="display:none">
      <span>2</span>
    </div>
    <div id="3" class="contenido-slider" style="display:none">
      <span>3</span>
    </div>
    <div id="4" class="contenido-slider" style="display:none">
      <span>4</span>
    </div>
    <div id="5" class="contenido-slider" style="display:none">
      <span>5</span>
    </div>
    <div id="arrow-left">Prev</div>
    <div id="arrow-right">next</div>
  </section>

  <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
  <script src="js/global.js"></script>
</body>

</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接