基本上,只要鼠标按下该按钮,我就会尝试多次再次执行按钮。
我需要这个带滑块的按钮。现在,我点击一个按钮,例如"增加滑块"并且滑块增加了1步,但是如果我长按该按钮,我现在希望能够增加滑块很多步。
我该怎么做?
答案 0 :(得分:2)
do
循环在1000毫秒内运行的次数最多,mouseleave
和mouseup
处理程序永远不会有机会运行,因为their events are sitting in the message queue等待mousedown
处理程序完成该循环的运行。
循环设置了几千个超时,至少在200毫秒后运行。鉴于您发布的代码,这些超时实际上并没有做任何事情,因为window
's click
handler is being called, not your button's。
mouseleave
和mouseup
处理程序基本上什么都不做,因为start
会在被检查之前重置为有效时间。
我们需要两个延迟:初始点击和滑块第一次增加之间的1000毫秒延迟,以及滑块之间的200毫秒延迟增加。如果用户在前1000毫秒内取消,我们将其视为单击。如果用户在重复开始后取消,我们不应将其视为点击。 (我们定义"取消"释放鼠标按钮或将光标移离按钮。这意味着在UI按钮上按下鼠标按钮并将光标移开将算作点击,但是代码会更简单。)
我们可以通过设置超时来设置延迟,超时在1000毫秒后设置一个间隔,每隔200毫秒,增加滑块。由于规范的最后一行,我们不会使用click
事件来增加滑块:
如果用户在重复开始后取消,我们不应将其视为点击。
因此我们将滑块增加代码赋予其自己的函数increaseSlider()
(无论如何这都是好的做法):
function startLongClick (e) {
window.setTimeout(() => {
increaseSlider();
window.setInterval(() => {
increaseSlider();
}, 200);
}, 1000);
}
$('#button').on('mousedown', startLongClick);
我们在超时时首次调用increaseSlider()
,因此滑块在初始点击后首先增加1000毫秒,而不是1200.我们在超时和间隔中使用箭头函数,因为arrow functions don't redefine this
,所以我们& #39; d如果需要,可以引用触发<button>
。
现在代码,单击该按钮将启动整个长按过程,无法停止它。停止进程意味着停止超时和间隔,我们可以使用window.clearTimeout()
或window.clearInterval()
(他们执行相同的功能;不要告诉任何人)。我们需要依赖ID [{1}}和setTimeout()
给我们,并在setInterval()
和mouseup
处理程序中清除它们:
mouseleave
现在按钮正在执行我们希望它执行的操作,但有一个例外:短按不会执行任何操作,因为我们没有使用let intervalId;
let timeoutId;
function startLongClick (e) {
timeoutId = window.setTimeout(() => {
increaseSlider();
intervalId = window.setInterval(() => {
increaseSlider();
}, 200);
}, 1000);
}
function cancelLongClick () {
window.clearInterval(intervalId);
window.clearTimeout(timeoutId);
}
$('#button').on('mousedown', startLongClick);
$('#button').on('mouseup', cancelLongClick);
$('#button').on('mouseleave', cancelLongClick);
处理程序和在调用click
之前清除超时。如果在increaseSlider()
事件之后但在超时触发之前触发了取消事件,则应该注册一个短按。由于在mousedown
事件之前timeoutId
未定义,并且在超时触发后我们不需要它,我们可以在超时时为其分配mousedown
并使用它来确定我们是否应该注册一下:
undefined
我们也在短信代码中将let intervalId;
let timeoutId;
function startLongClick (e) {
timeoutId = window.setTimeout(() => {
timeoutId = undefined;
increaseSlider();
intervalId = window.setInterval(() => {
increaseSlider();
}, 200);
}, 1000);
}
function cancelLongClick () {
window.clearInterval(intervalId);
if (timeoutId) {
increaseSlider();
window.clearTimeout(timeoutId);
timeoutId = undefined;
}
}
$('#button').on('mousedown', startLongClick);
$('#button').on('mouseup', cancelLongClick);
$('#button').on('mouseleave', cancelLongClick);
设置为timeoutId
。否则,在短暂点击后,每次将鼠标移出按钮时都会触发增加。
代码现在可以工作,但是需要两个全局变量,并且对特定按钮进行了硬编码。让我们把它变成一个通用的jQuery插件*:
undefined
&#13;
(($) => {
$.fn.repeatingClick = function (callback, delay = 500, interval = 200) {
return this.each(function () {
let intervalId;
let timeoutId;
function startLongClick (e) {
timeoutId = window.setTimeout(() => {
timeoutId = undefined;
callback.call($(this), e);
intervalId = window.setInterval(() => {
callback.call(this, e);
}, interval);
}, delay);
}
function cancelLongClick (e) {
window.clearInterval(intervalId);
if (timeoutId) {
callback.call(this, e);
window.clearTimeout(timeoutId);
timeoutId = undefined;
}
}
$(this).on('mousedown', startLongClick);
$(this).on('mouseup', cancelLongClick);
$(this).on('mouseleave', cancelLongClick);
});
}
})(jQuery);
function modifySlider (e) {
let modifier = Number($(this).data('change'));
$('progress').attr('value', Number($('progress').attr('value')) + modifier);
}
$('button').repeatingClick(modifySlider);
&#13;
改变了什么?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="dec" data-change="-1">−</button>
<progress value="25" max="50"></progress>
<button id="inc" data-change="1">+</button>
参数和increaseSlider()
替换了对callback
的来电。这样,任何函数都可以用作回调,由于我们在超时时使用了箭头函数,我们可以使用Function.call
和callback.call($(this), e)
来访问回调中的触发元素。 this
和delay
,以便更常用。interval
中。由于jQuery对象可以表示集合以及单个元素,因此我们将原始代码包装在对$.repeatingClick()
的调用中以单独访问每个元素。我们还以通常的方式返回jQuery对象。其余部分特定于此应用程序:两个按钮,用于修改($.each()
)&#39;滑块的值,使用自定义<progress>
属性作为实际金额,以便我们可以给两个相同的代码。
*我之前从未编写过jQuery插件;围绕核心逻辑的大多数代码直接来自jquery-longpress,这是一个几乎完成OP所需的jQuery插件。
答案 1 :(得分:1)
尝试使用间隔而不是手动计算时间。看看这个:
var value = 0
var addval;
var press = false;
$('#button').on('mousedown', function (e) {
press = true;
increaseValue();
return false;
});
$('#button').on('mouseleave', function (e) {
clearInterval(addval);
return false;
});
$('#button').on('mouseenter', function(e) {
if (press)
increaseValue();
});
$('#button').on('mouseup', function (e) {
press = false;
clearInterval(addval);
return false;
});
function increaseValue() {
addval = setInterval(function(){
value++;
$("#counter").text(value);
}, 100);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Press me</button>
<div id="counter">0</div>
您可以通过更改间隔时间来调整速度。