I have a bunch of places where I have to code the same functionality for a click and an ENTER key press (keyup). I'm ending up writing event handlers like this:
$('#SomeElement').on('click keyup', function (e) {
if (e.type === 'click' || e.type === 'keyup' && e.keyCode === 13) {
// do what needs to be done
}
});
Is there an elegant way of handling this without the if statement? I hate the fact that it's an event handler specific to click and keyup, yet I have to check the event type inside the handler.
EDIT: I'm OK with abstracting out the if statement into a separate function. As long as I don't have to copy/paste the same line of code over and over again.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
(function( $ ) {
$.fn.clickOrKeyPress = function( callback ) {
this.on('click keyup', function (e) {
if (e.type === 'click' || e.type === 'keyup' && e.keyCode === 13) {
callback(e);
}
});
return this;
};
}( jQuery ));
You will need an if condition to confirm if the key pressed is enter. So you cannot completely get rid of if condition there.
But you can get rid of redundant conditions, like you don't need to check if the event type is keyup as we know if the event is not click, it will definitely be a keyup event.
So you can reduce your condition to
e.type === 'click' || e.keyCode === 13
My final solution - jQuery Event Extensions.
Create jQuery event extension specific for ENTER key.
$.event.special.enterkey = {
delegateType: 'keyup',
bindType: 'keyup',
handle: function (event) {
if (event.keyCode === 13)
return event.handleObj.handler.apply(this, arguments);
}
};
Now all I have to do is the following. Neat and elegant.
$('#SomeElement').on('click enterkey', function (e) {
// do what needs to be done
});
P.S. To all the incognito downvoters - you should be ashamed of yourselves.
I have not tested this yet, but maybe you can do named function and pass it with another callback to the event handler?...
Example (not tested!):
// Define the callback function somewhere
function clickKeyupCallback(e, callback) {
if (e.type === 'click' || e.type === 'keyup' && e.keyCode === 13) {
return callback;
}
}
$('#SomeElement').on('click keyup', clickKeyUpCallback(e, function() {
// your normal code here
}));
// EDIT
I realized the named function has to sit on a different place here if you want to do it this way and abstract the "if" part.
another example:
// Define the callback function somewhere
function clickKeyupCallback(e, callback) {
if (e.type === 'click' || e.type === 'keyup' && e.keyCode === 13) {
callback();
}
}
$('#SomeElement').on('click keyup', function(e) {
clickKeyupCallback(e, function() {
// do what ever needs to be done
});
});
I didn't understand clearly what you mean by "I have a bunch of places where I have to code the same functionality". But according to my understanding you want to attach some handlers to some elements that involve this check.
function doSomething(e) {
//do what needs to be done
}
function handleEvent(attachedHandler) {
return function(e) {
if (e.type === 'click' || e.type === 'keyup' && e.keyCode === 13) {
attachedHandler(e);
}
};
}
$('#SomeElement').on('click keyup', handleEvent(doSomething));
lemme know if it helps you...
Related
I want to run countup(); and random(); function after I hit enter on my keyboard. But I wanna make that it's only work for the first time.I mean when first time i hit enter, it will run that function. But if those function already run and I hit enter again, it'll never effect anything.
Here's my code :
addEventListener("keydown", function(e){
if (e.keyCode === 13) {
countup();
random();
}
});
Anyone can help me? Thanks.
Do something like this
// Create a named function as your event handler
var myFunction = function (e) {
if (e.keyCode === 13) {
// Do your stuff here
countup();
random();
// Remove event listener so that next time it is not triggered
removeEventListener("keydown", myFunction);
}
};
// Bind "keydown" event
addEventListener("keydown", myFunction);
Idea is user a global variable, set it after firing event.
var is_fired = false;
addEventListener("keydown", function(e){
if (e.keyCode === 13 && is_fired == false) {
countup();
random();
is_fired = true
}
});
You can make click event listener work only once after trigger it.you just need to add another argument to addEventListener() which is {once:true}and it will work as expected:
addEventListener("keydown", function(e){
if (e.keyCode === 13) {
countup();
random();
}
},{once: true});
Check my question it's similar to your case.
Also you can just use removeEventListener()method but you should defined your Anonymous function before as external function like myKeyPressed() and then inside if condition remove event Listener from your element:
element.removeEventListener("keydown", myKeyPressed);
var is_clicked = false;
addEventListener("keydown", function(e){
if (e.keyCode === 13 && !is_clicked) {
countup();
random();
is_clicked = true;
}
});
There is a removeEventListener function in javascript but it's tricky to implement that inside the function you are calling on addEventListener.
Try this, it worked in jsfiddle.
addEventListener("keydown", function(e){
if (e.keyCode === 13) {
alert("i did it");
this.removeEventListener('keydown',arguments.callee,false);
}
});
You can add a variable to check the status of your keydown.
The first time you use it, set it up to true. So you will only have this function triggered once.
var n = document.getElementById("txtInput"),
r = document.getElementById("result"),
loadFlag = true;
n.addEventListener("keyup", function(e) {
if (e.keyCode === 13 && loadFlag ) {
countup(r);
random(r);
loadFlag = false;
}
}, false);
To add keydown to an element in your HTML code.
element.addEventListener("keydown", event => {
//check if event is cancelable because not all event can be cancelled
if(event.cancelable)
{
//this prevent element from executing the default event when user click
event.preventDefault()
if(event.keycode === 13){ //write your statement here }
}
}
for more https://www.w3schools.com/jsref/event_preventdefault.asp
I'm working on a form where I do not want enter/return to submit the form so I used a function like this.
$('[name="form"]').keypress(function(e) {
var charCode = e.charcode || e.keyCode || e.which;
if (charCode === 13) {
e.preventDefault();
return false;
}
});
That works, but now I want to assign the enter/return to perform functions on two inputs on the form. I'm totally stuck.
To get the inputs I've tried vanilla js calling by id, jQ calling by id and then a mixer of the two with variables. I've also tried .keypress, .keydown, .keyup instead of the attachEventListener method. No matter what I do, I get this error in console.
"TypeError: ...addEventListener is not a function" (or keypress, keydown etc.)
I've also researched a good deal but can't find any solution. I appreciate any suggestions.
Here is this block of code in it's current form that's giving the trouble.
var yelpInput = $('#inputURL');
var googleInput = $('#googleURL');
yelpInput.addEventListener("keydown", function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
// Google
googleInput.addEventListener("keydown", function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
Thanks
var yelpInput = $('#inputURL');
var googleInput = $('#googleURL');
yelpInput.keydown(function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
// Google
googleInput.keydown(function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
yelpInput is jQuery wrapped object which does not have addEventListener method.
Use .on to attach event-handler on jQuery wrapped object or yelpInput[0].addEventListener/yelpInput.get(0).addEventListener to attach event using JavaScript as yelpInput[0] will be an DOMElement not jQuery-wrapped object.
var yelpInput = $('#inputURL');
var googleInput = $('#googleURL');
yelpInput.on("keydown", function(e) {
//-----^^^
if (e.keyCode === 13) {
alert('do stuff!');
}
});
googleInput.on("keydown", function(e) {
//-------^^^
if (e.keyCode === 13) {
alert('do stuff!');
}
});
I have 2 events, a keydown and a click. I would like to put them into a single function and when the function is called, whichever event was fired would do what it's supposed to.
Example:
var close = function () {
$('.alert').remove();
};
$(document).on('keydown', function (event) {
if (event.keyCode === 27) {
//27 = ESC
close();
}
});
$('.alertBG').on('click', function () {
close();
});
I can't think of a way to get the document and .alertBG parts to play nicely. (Fiddle)
Don't. Your functions are too different. You have already factored the reusable parts of them out into a close function that you call from both. This is the best way to do it.
If you really wanted to, then you would have to bind a click/keydown handler to document and test the type of event and the element.
$(document).on("keydown click", function (event) {
if (
(event.type === "keydown" && event.keyCode === 27) || (event.type === "click" && (
$(event.target).is(".alertBG") || $(event.target).parents(".alertBG").length))) {
close();
}
});
As you can see, it's much cleaner just to bind your event handlers separately when there are so many differences between them.
Do you mean something like this?
function handler(event) {
if(event.type === "click") {
close();
} else if(event.type === "keydown") {
if (event.keyCode === 27) {
//27 = ESC
close();
}
}
}
$(document).on('keydown', handler);
$('.alertBG').on('click', handler);
Anything like this ?
function myFunc(method){
if(method == "one"){
// do anything
}
else if(method == "other"){
// do other thing
}
}
$(document).on('keydown', function (event) {
if (event.keyCode === 27) {
myFunc("one");
}
});
$('.alertBG').on('click', function () {
myFunc("other");
});
I'm trying to setup a text box that runs a function on keydown.
The code is:
var input = document.getElementById('Input_Number');
input.addEventListener('onkeypress', DrawDigits);
function DrawDigits(event) {
if (event && event.keyCode == '13') {}
}
Here's an example:
http://jsfiddle.net/wuK4G/
I know this is a common question, but I really can't find the answer. I've tried several methods and none of them work.
Try this:
function DrawDigits(event) {
if (event && event.keyCode == '13') {}
}
var input = document.getElementById('Input_Number');
input.addEventListener('keypress', DrawDigits);
// ^^
The eventlistener is keypress instead of onkeypress.
If you assign the eventlistener without addEventListener it is:
document.getElementById('Input_Number').onkeypress = DrawDigits
Maybe that was the confusion?
I'm trying to trigger something to happen either when I press the escape key or when I click on an element. I've tried using..
if( $( '#some_id' ).click() || e.keyCode == 27 )
{
alert( 'Click or esc' );
}
But that doesn't seem to be working, is there something else I can use? If I do each individually like..
$( '#some_id' ).click(...);
or..
if( e.keyCode == 27 )
it works without a problem, but I'd prefer to have it working together to avoid code duplication. Sorry if it's something stupid I missed but would really like to get this sorted.
Thanks :)
Use .bind() .on() (as of jQuery 1.7) passing in multiple events:
$("#some_id").on("click keyup", function (e) {
if (e.type == "click" || e.keyCode == 27) {
alert("click or esc");
}
});
You mentioned code duplication. Why not do them separately, but put the code you want to execute for both of them into a function:
$('#some_id').click(function () {
doStuff();
});
$('#some_id').keypress(function (e) {
if (e.keyCode == 27) doStuff();
});
function doStuff() {
alert('Click or esc');
}