We have multiple spans inside of a div. We want spans to revert to the original layout when user clicks white space. This is the code:
var whiteSpace = function (){
$(function(){
$('div').on('click',function(e) {
if (e.target !== this)
return;
originalL();
});
});
};
The problem is we have two modes, work mode and set mode, and we want this to only work in the work mode. We change modes with keypress,
$(document).on("keypress", function (e){
if(e.which === 83) {
alert('"Shift + s" was pressed. Start Setup Mode.');
state = "false";
dragResize();
var whiteSpaceDisable = function (){
$(function(){
$('div').off('click',function(e) {
if (e.target !== this)
return;
originalL();
});
});
};
whiteSpaceDisable();
}
if(e.which === 87) {
alert('"Shift + w" was pressed. Start Work Mode.');
state = "true";
dragDropWidget ();
dragResizeDisable();
whiteSpace = function (){
$(function(){
$('div').on('click',function(e) {
if (e.target !== this)
return;
originalL();
});
});
};
whiteSpace();
}
});
When user tries to go to the set mode from the work mode first time, it works. However, when user tries to the same thing second time, it doesn't work. WhiteSpace function persists.
How can we turn this function off in the set mode? By the way, page reload is not an option.Thank you very much!
In your keypress handler, replace:
var whiteSpace = ...
with:
whiteSpace = ...
Right now you're just assigning the other function to a new whiteSpace variable that is scoped to that keypress handler function. If you want to override the previously defined whiteSpace variable, you need to make sure you're actually assigning to that same variable reference, not creating a new one.
Problem solved by placing 'if conditional' inside the originalL function, so it will evaluate before firing. this was the problem.
We just made a 'workMode' variable that can be set to whatever value we need through keypress function. Here's the code that fixed it:
var workMode = "off";
function originalL() {
if (workMode === "on"){
small1O();
small2O();
smalllongO();
smallwideO();
}
};
and at bottom of page, at the keystroke listeners, putting this:
$(document).on("keypress", function (e) {
if (e.which === 83) {
alert('"Shift + s" was pressed. Start Setup Mode.');
workMode = "off";
dragResize();
originalL();
}
;
if (e.which === 87) {
alert('"Shift + w" was pressed. Start Work Mode.');
workMode = "on";
smalllongExpand();
originalL();
dragResizeDisable();
}
Related
EDIT: I solved it by changing = to ==, but that didnt fully solve it but then I added a change to $currentSlide and now it works! Yay!
$(document).keydown(function(e) {
if(e.keyCode == 39)
{
if($currentSlide == $slide1){
slideShow(slide2);
$currentSlide = $slide2;
}
else if($currentSlide == $slide2){
slideShow(slide3);
$currentSlide = $slide3;
}
else if($currentSlide == $slide3){
slideShow(slide1);
$currentSlide = $slide1;
}
}
})
I have searched for an answer but haven't found anything that suits my question. I am a noob on javascript so bear with me.
I have a function that works as a slideshow. (I use $ in front of my jquery variables, I have a lot of javascript variables too so I just use it to separate them.)
var $currentSlide = "#slide1";
var $slide1 = "#slide1";
var $slide2 = "#slide2";
var $slide3 = "#slide3";
function slideShow($slide) {
if ($slide != $currentSlide){
$($currentSlide).fadeOut(500);
$($slide).delay(500).fadeIn(500);
$currentSlide = $slide;
}
};
To call this function, I use a simple link with parameter depending on which slide is active.
onclick="slideShow(slide2)"
And then I want to change slide with keypress (to right). This is my code for the keypress:
$(document).keydown(function(e) {
if(e.keyCode == 39) {
if ($currentSlide = $slide1){
slideShow(slide2);
} else if($currentSlide = $slide2) {
slideShow(slide3);
} else if($currentSlide = $slide3) {
slideShow(slide1);
}
}
})
It works perfectly when using the links but when I press key it behaves very weird. First click works like a charm, but then it doesnt work any more. If I click to get the third slide, another click will put next slide on top of slide3 but slide3 never goes away.
I realise there is some huge mistake by me here but I'm too much of a beginner to fix it. Any ideas?
your if-else conditions will always be true, because you used '=' instead of '=='. since your first if condition will be true it always shows slide2 and it looks to you that it only worked once
$(document).keydown(function(e) {
if(e.keyCode == 39) {
if ($currentSlide == $slide1){
slideShow(slide2);
} else if($currentSlide == $slide2) {
slideShow(slide3);
} else if($currentSlide == $slide3) {
slideShow(slide1);
}
}
})
The second problem maybe caused by the clock on the slideshow, if you are using one. When you click the next/previous button you need to reset the clock of your slideshow.
There are two issues
You do an assignment in your if conditions, so they always are true. Instead use the comparator ===;
In the onclick attribute you specify an undefined variable, since the $ is missing from it
Beside correcting this, I would suggest to use a class for your slide elements, not individual IDs. So use class="slide" instead of id="slide1" in your HTML, and apply it to all slides -- they can share the same class.
Then store the sequence number of the current slide, counting from 0.
I would also remove all the onclick attributes on the slide elements and deal with click handlers from code, which can be done quite concisely with $('.slide').click( ... ):
var currentSlideNo = 0; // zero-indexed
function slideShow(slideNo) {
if(slideNo != currentSlideNo){
$('.slide').get(currentSlideNo).fadeOut(500);
currentSlideNo = slideNo;
$('.slide').get(currentSlideNo).delay(500).fadeIn(500);
}
};
$('.slide').click(function () {
slideShow((currentSlideNo + 1) % $('.slide').length);
});
$(document).keydown(function(e) {
if (e.keyCode == 39) {
slideShow((currentSlideNo + 1) % $('.slide').length);
}
});
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 am writing a search function much like the [cmd+f] function in a browser. I have everything working but I want the enter key on press to cycle through the results through the page. I also have arrow buttons that call the function I wrote and they work. I prevented the default behavior of enter using:
$('form').keydown(function (event) {
if (event.keyCode == 13) {
event.preventDefault();
return false;
}
});
I am using this code to call the function on enter:
$('form').keyup(function (event) {
if (event.keyCode == 13) {
nextSearch();
}
});
It works for the first result but I think it resets the global variable I use to mark the place. The only logical answer I can think of is that pressing enter now refreshes the JavaScript. Is there a way to prevent this?
I use these global variables to keep track:
window.luCurrentNumber = 0;
window.luLastActive = 0;
If I understand you corrected, you the arrow keys and the enter keys to tab instead of performing their default. Here is an example of a function that I use to treat the Enter key as a tab, which I wrote because users kept hitting the enter key and accidentally submitting the page.
//Make enter key is pressed, tab instead of submitting.
$('body').on('keydown', 'input, select', function (e) {
var self = $(this)
, form = self.parents('form:eq(0)')
, focusable
, next
;
if (e.keyCode == 13) {
focusable = form.find('input,a,select,button').filter(':visible');
next = focusable.eq(focusable.index(this) + 1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
Though it's not exactly what you are trying to do, I think it should set you on the right path.
I want to add a autocomplete function to a site and found this guide which uses some js code which works really nice for one textbox: http://www.sks.com.np/article/9/ajax-autocomplete-using-php-mysql.html
However when trying to add multiple autocompletes only the last tetbox will work since it is the last one set.
Here is the function that sets the variables for the js script
function setAutoComplete(field_id, results_id, get_url)
{
// initialize vars
acSearchId = "#" + field_id;
acResultsId = "#" + results_id;
acURL = get_url;
// create the results div
$("#auto").append('<div id="' + results_id + '"></div>');
// register mostly used vars
acSearchField = $(acSearchId);
acResultsDiv = $(acResultsId);
// reposition div
repositionResultsDiv();
// on blur listener
acSearchField.blur(function(){ setTimeout("clearAutoComplete()", 200) });
// on key up listener
acSearchField.keyup(function (e) {
// get keyCode (window.event is for IE)
var keyCode = e.keyCode || window.event.keyCode;
var lastVal = acSearchField.val();
// check an treat up and down arrows
if(updownArrow(keyCode)){
return;
}
// check for an ENTER or ESC
if(keyCode == 13 || keyCode == 27){
clearAutoComplete();
return;
}
// if is text, call with delay
setTimeout(function () {autoComplete(lastVal)}, acDelay);
});
}
For one textbox I can call the function like this
$(function(){
setAutoComplete("field", "fieldSuggest", "/functions/autocomplete.php?part=");
});
However when using multiple textboxes I am unsure how I should go about doing this, here is something I did try but it did not work
$('#f1').focus(function (e) {
setAutoComplete("f1", "fSuggest1", "/functions/autocomplete.php?q1=");
}
$('#f2').focus(function (e) {
setAutoComplete("f2", "fSuggest2", "/functions/autocomplete.php?q2=");
}
Thanks for your help.
You should be using classes to make your function work in more than one element on the same page. Just drop the fixed ID's and do a forEach to target every single element with that class.
For example:
When someone types # it will ready the function.
On Twitter for example, shows something when someone types #USERNAME then after the space, they don't show anything.
Here an javascript example:
document.getElementById('test').onkeyup = function(oEvent) {
if (typeof oEvent == 'undefined') oEvent = window.event; // IE<9 fix
if (oEvent.keyCode != 32) return; // stop if character is not the space
if (/#USERNAME /.test(this.value)) { // check if #-template is available
this.value = this.value.replace(/#USERNAME /g, 'Dirk '); // replace it
}
}
Also see this jsfiddle.
=== UPDATE ===
Here an jQuery alternative:
$('#test').keyup(function(oEvent) { // set (keyup) event handler
if (oEvent.keyCode != 32) return; // stop if character is not the space
if (/#USERNAME /.test($(this).val())) { // check if #-template is available
$(this).val($(this).val().replace(/#USERNAME /g, 'Dirk ')); // replace it
}
});
Also see this jsfiddle.
Perhaps you can try an onkeypress event on pressing the spacebar.