【问题标题】:JavaScript application: trying to make the "wheel" event listener discontinuous failsJavaScript 应用程序:尝试使“wheel”事件侦听器不连续失败
【发布时间】:2018-06-30 13:35:36
【问题描述】:

我正在使用 Bootstrap 4 和 JavaScript 开发一个小型“图片浏览器”应用程序。

如下所示,有一个“上一个”和一个“下一个”按钮可以帮助浏览图片。

我有 bean 试图找到一种可靠的方法来使 鼠标滚动 功能与这些按钮相同。 向下滚动 相当于单击“下一步”按钮。 向上滚动相当于点击“Prev”按钮。

var picArr = $('#pictures_list li');
// The index of the last element of the array is "maxIndex"
var maxIndex = picArr.length - 1;
// Initialize counter
var counter = 0;
var updateCounter = function(btn) {
  var direction = $(btn).data("direction")
  if (direction === "left") {
    if (counter > 0) {
      counter--;
    } else {
      counter = maxIndex;
    }
  } else {
    if (counter < maxIndex) {
      counter++;
    } else {
      counter = 0;
    }
  }
}

var showCount = function(container_id) {
  var pageCount = counter + 1;
  document.getElementById(container_id).innerHTML = "Picture " + pageCount + " of " + picArr.length;
}

var showSlide = function() {
  var mTop = (200 * counter) * (-1) + 'px';
  $('#pictures_list').animate({
    'marginTop': mTop
  }, 400);
}

showCount('show_count');

$('#controls button').on('click', function() {
  updateCounter(this);
  showSlide();
  showCount('show_count');
});

document.getElementById("picture_frame").addEventListener("wheel", function() {
  updateCounter(this);
  showSlide();
  showCount('show_count')
});
#picture_frame {
  width: 200px;
  height: 200px;
  margin: 5px auto;
  border: 1px solid #ccc;
  border-radius: 2px;
  overflow: hidden;
}

.controls>div {
  display: inline-block;
}

#picture_frame {
  height: 200px;
  overflow: hidden;
}

#pictures_list {
  flex-flow: row wrap;
  align-items: stretch;
  width: 200px;
}

#pictures_list li {
  display: flex;
  height: 200px;
  flex: 1 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div id="picture_frame">
    <ul id="pictures_list" class="list-unstyled d-flex">
      <li><img src="https://picsum.photos/200/200
" alt="First picture"></li>
      <li><img src="https://picsum.photos/200/200?gravity=east
" alt="Second picture"></li>
      <li><img src="https://picsum.photos/200/200?gravity=west
" alt="Third picture"></li>
      <li><img src="https://picsum.photos/200/200?gravity=north
" alt="Fourth picture"></li>
    </ul>
  </div>
  <div class="text-center mb-2">
    <span class="badge badge-primary" id="show_count"></span>
  </div>
  <div class="controls text-center">
    <div class="btn-group" id="controls">
      <button type="button" class="btn btn-primary btn-sm" data-direction="left">Prev</button>
      <button type="button" class="btn btn-primary btn-sm" data-direction="right">Next</button>
    </div>
  </div>
</div>

在鼠标滚轮上触发showSlide() 函数确实有效,但过渡太……连续。我希望它与按钮触发的转换相同。

我错过了什么?

【问题讨论】:

  • “太连续”是什么意思?
  • 这意味着我想让鼠标滚轮像按钮一样工作

标签: javascript jquery twitter-bootstrap mousewheel


【解决方案1】:

这里有几种解决方案:

--为了防止滚动条滚动多张图片,可以使用这个函数:

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

https://davidwalsh.name/javascript-debounce-function

-- 您应该更改函数updateCounter 的参数,以便它采用滚动图像的方向。 (例如:布尔值:true = 下一个,false = 上一个)

--恢复滚动方向,参考这个答案:https://stackoverflow.com/a/45719399/4864628

var picArr = $('#pictures_list li');
// The index of the last element of the array is "maxIndex"
var maxIndex = picArr.length - 1;
// Initialize counter
var counter = 0;
var updateCounter = function(direction) {
  if (direction) {
    if (counter > 0) {
      counter--;
    } else {
      counter = maxIndex;
    }
  } else {
    if (counter < maxIndex) {
      counter++;
    } else {
      counter = 0;
    }
  }
}

var showCount = function(container_id) {
  var pageCount = counter + 1;
  document.getElementById(container_id).innerHTML = "Picture " + pageCount + " of " + picArr.length;
}

var showSlide = function() {
  var mTop = (200 * counter) * (-1) + 'px';
  $('#pictures_list').animate({
    'marginTop': mTop
  }, 400);
}

// Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If `immediate` is passed, trigger the function on the
    // leading edge, instead of the trailing.
    function debounce(func, wait, immediate) {
    	var timeout;
    	return function() {
    		var context = this, args = arguments;
    		var later = function() {
    			timeout = null;
    			if (!immediate) func.apply(context, args);
    		};
    		var callNow = immediate && !timeout;
    		clearTimeout(timeout);
    		timeout = setTimeout(later, wait);
    		if (callNow) func.apply(context, args);
    	};
    };
    
showCount('show_count');

$('#controls button').on('click', function() {
  updateCounter($(this).attr('data-direction') == 'left');
  showSlide();
  showCount('show_count');
});

var pictureFrame = document.getElementById("picture_frame");
var onScroll = debounce(function(direction) {
  updateCounter(direction);
  showSlide();
  showCount('show_count')
}, 100, true);

pictureFrame.addEventListener("wheel", function(e) {
  e.preventDefault();
  var delta;
  if (event.wheelDelta){
      delta = event.wheelDelta;
  }else{
      delta = -1 * event.deltaY;
  }
  
  onScroll(delta >= 0);
});
#picture_frame {
  width: 200px;
  height: 200px;
  margin: 5px auto;
  border: 1px solid #ccc;
  border-radius: 2px;
  overflow: hidden;
}

.controls>div {
  display: inline-block;
}

#picture_frame {
  height: 200px;
  overflow: hidden;
}

#pictures_list {
  flex-flow: row wrap;
  align-items: stretch;
  width: 200px;
}

#pictures_list li {
  display: flex;
  height: 200px;
  flex: 1 100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div id="picture_frame">
    <ul id="pictures_list" class="list-unstyled d-flex">
      <li><img src="https://picsum.photos/200/200
" alt="First picture"></li>
      <li><img src="https://picsum.photos/200/200?gravity=east
" alt="Second picture"></li>
      <li><img src="https://picsum.photos/200/200?gravity=west
" alt="Third picture"></li>
      <li><img src="https://picsum.photos/200/200?gravity=north
" alt="Fourth picture"></li>
    </ul>
  </div>
  <div class="text-center mb-2">
    <span class="badge badge-primary" id="show_count"></span>
  </div>
  <div class="controls text-center">
    <div class="btn-group" id="controls">
      <button type="button" class="btn btn-primary btn-sm" data-direction="left">Prev</button>
      <button type="button" class="btn btn-primary btn-sm" data-direction="right">Next</button>
    </div>
  </div>
</div>

【讨论】:

  • 你能加个小提琴吗?
  • this question 获得 100 声望 BOUNTY。感兴趣的? :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 2017-12-16
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
相关资源
最近更新 更多