HTML5 范围的 onChange 事件

发布于 2024-10-20 07:14:01 字数 545 浏览 7 评论 0原文

目前,我的范围输入上的 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());
});

这有帮助吗?

Currently the onChange event on my range inputs is firing at each step.

Is there a way to stop this event from firing until the user has let go of the slider?

I'm using the range to create a search query. I want to be able to run the search every time the form is changed but issuing a search request at each step of the slider's movement is too much.


Here's the code as it stands:

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());
});

Does that help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

待天淡蓝洁白时 2024-10-27 07:14:01

用于最终选择的值:

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

用于获取滑动时的增量值:

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

Use for final selected value:

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

Use to get incremental value as sliding:

$(".slider").on("input", function(){console.log(this.value)});
心意如水 2024-10-27 07:14:01

有点晚了,但前几天我也遇到了同样的问题。这是我使用 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);

现在只需将您的函数绑定到“更改”事件即可。

Bit late, but I had the same problem the other day. Here is my solution using jQuery bind/trigger:

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

Now just bind your function to the 'changed' event instead.

看透却不说透 2024-10-27 07:14:01

呸!

使用 onmouseup 事件而不是 onChange

Bah!

Use onmouseup event Rather then onChange

亚希 2024-10-27 07:14:01

一个问题是,据我所知,HTML5 没有定义何时触发 onchange 事件,因此不同浏览器的情况很可能有所不同。您还必须考虑,浏览器实际上不必将 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; }

One problem is that AFAIK the HTML5 doesn't define when the onchange event is supposed to fire, so it is most likely different from browser to browser. And you also have to consider, that a browser doesn't actually have to render an input type=range as a slider.

Your only choice is that you have to build in a mechanism to make sure that your search isn't triggered too often, for example, check if a search is currently running and abort if it is, or make sure that searches are triggered at a maximum of every x seconds.

Quick example for the latter (just a quick hack, untested).

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; }
九八野马 2024-10-27 07:14:01

纯 JS 在这里:

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

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

Pure JS here:

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

or

myInput.onchange = function(){
    console.log(this.value);
}
夏了南城 2024-10-27 07:14:01

Gravediggin,但如果您需要它,请检查 js throttledebounce 函数

用法:

//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);
        }
    };
};

gravediggin but if you need it check js throttle or debounce functions

Usage:

//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));

Code:

/*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);
        }
    };
};
傾旎 2024-10-27 07:14:01

以下是我用于捕获 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());
});

如果您愿意,您还可以将“点击”事件绑定到范围滑块想要在单击(甚至拖动)时返回其值。把它想象成一个“mouseup”事件。 (我确实尝试过,但在单击滑块后滑块没有停止。)

JavaScript:

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

附带说明,这会返回一个字符串,因此请确保使用 'parseInt($(this ).value())' 在适当的时候。

希望这有帮助。

Here's what I use for capturing the 'change event' for the html5 range slider:

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());
});

You can also bind the 'click' event to the range slider if you want to return its value when it has been clicked (or even dragged). Think of it like a 'mouseup' event. (I did try that but the slider didn't stop after I had clicked on the slider.)

JavaScript:

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

On a side note, this returns a string so make sure you use 'parseInt($(this).value())' when appropriate.

Hope this helps.

简单爱 2024-10-27 07:14:01

我在同一页面中使用多个 HTML5 默认滑块,并进行以下设置:

  • 使用 oninput 事件移动滑块时,页面中的输出标记会更改值
  • 触发 change 事件发布后

使用最新的 Chrome 进行了测试,并在带有 Node 和 Socket.io 的 Raspberry 上编译良好。

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

<output id="APIDConKiVal"></output>  <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);
    }
}

I use several HTML5 default sliders in the same page with the following setup:

  • Output tag in the page changes value when the slider is moved using the oninput event
  • A change event is triggered once on release

Tested with the latest Chrome and compiles well on a Raspberry with Node and Socket.io.

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

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

A simple Javascript code creates the listeners. You might need to try different events instead of 'change' in the last line to see what fits you.

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);
    }
}
拥抱我好吗 2024-10-27 07:14:01

另一个建议:

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

another suggest:

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

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

你也可以尝试结合 bluronkeyuponmouseup 事件来尝试捕获不同的情况:当用户使用键盘箭头进行选择并点击 blur,当用户进行选择时onkeyup使用键盘时将注意力集中在滑块上,而在使用鼠标时则将注意力集中在 onmouseup 上。甚至可以只组合 onkeyuponmouseup

尽管如此,您仍然必须进行简单的检查该值是否已更改,并仅在发生更改后才运行必要的代码。

You can try to use blur event. Of course it also has it's limitations but it's just another suggestion :)

You can also try to combine the blur, onkeyup and onmouseup events to try to catch different situations: blur when the user makes the selection with keybord arrows and hits <Tab>, onkeyup when the user makes the selections with keyboard and stays focused on the slider, and onmouseup when he uses the mouse. It might be even possible to only combine the onkeyup and onmouseup.

Still you will have to make a simple check if the value has changed or not and run neccessary code only after a change occured.

虫児飞 2024-10-27 07:14:01

onchange 工作得很好,但我需要在滑动时更新该值。

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/

onchange works just fine , but I needed to update the value while sliding it.

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/

安稳善良 2024-10-27 07:14:01

让我们向集合添加一个简单的 ES6 替代方案:

let timer;

const debounceChange = (value, callback) => {
    clearTimeout(timer);
    timer = setTimeout(() => callback(value), 500);
};

在 JSX 中使用时,它看起来像这样:

<input type="range" onChange={e => debounceChange(e.target.value, props.onChange)}/>

Let's add a simple ES6 alternative to the collection:

let timer;

const debounceChange = (value, callback) => {
    clearTimeout(timer);
    timer = setTimeout(() => callback(value), 500);
};

When used in JSX it would look like this:

<input type="range" onChange={e => debounceChange(e.target.value, props.onChange)}/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文