How to run a function once when binding to multiple events that all trigger in Javascript?

 ̄綄美尐妖づ 提交于 2019-12-01 09:18:48

I would try to set up a value-checking function like this:

var $inputIntance = $("#path-to-your-input");
var lastInputValue;

function checkInputValue () {
    var newValue = $inputIntance.val();
    if (newValue != lastInputValue) {
        // make your AJAX call here
        lastInputValue = newValue;
        el = $inputIntance.closest('ul');
        widget[func](dyn, el, lib_template, locale, lastInputValue, "update");
    }
}

and then then fire this checks by any user-action event you like:

$inputIntance.on('keyup change', function(e) {
    checkInputValue();
}

or like this

$inputIntance.on('keyup change', checkInputValue );

UPDATE: there might be the case when you have to limit the number of AJAX requests per time. I added time control functionality to my previous code. You can find the code below and try it live here in JSFiddle.

$(document).ready(function () {
    var $inputIntance = $("#test-input");
    var lastInputValue;
    var valueCheckTimer;
    var MIN_TIME_BETWEEN_REQUESTS = 100; //100ms
    var lastCheckWasAt = 0;

    function checkInputValue () {
        lastCheckWasAt = getTimeStamp();
        var newValue = $inputIntance.val();
        if (newValue != lastInputValue) {
            // make your AJAX call here
            lastInputValue = newValue;
            $("#output").append("<p>AJAX request on " + getTimeStamp() + "</p>");
            //el = $inputIntance.closest('ul');
            //widget[func](dyn, el, lib_template, locale, lastInputValue, "update");
        }
    }

    function getTimeStamp () {
        return (new Date()).getTime();
    }

    function checkInputValueScheduled() {
        if (valueCheckTimer) { // check is already planned: it will be performed in MIN_TIME_BETWEEN_REQUESTS
            return;
        } else { // no checks planned
            if  ((getTimeStamp() - lastCheckWasAt) > MIN_TIME_BETWEEN_REQUESTS) { // check was more than MIN_TIME_BETWEEN_REQUESTS ago
                checkInputValue();
            } else { // check was not so much time ago - schedule new check in MIN_TIME_BETWEEN_REQUESTS
                valueCheckTimer = window.setTimeout(
                    function () {
                        valueCheckTimer = null;
                        checkInputValue();
                    }, 
                    MIN_TIME_BETWEEN_REQUESTS
                );
            }
        }
    }

    $inputIntance.bind('keyup change', function(e) {
        $("#output").append("<p>input event captured</p>");
        checkInputValueScheduled();
    });
});

I came across this problem before and what I ended up doing is saving the request on an object upon creation and test for a previously set one to abort it if necessary. You'd have to edit the function that triggers the ajax call. For example:

if ( ajaxRequest ) { 
  ajaxRequest.abort();
}
ajaxRequest = $.ajax({ ... }); // triggers ajax request and saves it

If the widget function returns an ajax object then you can probably assign that to the variable instead of modifying the original ajax request.

Any reason for listening to keyUp in addition to change? Maybe what really matters is just one of these events.

If not, I guess you will have to use a closure as you suggested.

Ok. I got it (after a felt 1000 tries...).

Here is what works = triggers whichever event fires first, blocks the trailer:

var isEven;
input.on('keyup change', function(e) {
    isEven = true;
    if (timer) {
        window.clearTimeout(timer);
    }
    timer = window.setTimeout( function() {
        timer = null;
        val = input.val();
        el = input.closest('ul');
        // prevent double firing after interval passed
        if (isEven === true ){
            isEven = false;
        } else {
            isEven = true;
            return;
        }
        widget[func](dyn, el, lib_template, locale, val, "update");
    }, interval );
});

Seems to do what it should. Feel free to correct me, if it's wrong.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!