I'm working withjQuery.payment on a credit card number text input field. When the user enters any 4th number (4, 8, 12) the plugin automatically puts in a space for a nice look. Because of this, only the keyup
event fires, not the input
event. However, if the user were to right-click and paste a value in, then only the input
event fires. So we have cases where it's one or the other, or both events firing.
I have a bound anonymous function for change keyup input
to ensure all use-cases are covered, but I want the function to only run once each time the key is pressed, but normal key presses fire both keyup
and input
. jQuery's .one()
is not an option because this function needs to run more than once, just not twice for one key press. How can I make sure this function only runs once even when both events are fired from one key press?
I know I could edit jQuery.payment and trigger the input
event, but I don't want to modify vendor plug-ins, in case I decide to change versions or something down the road.
You could play around with attaching/detaching event handlers all day and never hit on a successful formula.
If your event handler was idempotent (for a given input state), then you wouldn't need to worry about triggering it twice.
If the handler is not naturally idempotent, then you can include a condition which ensures that a second successive call, with the same input value, does nothing. It's slightly contrived, but this can be regarded as "forced idempotence".
To achieve this, the input element's "last state" (its value) needs to be stored, read back and tested.
You could store the state in some outer/global javascript var but it's neater to use a '.data()' property of the element itself (which is actually 100% js, not pushed into the DOM).
$(function() {
$("#myInput").on("keyup input", function(e) {
var $this = $(this),
$lastState = $this.data('lastState') || '',//read back the element's previous state (or empty string if this is the first call)
val = $this.val();//current state
if(val !== $lastState) {//the all-important test.
$this.data('lastState', val);//store current state to be read back at next call
//here do whatever is required of your event handler.
}
});
});
I would use jQuery change event and always make sure the event was not binded before. And i would not follow a logic like "when user presses the 4th digit". Instead i would format the whole text every time.
function MyInputChanged(){
var currentText = $("#myInput").val();
var newText = someFunctionToFormatText(currentText);
$("#myInput").val(newText);
}
$("#myInput").unbind("change", MyInputChanged);
$("#myInput").bind("change", MyInputChanged);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.