web-dev-qa-db-fra.com

Evénement onChange pour la gamme HTML5

Actuellement, l'événement onChange sur mes entrées de gamme se déclenche à chaque étape.

Y a-t-il un moyen d'empêcher cet événement de se déclencher jusqu'à ce que l'utilisateur lâche le curseur?

J'utilise la plage pour créer une requête de recherche. Je souhaite pouvoir effectuer la recherche chaque fois que le formulaire est modifié, mais émettre une demande de recherche à chaque étape du déplacement du curseur est une tâche excessive.


Voici le code tel qu'il se présente:

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

Est ce que ça aide?

67
WilliamMayor

Utiliser pour la valeur finale sélectionnée:

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

Utilisez pour obtenir une valeur incrémentielle en glissement:

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

Un peu en retard, mais j'ai eu le même problème l'autre jour. Voici ma solution utilisant 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);

Maintenant, associez simplement votre fonction à l'événement 'modifié'.

14
Arwyn

Bah!

Utiliser onmouseup événement plutôt que onChange

9
Toastar

Un problème est que, autant que je sache, HTML5 ne définit pas quand l'événement onchange est censé se déclencher, il est donc probablement différent d'un navigateur à l'autre. Et vous devez également prendre en compte le fait qu'un navigateur n'a pas à rendre un input type=range comme un curseur.

Votre seul choix est que vous deviez créer un mécanisme pour vous assurer que votre recherche n'est pas déclenchée trop souvent, par exemple, vérifier si une recherche est en cours et abandonner si c'est le cas, ou vous assurer que les recherches sont déclenchées à un moment donné. maximum de chaque x secondes.

Exemple rapide pour ce dernier (juste un hack rapide, non testé).

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; }
6
RoToRa

Pure JS ici:

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

ou

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

gravediggin mais si vous en avez besoin, vérifiez js throttle ou debounce fonctions

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);
        }
    };
};
2
mons droid

Voici ce que j'utilise pour capturer "l'événement de changement" du curseur de la plage 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());
});

Vous pouvez également lier l'événement 'click' au curseur de la plage si vous souhaitez renvoyer sa valeur après avoir été cliqué (ou même déplacé). Pensez-y comme à un événement "mouseup". (J'ai essayé cela, mais le curseur ne s'est pas arrêté après que j'ai cliqué dessus.)

JavaScript:

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

Sur une note de côté, cela retourne une chaîne, alors assurez-vous d'utiliser 'parseInt ($ (this) .value ())' le cas échéant.

J'espère que cela t'aides.

1
Scott

J'utilise plusieurs curseurs par défaut HTML5 dans la même page avec la configuration suivante:

  • La balise de sortie dans la page change de valeur lorsque le curseur est déplacé à l'aide de l'événement oninput
  • Un événement change est déclenché une fois à la libération

Testé avec le dernier Chrome et se compile bien sur un Raspberry avec Node et 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"/>

Un simple code Javascript crée les auditeurs. Vous devrez peut-être essayer différents événements au lieu de "changer" à la dernière ligne pour voir ce qui vous convient.

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);
    }
}
1
Paolo

onchange fonctionne très bien, mais je devais mettre à jour la valeur en la faisant glisser.

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/

0
alejandro

une autre suggère:

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

Ajoutons une alternative simple à la collection ES6:

let timer;

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

Utilisé dans JSX, il ressemblerait à ceci:

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

Vous pouvez essayer d'utiliser blur event. Bien sûr, il a aussi ses limites, mais ce n'est qu'une autre suggestion :)

Vous pouvez également essayer de combiner les événements blur, onkeyup et onmouseup pour essayer d’attraper différentes situations: blur lorsque l’utilisateur effectue la sélection à l’aide de flèches clavier et frappe <Tab>, onkeyup lorsque l'utilisateur effectue les sélections au clavier et reste concentré sur le curseur, et onmouseup lorsqu'il utilise la souris. Il pourrait même être possible de ne combiner que onkeyup et onmouseup.

Vous devrez néanmoins vérifier si la valeur a changé ou non et exécuter le code nécessaire uniquement après une modification.

0
Michal Trojanowski