As I want to unbind(off) the events I wrapped the code inside a function but as I need to see which key is pressed I need to get the event of the event(not sure how this is called.
// normal example
$('body').on('keydown',function( event ){
if(event.keyCode == 37){
// do something
}
});
// my example
function keyDownHandler() {
if(event.keyCode == 39) {
// does not work
}
}
$('body').on('keydown', keyDownHandler);
You need to get the event object, you can get it as callback function argument
function keyDownHandler(event) {
// set it here ----^^^^^^---
if(event.keyCode == 39) {
// works now
}
}
$('body').on('keydown', keyDownHandler);
$(document).ready(function () {
//1st way
$('body').on('keydown', function(event){
keyDownHandler(event);
});
//2nd way ,same as first but shorter use it for send event only
$('body').on('keydown', keyDownHandler);
//3rd way ,this way to send more data
$('body').on('keydown', {example:'hello world'},keyDownHandler2);
});
function keyDownHandler(event) {
console.log(event.keyCode);
}
function keyDownHandler2(event) {
console.log(event.keyCode);
console.log(event.data.example);
}
Related
In a jQuery script I have a function that normally gets called in response to a click, so acts as an event handler, but I also need to call it directly. In both cases it needs some parameters.
So, the situation, simplified, is this:
function go(e) {
console.log(e.data.dir)
}
$("body").keydown(function(e) {
if (e.which == 37) { // left
go({dir: 'forward'});
} else if (e.which == 39) { // right
go({dir: 'forward'});
}
});
$('.forward').on('click', {
dir: 'forward'
}, go);
Here's a fiddle
This clearly doesn't work because when I call the function directly there's no data key.
A workaround would be to call the function like this:
go({data: {dir: 'forward'}});
And it works, but is pretty ugly.
What would it be the right approach in such a case?
In this particular case, you can solve the issue with apply() and just pass along the arguments from the event handler if the condition is truthy
function go(e) {
console.log(e.data.dir)
}
$("body").on('keydown', {dir: 'forward'}, function(e) {
if (e.which === 37 || e.which === 39) {
go.apply(this, arguments);
}
});
$('.forward').on('click', {dir: 'forward'}, go);
FIDDLE
Or you could pass in an object with the matching properties
$("body").on('keydown', {dir: 'forward'}, function(e) {
if (e.which === 37 || e.which === 39)
go({data:{dir: 'forward'}});
});
or trigger the click event with a custom event
$("body").on('keydown', {dir: 'forward'}, function(e) {
if (e.which === 37 || e.which === 39)
$('.forward').trigger('click', [{data: {dir: 'forward'}}] );
});
There are two ways I can see this going.
You could store you parameter object in a variable at the top of your script, and pass the variable to go() when you need to call it outside of a click handler. That would make things a little less ugly.
Or you could check if e is null inside go(), and if it is, use/set some generic default.
Either would be acceptable, depending on what all the method has to do.
I think I would do something like this (unless I need the event):
function go(data) {
console.log(data.dir)
}
$("body").keydown(function(e) {
if (e.which == 37) { // left
go({dir: 'forward'});
} else if (e.which == 39) { // right
go({dir: 'forward'});
}
});
$('.forward').on('click', function(){
go({dir: 'forward'});
});
How can I bind 2 different events when the document loads?
I have a text field and a button. The function should be executed either when the button is clicked:
$(document).ready(function() {
$("button").click(function() {
myFunction();
});
});
or when Enter is pressed:
$("#id_of_textbox").keyup(function(event){
if(event.keyCode == 13){
myFunction();
}
});
But how to combine both events?
Did you want this:
$(document).ready(function() {
$("button").click(function() {
myFunction();
});
$("#id_of_textbox").keyup(function(event){
if(event.keyCode == 13){
myFunction();
}
});
});
You can bind your function to as many events as needed, here's one way...
$(document).ready(function() {
$("button").click(myFunction);
$("#id_of_textbox").keyup(myFunction);
});
function myFunction(event) {
if ((event.type === 'keyup') && (event.keyCode !== 13)) {
return;
}
// process event here
}
I have created two functions. To keep it simple lets take for an example the following:
I got functions firing different events for the same objects. You can activate them using your keyboard arrows
$("body").keydown(function(e) {
if (event.which == 39) open_second_layer();
});
$("body").keydown(function(e) {
if (event.which == 37) open_first_layer();
});
As soon as I have fired one function and press the same key again it fires the animation one more time (unnecessarily).
Because of that as soon as the function open_second_layer has been fired, it should not be able to be fired again, until open_first_layer is fired again. The same should be the case the other way round.
I found .bind and .when as possible solutions, but can't figure out how to use them the right way for that case. I appreciate every suggestions or keywords to google.
You can keep a state variable and track when changes are made to it:
var state_changed = (function() {
var current = null;
return function(state) {
if (state == current) {
return false;
}
current = state;
return true;
};
}());
function open_first_layer()
{
if (!state_changed(1)) {
return;
}
// rest of code
}
function open_second_layer()
{
if (!state_changed(2)) {
return;
}
// rest of code
}
$("body").keydown(function(e) {
if (event.which == 39) {
open_second_layer();
} else if (event.which == 37) {
open_first_layer();
}
});
You can use jQuery's one().
In your first click handler, you bind the second one.
In your second click handler, you bind the first one.
sample
<div id=activate-first>first</div>
<div id=activate-second style="display:none;">second</div>
$(document).ready(function () {
function slide_first(){
$('#activate-first').show();
$('#activate-second').hide();
$('#activate-second').one('click', slide_first);
};
function slide_second(){
$('#activate-first').hide();
$('#activate-second').show();
$('#activate-first').one('click', slide_second);
};
$('#activate-first').one('click', slide_second);
$('#activate-second').one('click', slide_first);
});
Put the other function inside slide_first, like:
function slide_first(){
// other code
$('#activate_second').one('click', slide_second);
}
$('#activate_first').one('click', slide_first);
or use an Anonymous function to do the same:
$('#activate_first').one('click', function(){
// slide_first code here
$('#activate_second').one('click', function(){
// slide_second code here
});
});
Maybe your really want:
function recursiveSlider(){
$('#activate_first').one('click', function(){
// slide_first code here
$('#activate_second').one('click', function(){
// slide_second code here
recursiveSlider();
});
});
}
recursiveSlider();
This is a perfect use case for delegation. You have a single click event, and whenever the event happens, you determine what has been clicked, and you take action accordingly:
$(document.body).on("click", function(ev) {
var $targ = $(ev.target);
if ($targ.is('#button_1')) {
// someone clicked #button_1
}
if ($targ.is('.page-2 *')) {
// something inside of .page-2 was clicked!!
}
});
UPDATE: now the OP has included more code, I'm not sure the issue is - there's no need to bind and unbind events...
http://jsfiddle.net/ryanwheale/uh63rzbp/1/
function open_first_layer() {
$('#first_panel').addClass('active');
$('#second_panel').removeClass('active');
}
function open_second_layer() {
$('#first_panel').removeClass('active');
$('#second_panel').addClass('active');
}
// one event === good
$("body").keydown(function(e) {
if (event.which == 39) open_second_layer();
if (event.which == 37) open_first_layer();
});
... or if you're trying to build a slider, I suggest changing your naming convention:
http://jsfiddle.net/ryanwheale/uh63rzbp/2/
var current_layer = 1,
$all_layers = $('[id^="panel_"]'),
total_layers = $all_layers.length;
function move_layer (dir) {
current_layer += dir;
if (current_layer < 1) current_layer = total_layers;
else if (current_layer > total_layers) current_layer = 1;
$all_layers.removeClass('active');
$('#panel_' + current_layer).addClass('active');
}
// one event === good
$("body").keydown(function(e) {
if (event.which == 39) move_layer(1);
if (event.which == 37) move_layer(-1);
});
move_layer(0);
I'm trying to use mouse events in a slideshow in Javascript. How do I use the keyup event to change the image? If I use KeyUp in the text box it's working, but when I use it on the image below it doesn't work.
<script>
var image=document.getElementById("x")
image.addEventListener("keyup",displaykey,false)
image.addEventListener("click",previous,false)
image.addEventListener("contextmenu",next,false)
var step=1;
function previous()
{
step--;
if(step==0)
{
step=3;
}
document.slide.src=eval("show"+step+".src")
}
function next(event)
{
step++;
if(step==4)
{
step=1;
}
document.slide.src=eval("show"+step+".src")
event.preventDefault()
}
function displaykey(event)
{
console.log(e.target)
var unicode=e.keyCode
event.preventDefault();
if((unicode==33)||(unicode==38))
{
previous();
}
else if((unicode==40)||(unicode==34))
{
next();
}
}
</script>
You can try to use JQuery hotkeys plugin that
lets you easily add and remove handlers for keyboard events anywhere in your code supporting almost any key combination.
Since you are wanting to change the image on a keyup event and only use javascript the following code will work :
document.onkeyup = function(e) {
var image = document.getElementById('x');
//Left Key
if (event.keyCode == 37) {
previous();
//Right Key
} else if (event.keyCode == 39) {
next();
}
}
This code will execute the onclick event of the image you have whenever the user lifts the left or right directional keys. You can change the keycodes and add more should you wish.
function displaykey(event) {
console.log(e.target)
var unicode=e.keyCode
event.preventDefault();
if((unicode==33)||(unicode==38)) {
previous();
} else if((unicode==40)||(unicode==34)) {
next();
}
}
I think the error occurs here as you passed event in argument and is then using e instead of event.
I need to make click event and arrow right make the same event
So instead of this repeated code
$('#foo').on('click',function() {
//do something
});
$(document).keydown(function(e){
if (e.keyCode == 39) {
//do the same thing above
}
});
How should i do it?
Thank You :)
make them both trigger the same function.
$('#foo').on('click', CoolFunction);
$(document).keydown(function(e){
if (e.keyCode == 39) {
CoolFunction();
}
});
function CoolFunction() {
//same thing
}
Have both call the same function, or alternatively in keydown you could do
$('#foo').trigger('click');
Use built in javascript so both have the same context. Don't use trigger, it has side effects.
$('#foo').on('click', commonFn);
$(document).keydown(function(){
if (e.keyCode == 39) {
commonFn.apply(this,arguments);
}
});
function commonFn() {
//same thing
}