Wait for mouse click to execute the rest of the function - javascript

I have a quiz that after selecting the answer it will show result and move on to the next question after a set time.
Now how can i make it to show the result then pause and wait for mouse click before moving on?
self.rightAnswer = function(elm) {
startSound('rightsound', false);
//var bgcss = ($("#" + elm).toggleClass('correct'))
$(elm).toggleClass('correct');
background.pause();
setTimeout(function () {
self.money($(".active").data('amt'));
if(self.level() + 1 > 6) {
$("#game").fadeOut('slow', function() {
$("#game-over").html('Thanks you!');
$("#game-over").fadeIn('slow');
});
} else {
$("#question-answer-block").fadeOut('fast', function(){
$("#question-answer-block").fadeIn('slow');
self.level(self.level() + 1);
var bgcss = ($(elm).toggleClass('correct'))
self.showAllAnswers();
self.transitioning = false;
});
}
self.resetAnswersView();
startSound('background', true);
}, 5000);
}

Related

Click event works on third or fourth try on button

This is a continuation of This
I used setTimeout() to place cursor on the input fields on pressing the tab, without which the focus goes to a link outside the <div> for some reason I am not aware of.
setTimeout() fixed that issue, but now:
On clicking on submit button the form does nothing but place cursor on the input fields for three or four times then proceeds with submitting.
Here is the submit button functions
$(“#submitbtn”).click(function(e) {
console.log(“click”);
e.preventDefault();
var s = setTimeout(function() {
removeTimeouts();
startValidation();
});
e.stopPropagation();
e.cancelBubble = true;
});
Here is hover function for Submit button
$(“#submitbtn”).mouseover(function(e) {
console.log(“Hover”);
removeTimeouts();
$(“#submitbtn”).focus();
e.preventDefault();
e.stopPropagation();
e.cancelBubble = true;
});
The function removeTimeouts() has all clearTimeout() for all setTimeout() through out the JavaScript file.
But somehow the click function is never works until third or fourth try.
The hover function works on first mouse move though, it prints “Hover” on console, every time the mouse it moves over submit button.
Even after clearing all setTimeout() somehow the focus is moved to input fields instead of proceeding with the console.log() onclick.
Can someone help me understand the issue and help fix the form gets submitted on first click?
Update:
1) This is typed from mobile app, even after re-editing the quote appearing as “” It’s correct in my code just not here.
2) Focus and timeout event is to validate the input fields while moving out of the input field, like if the field is empty, the cursor won’t move to next input field. But just focus is not working, and tab just takes the cursor out of the input fields to a link below it, so time-out helps keeping the cursor the input field.
3) Snippet - This does not replicate the issue as this is by far I can post the code sorry :(
(function ($) {
// Behind the scenes method deals with browser
// idiosyncrasies and such
$.caretTo = function (el, index) {
if (el.createTextRange) {
var range = el.createTextRange();
range.move("character", index);
range.select();
} else if (el.selectionStart != null) {
el.focus();
el.setSelectionRange(index, index);
}
};
// Another behind the scenes that collects the
// current caret position for an element
// TODO: Get working with Opera
$.caretPos = function (el) {
if ("selection" in document) {
var range = el.createTextRange();
try {
range.setEndPoint("EndToStart", document.selection.createRange());
} catch (e) {
// Catch IE failure here, return 0 like
// other browsers
return 0;
}
return range.text.length;
} else if (el.selectionStart != null) {
return el.selectionStart;
}
};
// The following methods are queued under fx for more
// flexibility when combining with $.fn.delay() and
// jQuery effects.
// Set caret to a particular index
$.fn.caret = function (index, offset) {
if (typeof(index) === "undefined") {
return $.caretPos(this.get(0));
}
return this.queue(function (next) {
if (isNaN(index)) {
var i = $(this).val().indexOf(index);
if (offset === true) {
i += index.length;
} else if (typeof(offset) !== "undefined") {
i += offset;
}
$.caretTo(this, i);
} else {
$.caretTo(this, index);
}
next();
});
};
// Set caret to beginning of an element
$.fn.caretToStart = function () {
return this.caret(0);
};
// Set caret to the end of an element
$.fn.caretToEnd = function () {
return this.queue(function (next) {
$.caretTo(this, $(this).val().length);
next();
});
};
}(jQuery));
var allTimeouts = [];
function placeCursor(id) {
id.focus(function(e) {
e.stopPropagation();
//e.cancelBubble();
id.caretToEnd();
});
id.focus();
}
function removeTimeouts(){
for(var i = 0; i < allTimeouts.length; i++) {
clearTimeout(allTimeouts[i]);
}
}
function focusInNumber (id) {
var thisID = id;
var nextID = id + 1;
var preID = id - 1;
//$("#number" + thisID).prop("disabled", false);
var s = setTimeout(function() {
placeCursor($("#number" + thisID));
});
allTimeouts.push(s);
if(preID != 0) {
if($("#number" + preID).val().length <= 0) {
var s = setTimeout(function() {
placeCursor($("#number" + preID));
});
allTimeouts.push(s);
}
}
}
function focusOutNumber (id) {
var thisID = id;
var nextID = id + 1;
var preID = id - 1;
var value = $("#number" + thisID).val();
var regex = new RegExp(/^\d*$/);
var regex1 = new RegExp(/^.*[\+\-\.].*/);
var l = $("#number" + thisID).val().length;
if(!value.match(regex)) {
alert("Just enter numerical digits");
var s = setTimeout(function() {
placeCursor($("#number" + thisID));
},5000);
allTimeouts.push(s);
} else {
if (l<=0) {
alert("This field cannot be empty");
var s = setTimeout(function() {
placeCursor($("#number" + thisID));
},5000);
allTimeouts.push(s);
} else {
if(value.match(regex)) {
var s = setTimeout(function() {
placeCursor($("#number" + nextID));
}, 100);
allTimeouts.push(s);
}
}
}
}
$(document).ready(function(){
$("#number1").focusin(function(){
focusInNumber(1);
});
$("#number1").focusout(function(){
focusOutNumber(1);
});
$("#number2").focusin(function(){
focusInNumber(2);
});
$("#number2").focusout(function(){
focusOutNumber(2);
});
$("#number3").focusin(function(){
focusInNumber(3);
});
$("#number3").focusout(function(){
focusOutNumber(3);
});
$("#number4").focusin(function(){
focusInNumber(4);
});
$("#number4").focusout(function(){
focusOutNumber(4);
});
$("#submitbtn").click(function(e) {
console.log("click");
e.preventDefault();
var s = setTimeout(function() {
removeTimeouts();
alert("startValidation()");
});
e.stopPropagation();
e.cancelBubble = true;
});
$("#submitbtn").mouseover(function(e) {
console.log("Hover");
removeTimeouts();
$("#submitbtn").focus();
e.preventDefault();
e.stopPropagation();
e.cancelBubble = true;
});
});
.SubmitBtn {
width: 100%;
background-color: #cccccc;
}
.Submitbtn:hover {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" class="reqField" id="number1" placeholder="Enter Number only"></input>
<input type="number" class="reqField" id="number2" placeholder="Enter Number only"></input>
<input type="number" class="reqField" id="number3" placeholder="Enter Number only"></input>
<input type="number" class="reqField" id="number4" placeholder="Enter Number only"></input>
<div id="submitbtn" class="SubmitBtn">Submit</div>
After breaking my head and console.log on all the statement to figure out the flow of code, I was able to find that on $("#submitbtn").click() there is some .focusout() is called.
As these .focusout() were necessary for on the go validation on the <input> fields, i tried to add $.(":focus").blur() and it worked along with adding a return false; on placeCursor() function.
The $.(":focus").blur() removes focus from any currently focused element. And this is a live saver for our logic of code.
So the code looks like
$("#submitbtn").mouseover(function(e) {
console.log("Hover");
$.(":focus").blur();
removeTimeouts();
$("#submitbtn").focus();
e.preventDefault();
e.stopPropagation();
e.cancelBubble = true;
});
....
function placeCursor(id) {
id.focus(function(e) {
e.stopPropagation();
//e.cancelBubble();
id.caretToEnd();
});
id.focus();
return false;
}
Hope this helps someone someday.
Thank you!

JavaScript clearTimeout not firing correctly

I have a submit function on a textbox with JavaScript. When the script fires, it checks a Kendo grid for a certain article and adds +1 to its quantity as well as opening the corresponding cell in editing mode. What I want to achieve is that on every submit the timer that starts grid.editCell() will reset its timer.
Currently, the event fires properly. However, the timer doesn't get reset, although the clearTimeout() does work if I just simply start the timer and then clear it right afterwards.
JavaScript:
$('#txtBarcode').submit(function (e) {
var grid = $("#PickListDetailGrid").data("kendoGrid");
var dataSource = $("#PickListDetailGrid").data("kendoGrid").dataSource;
var allData = grid.dataSource.data();
var code = this.value;
var notification = $("#notification").data("kendoNotification");
var timer = null;
clearTimeout(timer);
$.each(allData, function (index, item) {
if (item.ArticleID == code) {
clearTimeout(timer);
timer = null;
if (item.Quantity > item.PickedQuantity && item.PickedQuantity.toString().length < 4) {
var edit = function () {
if (item.PickedQuantity != item.Quantity && timer != null) {
grid.select("tr:eq(" + (index) + ")");
grid.editCell("tr:eq(" + (index + 1) + ") td:eq(" + (5) + ")");
} else {
//do nothing
}
}
item.PickedQuantity++;
item.dirty = true;
dataSource.sync();
if (item.PickedQuantity != item.Quantity) {
console.log("tik tok");
if (timer) {
clearTimeout(timer); //cancel the previous timer.
timer = null;
}
timer = setTimeout(edit, 3000);
} else {
clearTimeout(timer);
timer = null;
}
document.getElementById("txtBarcode").value = "";
} else {
if (item.PickedQuantity.toString().length > 4) {
notification.hide();
notification.show({
message: "Added item"
}, "upload-success");
} else {
notification.hide();
notification.show({
title: "Quantity Error",
message: "You already picked this item to the maximum"
}, "error");
document.getElementById("txtBarcode").value = "";
grid.select("tr:eq(" + (index) + ")");
grid.editCell("tr:eq(" + (index + 1) + ") td:eq(" + (5) + ")");
$('.focus :input').focus();
}
}
}
})
})
You can try delay function like this. The delay function should be outside of the each function.
var delay = (function() {
var timer = 0;
return function(callback, ms) {
clearTimeout(timer);
timer = setTimeout(callback, ms);
};
})();
delay(function() {
//do something
}, 3000);
The problem was that var timer = null; had to be outside of the submit function to be properly cleared and set to null before assigning a new setTimeout() to it.

How can I get div to move up and down on hover? Mouseover and Mouseout conflict

I am trying to use run an animation using setInterval which works quiet well. Although I am trying to get the animation to run all the way through and then stop after mouse out.
I can get the div to move up and down but if you move the mouse in and out too fast it get's stuck in a loop of adding and subtracting pixels. Or other times it will stop moving altogether and get stuck at the top of bottom.
You can see the issue here, move the mouse in and out of the small box a few times fast.
https://jsfiddle.net/L16fdbrj/1/
Here is my Javascript:
var blog_folder_index = false;
var blog_folder_pos = 0;
var blog_folder_interval;
var framespeed = 5;
function blog_folder_mouseover()
{
if (blog_folder_index == false)
{
document.getElementById("blog_folder_button").style.cursor = "pointer";
blog_folder_interval = setInterval(function (){ blog_folder_add();}, 35);
}
}
function blog_folder_mouseout()
{
blog_folder_interval = setInterval(function (){ blog_folder_subtract();}, 50);
console.log("mouseout");
}
function blog_folder_add()
{
if (blog_folder_pos <= -30)
{
console.log(blog_folder_pos);
stop_function();
}
else if (blog_folder_pos > -30)
{
blog_folder_pos -= framespeed;
document.getElementById("blog_folder").style.marginTop = blog_folder_pos + 'px ';
}
}
function blog_folder_subtract()
{
if (blog_folder_pos >= 0)
{
console.log(blog_folder_pos);
stop_function();
}
else if (blog_folder_pos < 0)
{
blog_folder_pos += framespeed;
document.getElementById("blog_folder").style.marginTop = blog_folder_pos + 'px ';
}
}
function blog_folder_click()
{
blog_folder_index = true;
portfolio_folder_index = false;
about_folder_index = false;
document.getElementById("blog_folder_button").style.cursor = "default";
document.getElementById("portfolio_folder").style.zIndex = "2";
document.getElementById("blog_folder").style.zIndex = "3";
document.getElementById("about_folder").style.zIndex = "1";
blog_folder_interval = setInterval(function (){ blog_folder_subtract();}, 35);
}
function stop_function()
{
clearInterval(blog_folder_interval);
}
You simply need to clear your previous interval before creating a new one:
https://jsfiddle.net/L16fdbrj/2/
function blog_folder_mouseover() {
if (blog_folder_index == false) {
document.getElementById("blog_folder_button").style.cursor = "pointer";
// clear previous interval
stop_function();
blog_folder_interval = setInterval(function () {
blog_folder_add();
}, 35);
}
}
function blog_folder_mouseout() {
// clear previous interval
stop_function();
blog_folder_interval = setInterval(function () {
blog_folder_subtract();
}, 50);
console.log("mouseout");
}

How to make a button disable automatically?

I'm trying to code a button - each time you click it, it disables for 3 seconds...but for some reason, it waits a second then disables it. How would you make it so that it disables automatically? This is some of my code so far:
function countdown() {
setTimeout(function () {
document.getElementById('btnOne').disabled = null;
}, 4000);
var countdownNum = 4
incTimer();
function incTimer() {
setTimeout(function () {
if (countdownNum != 1) {
countdownNum--;
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
incTimer();
document.getElementById('btnOne').disabled = true;
} else {
document.getElementById('timeLeft').innerHTML = '';
document.getElementById('btnOne').disabled = false;
}
}, 1000);
}
}
This works for me
<span id="timeLeft"></span>
<input type="submit" id="btnOne" onClick="countdown()">
function countdown() {
document.getElementById('btnOne').disabled = true;
var countdownNum = 3
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
incTimer();
function incTimer() {
setTimeout(function () {
if (countdownNum != 1) {
countdownNum--;
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
incTimer();
document.getElementById('btnOne').disabled = true;
} else {
document.getElementById('timeLeft').innerHTML = '';
document.getElementById('btnOne').disabled = false;
}
}, 1000);
}
}
I believe this code does the things you need.
<script type="text/javascript">
function fclick(){
document.getElementById('myButton').disabled = true;
setTimeout('countDown(3);', 1000);
}
function countDown(i){
if (i >= 0)
{
document.getElementById('myButton').value = 'Click again in ' + i + ' secs';
i--;
setTimeout('countDown('+i+');', 1000);
}
else
{
document.getElementById('myButton').value = 'Click me';
document.getElementById('myButton').disabled = false;
}
}
</script>
<input type="button" value="Click me" id="myButton" onclick="fclick()">
You are setting a timeout that says "after 1 second, do X".
Your current timeout is actually pretty hard to follow, but it broadly does this in a very tangled way:
Make counter = 4
Wait 1 second.
If counter != 1, subtract 1 from the counter, disable button, and go back to 2. Continue otherwise.
Enable button.
As you can see, you are disabling the button AFTER waiting 1 second, not immediately.
I would suggest changing your countdown() method as follows:
Disable button.
Make counter = 3
If counter > 0, Print "Click again in counter seconds", Subtract 1 from counter, Wait 1 second and go back to 2. Continue Otherwise.
Enable button.
That could look like this: (using your code)
--- Working Example Here!!! ---
function countdown() {
document.getElementById('btnOne').disabled = true;
//3 is more understandable than 4 for your example.
var countdownNum = 3;
incTimer();
function incTimer() {
if (countdownNum > 0) {
// Order of statements IS important.
// Note the differences in this IF block.
document.getElementById('timeLeft').innerHTML = 'Click again in ' + countdownNum;
countdownNum--;
setTimeout(function(){
// Note that the whole timeout was moved inside,
// Imagine this is recursive function, with a delay.
incTimer();
}, 1000);
} else {
document.getElementById('timeLeft').innerHTML = '';
document.getElementById('btnOne').disabled = false;
}
}
}
There are better ways to express your code, but I tried to stick as much as possible to your code style.

How would I toggle the state of a setInterval function in jQuery?

I want to be able to click a an element with an id of pause to start a count of the elements in a time object and if I re click the pause it will stop it and reclick start it exactly like the toggle feature in JQuery but with a setInteval function how would I go about doing this?
$("#pause").click(function(ffe) {
if(on == true) {
on = false
alert("on");
}
else {
on = true;
alert("off");
}
if(on == false) {
setInterval(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
}
else {
alert("Error");
}
});
A classic technique is to use a single master setInterval loop and simply use if..else logic to determine what needs to run. This is how a lot of javascript games work:
var on = true;
// Our master scheduler:
setInterval(function() {
if (on) {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}
}, 100);
// Code to handle the pause button
$("#pause").click(function(ffe) {
on = !on;
}
You can use the setTimeout function, if you want to run the function once, setInterval runs continuously, try the following:
var on = false;
$("#pause").click(function(ffe) {
if (on) {
on = false;
setTimeout(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
} else {
on = true;
}
});
You need to use .clearInterval() to stop the execution.
Here is the code: (THE WORKING DEMO)
$("#pause").click((function () {
var interId = null;
var $ul = $("#timet ul");
return function (e) {
if (interId) {
$(this).text("start");
clearInterval(interId);
interId = null;
} else {
$(this).text("pause");
interId = setInterval(function () {
$ul.append($('<li>').text($('li', $ul).length));
}, 100);
}
};
}()));​

Categories

Resources