javascript - Skicka inte en händelse om en annan redan har skickats


Jag har en kod som ser ut så här:

$('#foo').on('click', function(e) {
   //do something
});

$('form input').on('change', function(e) {
  //do some other things
));

Första och andra händelsen gör faktiskt samma saker med samma inmatningsfält, men på olika sätt. Problemet är att när jag klickar på #foo-elementet så utlöses även formulärändringshändelsen. Jag behöver att formulärändringen alltid utlöses när innehållet i inmatningen ändras, men inte när #foo-elementet klickas.

Det är frågan )). Hur gör man detta?

Här är koden på jsfiddle: http://jsfiddle.net/QhXyj/1/

Svar #1

Vad som händer är att onChange utlöses när fokus lämnar #input. I ditt fall sammanfaller detta med att klicka på knappen. Försök att trycka på Tab och sedan klicka på knappen.

För att hantera detta specifika fall är en lösning att fördröja anropet till change-händelsen tillräckligt länge för att kontrollera om knappen klickades under tiden. I praktiken fungerade 100 millisekunder. Här är koden:

$().ready(function() {

    var stopTheChangeBecauseTheButtonWasClicked = false;
    $('#button').on('click', function(e) {
        stopTheChangeBecauseTheButtonWasClicked = true;
        $('#wtf').html("I don't need to change #input in this case");
    });

    $('#input').on('change', function(e) {
        var self = this;
        setTimeout(function doTheChange() {
            if (!stopTheChangeBecauseTheButtonWasClicked) {
                $(self).val($(self).val() + ' - changed!');
            } else {
                stopTheChangeBecauseTheButtonWasClicked = false;
            }
        }, 100);
    });
});

Och fiddeln - http://jsfiddle.net/dandv/QhXyj/11/

Svar #2

Det är helt naturligt att ett förändringsevent på ett avmarkerat element utlöses innan det klickade elementet får fokus. Om du inte vill använda en timeout ("gör något X ms efter att inmatningen ändrats om inte en knapp klickats däremellan", som föreslagits av Dan) - och timeouts är fula - kan du bara göra dessa åtgärder två gånger. Efter att inmatningen ändrats, spara dess tillstånd och gör något. Om sedan - någon gång senare - knappen klickas, hämta det sparade tillståndet och gör något liknande. Jag antar att detta är vad du faktiskt ville ha för ditt UI-beteende, inte alla användare är så snabba. Om någon lämnar inputfältet (t.ex. genom att trycka på Tab), och sedan senare aktiverar knappen "oberoende", vill du verkligen utföra båda åtgärderna?

var inputval = null, changedval = null;

$('form input').on('change', function(e) {
    inputval = this.value;
    // do some things with it and save them to
    changedval = …
    // you might use the value property of the input itself
));

$('#foo').on('click', function(e) {
    // do something with inputval
});

$('form …').on('any other action') {
    // you might want to invalidate the cache:
    inputval = changedval;
    // so that from now on a click operates with the new value
});