2011-03-02 78 views
65

目前我的范围输入中的onChange事件在每个步骤都触发。针对HTML5范围的onChange事件

有没有办法从射击,直到用户已经让滑块去阻止这一事件?

我使用的范围内创建一个搜索查询。我希望能够在每次更改表单时运行搜索,但是在滑块移动的每一步中发出搜索请求都太多了。


下面的代码,因为它主张:

HTML:

<div id="page"> 
    <p>Currently viewing page <span>1</span>.</p> 
    <input class="slider" type="range" min="1" max="100" step="1" value="1" name="page" /> 
</div> 

的JavaScript:

$(".slider").change(function() { 
    $("#query").text($("form").serialize()); 
}); 

这是否帮助?

+0

你是什么acutal代码? – 2011-03-02 12:04:56

+6

由于HTML规范中的模糊性,这是由WebKit和IE执行的错误。从那以后,这个规范已经被澄清,直到旋钮被释放后,'变化'事件才会开始。要在用户滑动旋钮时获取值,应该使用“输入”事件。但是,WebKit和IE还没有解决这个实现bug。 HTML规格修订版本:http://html5.org/tools/web-apps-tracker?from=7786&to=7787 – JeremiahLee 2013-09-11 21:57:49

回答

6

的一个问题是,当假设在onchange触发事件,据我所知的HTML5没有定义,所以它是最有可能不同于浏览器的浏览器。而且您还必须考虑,浏览器实际上并不需要将input type=range作为滑块呈现。

你唯一的选择是你必须建立一个机制来确保你的搜索不会被频繁触发,例如,检查一个搜索当前是否正在运行,如果它正在运行,或者确保搜索最多触发每个x秒。

后者(只是一个快速的黑客,未经测试)简单的例子。

var doSearch = false; 

function runSearch() { 
    // execute your search here 
} 

setInterval(function() { 
    if (doSearch) { 
    doSearch = false; 
    runSearch(); 
    } 
}, 2000); // 2000ms between each search. 

yourRangeInputElement.onchange = function() { doSearch = true; } 
9

Bah!

使用onmouseup事件,而随后onChange

+4

我曾经考虑过这个问题,但有两个原因决定:处理滑块值不变(轻微),我不能认为人们会用鼠标编辑表格(主要)。我对这个问题仍然没有正确的答案,但是我不觉得没有任何答案是正确的;他们是正确的(如他们的工作),但他们并没有真正回答这个问题。 – WilliamMayor 2011-07-18 09:10:54

+2

您还需要添加事件:'onkeyup'(在使用键盘的情况下)和'ontouchend'(在使用触摸屏的情况下)。 – iRon 2017-04-13 20:08:15

14

有点晚了,但我有同样的问题的一天。下面是使用jQuery绑定/触发我的解决方案:

(function(el, timeout) { 
    var timer, trig=function() { el.trigger("changed"); }; 
    el.bind("change", function() { 
     if(timer) { 
      clearTimeout(timer); 
     } 
     timer = setTimeout(trig, timeout); 
    }); 
})($(".slider"), 500); 

现在只要你的函数绑定到“改变”事件来代替。

+2

这是一个很好的解决方法,但是每次只有一个选择符“.slider”实际发生更改时,触发所有响应选择元素的“更改”的缺点。 我修改为例: '(函数($ EL,超时){ \t \t VAR定时器; \t \t $ el.bind( “变”,函数(){ \t \t \t \t变量$我= $(本); \t \t如果(定时器){ \t \t clearTimeout(定时器); \t \t} \t \t timer = setTimeout(function(){ \t \t \t \t \t $ me.trigger(“changed”); \t \t \t \t},timeout); \t \t}); \t \t})($(。slider),500);' – Fluxine 2014-01-09 10:35:44

+0

究竟如何实现这个代码? – 2014-04-26 14:32:13

0

另一个建议:

$(".slider").change(function(){  
    if (this.sliderTimeour) clearTimeout(this.sliderTimeour); 
    this.sliderTimeour = setTimeout(function(){ 
    //your code here 
    },delayTimeHere); 
}); 
+0

这段代码似乎与jQuery 1.9.1冲突,因为它一直抛出一个错误。然而,我发现下面的Arwyn的答案可行。 – 2014-01-27 15:14:52

0

你可以尝试使用blur事件。当然,它也有它的局限性,但它只是一个建议:)

您也可以尝试将bluronkeyuponmouseup活动结合起来,试图抓住不同的情况:blur当用户与keybord箭头并点击选择<Tab>onkeyup当用户的选择与键盘,并保持专注于滑块,并onmouseup当他使用鼠标。甚至可能只能合并onkeyuponmouseup

不过你必须做一个简单的检查,如果该值已更改或不并运行后,才发生更改neccessary代码。

1

这是我用来捕获了 '更改事件' 的HTML5范围滑块:

HTML:

<form oninput="output1.value=slider1.value"> 
    <input type="range" name="slider1" value="50"/> 
    <output name="output1" for="slider1">50</output> 
</form> 

的JavaScript:

var $slider = $('input[name="slider1"]'); 

$slider.bind('change', function(e) { 
    e.preventDefault(); 
    console.log($(this).val()); 
}); 

你也可以如果您希望在单击后返回它的值,请将'click'事件绑定到范围滑块编辑(甚至拖)。把它想象成一个'mouseup'事件。 (我没有尝试,但我不得不点击滑块后,滑块并没有停止。)

的JavaScript:

$slider.bind('click', function(e) { 
    e.preventDefault(); 
    console.log($this).val()); 
} 

在一个侧面说明,这会返回一个字符串,因此请务必使用'parseInt($(this).value())'。

希望这会有所帮助。

61

使用最终选择的值:

$(".slider").on("change", function(){console.log(this.value)}); 

用它来获得增量值滑动:

$(".slider").on("input", function(){console.log(this.value)}); 
+2

这适用于Firefox和Chrome,但不适用于Safari。 Safari在滑动时触发更改事件。至少在他们开始根据修订标准实施修复之前。 – baohouse 2014-08-14 18:57:06

+1

似乎在Safari 8.0.3中工作正常。 – Jurgen 2015-02-18 10:40:40

+0

很酷,谢谢 - 不知道“输入”事件。但是我正在寻找! (y)的 – 2015-02-27 11:56:45

0

平变化工作得很好,但我需要同时滑动它来更新值。

var interval; 
$("#rangeinput").mousedown(function(event){ 
    interval = setInterval(function(){ 
     $("#output").html($("#rangeinput").val()); 
     console.log("running"); 
    },150); 
}); 

$("#rangeinput").mouseup(function(event){ 
    clearInterval(interval); 
}); 

http://jsbin.com/vibuc/1/

1

我在同一页面中使用多个HTML5默认滑块具有以下设置:

  • 当滑块使用oninput事件
  • 移动在页面输出标签值改变
  • A change事件在发布时触发一次

使用最新版本的Chrome进行测试,并使用Node和Socket.io在树莓上编译。

<output id="APIDConKpVal"></output>&nbsp; <input type="range" 
      class="PIDControlSlider" 
      min="0" 
      max="1500" 
      step="1" 
      id="APIDConKp" 
      oninput="APIDConKpVal.value=value"/> 

<output id="APIDConKiVal"></output>&nbsp; <input type="range" 
      class="PIDControlSlider" 
      min="0" 
      max="2000" 
      step="1" 
      id="APIDConKi" 
      oninput="APIDConKiVal.value=value"/> 

简单的Javascript代码创建侦听器。您可能需要尝试不同的事件,而不是最后一行中的“更改”,以查看适合您的内容。

window.onload=function() 
{ 
var classname = document.getElementsByClassName("PIDControlSlider"); 

    var myFunction = function() { 
     var attribute = this.getAttribute("id"); 
//Your code goes here 
     socket.emit('SCMD', this.getAttribute("id")+' '+ this.value); 
    }; 

    for(var i=0;i<classname.length;i++){ 
     classname[i].addEventListener('change', myFunction, false); 
    } 
} 
5

纯JS这里:

myInput.oninput = function(){ 
    console.log(this.value); 
} 

myInput.onchange = function(){ 
    console.log(this.value); 
} 
2

gravediggin但如果你需要检查它的js 油门防抖动功能

用法:

//resize events gets processed 500ms after the last Event 
addEventListener("resize", _debounce(function(){ foo;}, 500)); 

//resize events get processed every 500ms 
addEventListener("resize", _throttle(function(){ foo;}, 500)); 

代码:

/*waits 'delay' time after the last event to fire */ 
_debounce = function(fn, delay) { 
    var timer = null; 
    return function() { 
     var context = this, 
      args = arguments; 
     clearTimeout(timer); 
     timer = setTimeout(function() { 
      fn.apply(context, args); 
     }, delay); 
    }; 
}; 


/* triggers every 'treshhold' ms, */ 
_throttle = function(fn, threshhold, scope) { 
    threshhold = threshhold || 250; 
    var last, 
     deferTimer; 
    return function() { 
     var context = scope || this; 

     var now = +new Date(), 
      args = arguments; 
     if (last && now < last + threshhold) { 
      // hold on to it 
      clearTimeout(deferTimer); 
      deferTimer = setTimeout(function() { 
       last = now; 
       fn.apply(context, args); 
      }, threshhold); 
     } else { 
      last = now; 
      fn.apply(context, args); 
     } 
    }; 
};