Quick question as I'm drawing a blank, if I have an event listener that contains 2 if statements that on first time round are both true but I don't want both of them to execute how do I prevent this? Can I break on the first conditional or something like that?
JS
var input = document.querySelector('.js-input'),
output = document.querySelector('.js-output');
input.addEventListener('keydown', function (event) {
if (this.value.length === 0) {
console.log('run this once');
}
if (this.value === '') {
console.log('this is empty so show hint')
}
});
var input = document.querySelector('.js-input'),
output = document.querySelector('.js-output');
var firstTimeCallbackRun= true;
input.addEventListener('keydown', function (event) {
if (this.value.length === 0) {
console.log('run this once');
if(firstTimeCallbackRun) {
firstTimeCallbackRun = false;
return;
}
}
if (this.value === '') {
console.log('this is empty so show hint')
}
});
var input = document.querySelector('.js-input'),
output = document.querySelector('.js-output'),
isFirst = true;
input.addEventListener('keydown', function (event) {
if (isFirst) {
isFirst = false;
return;
}
if (this.value.length === 0) {
console.log('run this once');
}
if (this.value === '') {
console.log('this is empty so show hint')
}
});
Maybe something like that? But probably you should ask yourself why this is happening and what are you doing wrong. Since it is a hacky and not optimal solution.
(function() {
var firstRun = true;
var input = document.querySelector('.js-input');
var output = document.querySelector('.js-output');
input.addEventListener('keydown', function (event) {
if (firstRun) {
firstRun = false;
if (this.value.length === 0) {
console.log('run this once');
}
} else {
if (this.value === '') {
console.log('this is empty so show hint')
}
}
});
})();
Here an example of how you could achieve this:
(function() {
var input = document.querySelector('.js-input');
var isDirty = function(element) {
if ( ! element.data) {
element.data = {isDirty: false};
}
if (element.value.length > 0 && ! element.data.isDirty) {
element.data.isDirty = true;
} else if (element.value.length === 0) {
element.data.isDirty = false;
}
return element.data.isDirty;
};
input.addEventListener('keyup', function (event) {
var dirtyClass = " is-dirty";
if (isDirty(this)) {
if (this.className.search(dirtyClass) === -1) {
this.className += dirtyClass;
}
} else {
this.className = this.className.replace(dirtyClass, "");
}
});
})();
Related
My knowledge is limited, so I'm just praying y'all will enlighten me who knows bare minimum of JS. I want to bypass a timer that makes it unable to go to the next page (I need 35s every single time and that's a lot considering some lessons have over 200 slides). How do I write a script for tampermonkey to make it show the link to the next page instantly?
// Obsługa przycisku Dalej
function goNext(vIsExam) {
// Przycisk nieaktywny - blokada przejścia
if (document.getElementById("pNext").rel != 'enabled') return false;
if (vIsExam==1) {
} else {
location.href='../sql/MemSql.php?pRun=MemCourseGoNext&pCourseResultId=262261&pCourseLessonId=227436';
}
} // function
// Aktywacja przycisku Dalej
function waitNextLesson(vTimeLeft, vTimer) {
setCookie('cLessonTime',vTimeLeft);
if (vTimeLeft > 0) {
document.getElementById('pNext').rel = 'disabled';
document.getElementById('pNextDiv').className = 'CourseInactive';
if (vTimer == 0) {
document.getElementById('pNextIcon').className = 'FontAwesome';
document.getElementById('pNextIcon').innerHTML = vTimeLeft;
} else {
document.getElementById('pNextIcon').className = 'FontAwesome';
document.getElementById('pNextIcon').className = 'FontAwesome FontAwesomeArrowRight';
}
document.getElementById('pNextName').innerHTML = 'CZEKAJ';
vTimeLeft = vTimeLeft - 1;
setTimeout("waitNextLesson("+vTimeLeft+","+vTimer+")",1000);
} else {
document.getElementById('pNext').rel = 'enabled';
document.getElementById('pNextDiv').className = '';
document.getElementById('pNextIcon').className = 'FontAwesome FontAwesomeArrowRight';
document.getElementById('pNextIcon').innerHTML = '';
document.getElementById('pNextName').innerHTML = 'NASTĘPNY SLAJD';
if (document.getElementById('iLessonAutoPlay').checked == true) document.getElementById('pNext').click();
}
} // function
// Obsługa LessonAutoPlay
function jLessonAutoPlay(e) {
setCookie('LessonAutoPlay', document.getElementById('iLessonAutoPlay').checked);
jStopPropagation(e);
} // function
//if (getCookie('LessonAutoPlay') == 'true') document.getElementById('iLessonAutoPlay').checked = true;
// Obsługa skrótów klawiaturowych (strzałka [<] i [>])
$("body").keyup(function(oEvent){
// Sprawdzenie czy można obsługiwać skróty
if (document.getElementById('DIALOG').style.display == 'none' && document.getElementById('LOADER').style.display == 'none') {
// Klawisz [<]
if (oEvent.keyCode == 37) {
document.getElementById("pPrev").click();
}
// Klawisz [>]
if (oEvent.keyCode == 39) {
if (document.getElementById("pNext").rel == 'enabled') {
document.getElementById("pNext").click();
}
}
}
});
I have some problem when I check the function validation, I need when checking all the cassis is true hide the parent div * errors message *
var error_pass = false;
$('#pass').focusout(function(){
check_pass();
error_pass = false;
if(error_pass !== true){
console.log('its showing!');
}else{
$('.test').fadeOut('522');
}
});
function check_pass() {
var fpass= $('#pass').val();
switch(error_pass = true){
case(fpass.length < 6 ? $('#pass-error-message3').css('color','red'):$('#pass-error-message3').css('color','green') ):
$('#pass-error-message3').show();
case(fpass.search(/(?=.[a-z])(?=.*[A-Z])/) == -1 ? $('#pass-error-message4').css('color','red') : $('#pass-error-message4').css('color','green')):
$('#pass-error-message4').show();
case(fpass.search(/\d/) == -1 ? $('#pass-error-message2').css('color','red'):$('#pass-error-message2').css('color','green')):
$('#pass-error-message2').show();
default:break;
}
}
Use if else statements like this
function validation() {
var error = false;
if (fpass.length < 6) {
error = true;
$('#pass-error-message3').css('color', 'red').show();
} else {
$('#pass-error-message3').css('color', 'green');
}
if (fpass.search(/(?=.[a-z])(?=.*[A-Z])/) == -1) {
error = true;
$('#pass-error-message4').css('color', 'red').show();
} else {
$('#pass-error-message4').css('color', 'green')
}
if(fpass.search(/\d/) == -1){
error = true;
$('#pass-error-message2').css('color','red').show();
}else{
$('#pass-error-message2').css('color','green');
}
if(error === false){
hideParentDiv(); // Here hide the div
}
}
Much cleaner approach
I'm new to web programming, and I'm trying to complete a simple guessing game project.
Right now I'm stuck because I'm trying to update an unordered list with the player's past guesses, but the page does not update.
Here is my jQuery code:
$(document).ready(function() {
game = new Game;
var guessNum
onSubmit = function(event){
event.preventDefault();
var input = $('#player-input');
var guess = +input.val();
input.val('');
var result = game.playersGuessSubmission(guess);
if (result == 'You have already guessed that number.') {
$('#title').text(result);
} else if (result === 'You Win!' || result === 'You lose.') {
$('#title').text(result);
$('#subtitle').text('Press the reset button to play again.')
$('#hint').prop('disabled', true)
$('#submit').prop('disabled', true)
} else { //this is the relevant portion
guessNum = (game.pastGuesses.length - 1).toString();
$('#' + guessNum).text(guessNum);
}
};
$('#submit').on('click', function(e){
onSubmit(e);
});
$('#player-input').on('keypress', function(e) {
if(e.which == 13) {
e.preventDefault();
onSubmit(e);
};
});
});
Here is the unordered list's html:
<div id='guesses'>
<!-- unordered list of guesses -->
<ul id='past-guesses' class="list-inline center">
<li id='0' class="guess list-group-item ">-</li>
<li id='1'class="guess list-group-item">-</li>
<li id='2' class="guess list-group-item">-</li>
<li id='3' class="guess list-group-item">-</li>
<li id='4' class="guess list-group-item">-</li>
</ul>
</div>
I have also tried not using the identifiers in the html, and instead selecting the li elements this way:
var idStr = "#past-guesses:eq(" + guessNum + ")"
$(idStr).text(game.playersGuess.toString());
In either case, the page does not update with the new values in the unordered list displayed. What am I doing wrong?
EDIT
In response to the request in comments, here's my entire JS file (now slightly edited because I was experimenting with changing the list id's to not begin with a number):
function generateWinningNumber() {
num = Math.random()
if (num === 0) {
return 1;
} else {
roundNum = Math.floor(num*100);
return roundNum + 1;
}
}
function shuffle(array) {
var m = array.length, t, i;
// While there remain elements to shuffle…
while (m) {
// Pick a remaining element…
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
function Game(){
this.winningNumber = generateWinningNumber();
this.playersGuess = null;
this.pastGuesses = [];
}
Game.prototype.difference = function() {
return Math.abs(this.playersGuess - this.winningNumber);
}
Game.prototype.isLower = function() {
if (this.playersGuess < this.winningNumber) {
return true;
} else {
return false;
}
}
Game.prototype.checkGuess = function() {
if (this.playersGuess === this.winningNumber) {
return "You Win!";
}
if (this.pastGuesses.indexOf(this.playersGuess) > -1) {
return "You have already guessed that number.";
}
this.pastGuesses.push(this.playersGuess);
if (this.pastGuesses.length >= 5) {
return "You Lose.";
} else if (this.difference() < 10) {
return "You're burning up!";
} else if (this.difference() < 25) {
return "You're lukewarm.";
} else if (this.difference() < 50) {
return "You're a bit chilly.";
} else {
return "You're ice cold!";
}
}
Game.prototype.playersGuessSubmission = function(num) {
if (num < 1 || num > 100 || typeof num != 'number') {
throw "That is an invalid guess."
} else {
this.playersGuess = num;
return this.checkGuess();
}
}
Game.prototype.provideHint = function() {
return shuffle([generateWinningNumber(), generateWinningNumber(), this.winningNumber]);
}
newGame = function() {
game = new Game;
return game;
}
$(document).ready(function() {
var game = new Game;
var guessNum
onSubmit = function(event){
event.preventDefault();
var input = $('#player-input');
var guess = +input.val();
input.val('');
var result = game.playersGuessSubmission(guess);
if (result == 'You have already guessed that number.') {
$('#title').text(result);
} else if (result === 'You Win!' || result === 'You lose.') {
$('#title').text(result);
$('#subtitle').text('Press the reset button to play again.')
$('#hint').prop('disabled', true)
$('#submit').prop('disabled', true)
} else {
guessNum = (game.pastGuesses.length - 1).toString();
$('#l' + guessNum).text(guessNum);
}
};
$('#submit').on('click', function(e){
onSubmit(e);
});
$('#player-input').on('keypress', function(e) {
if(e.which == 13) {
e.preventDefault();
onSubmit(e);
};
});
});
});
You need to escape the CSS selector.
try to replace this line:
$('#' + guessNum).text(guessNum);
with this:
var selector = "#\\" + guessNum.toString().charCodeAt(0).toString(16) + " " + guessNum.toString().substr(1);
$(selector).text(guessNum);
you can read more at:
https://www.w3.org/International/questions/qa-escapes
I am looking to make a checkbox that when unchecked, will turn off a certain function in a .js file. Can someone help me?
popup.html
HTML Check box:
content.js
Turn off this function:
var tweet = new Array();
var tweetName = new Array();
function linkSnipe() {
for (var i = 0; i < 5; i++) {
tweetName[i] = document.getElementsByClassName("fullname js-action-profile-name show-popup-with-id")[0].innerHTML;
tweet[i] = document.getElementsByClassName("js-tweet-text")[i].innerHTML;
}
if (tweet[0].match(shoeName) == shoeName && tweet[0].match(filterer) != filterer && tweet[0].match(filter2) != filter2) {
if(checkon == "Tweets"){
document.getElementsByClassName("twitter-timeline-link")[0].click();
update();
}
}
else if (tweet[1].match(shoeName) == shoeName && tweet[1].match(filterer) != filterer && tweet[1].match(filter2) != filter2) {
if(checkon == "Tweets"){
document.getElementsByClassName("twitter-timeline-link")[1].click();
update();
}
}
else if (tweet[2].match(shoeName) == shoeName && tweet[2].match(filterer) != filterer && tweet[2].match(filter2) != filter2) {
if(checkon == "Tweets"){
document.getElementsByClassName("twitter-timeline-link")[2].click();
update();
}
}
else if (tweet[3].match(shoeName) == shoeName && tweet[3].match(filterer) != filterer && tweet[3].match(filter2) != filter2) {
if(checkon == "Tweets"){
document.getElementsByClassName("twitter-timeline-link")[3].click();
update();
}
}
else if (tweet[4].match(shoeName) == shoeName && tweet[4].match(filterer) != filterer && tweet[4].match(filter2) != filter2) {
if(checkon == "Tweets"){
document.getElementsByClassName("twitter-timeline-link")[4].click();
update();
}
}
else if(checkon == "Tweets") {
location.reload();
}
}
setTimeout("linkSnipe()", 250);
}
When the checkbox is checked, redefine the function as:
<input type=checkbox ..... onchange="doit()">
function doit() {
window.linkSnipe=function() {}
}
I've used this too:
function doit() {
window['linkSnipe']=function() {}
}
If you want to turn the function on and off by the checkbox:
<input type=checkbox ..... onchange="doit(this)">
var linkSnipeSave = linkSnipe;
function doit(ck) {
if (ck.checked)
window['linkSnipe']=linkSnipeSave
else {
linkSnipeSave = linkSnipe; //not sure if this line is needed...pls test
window['linkSnipe']=function() {}
}
}
You could simply have a Boolean variable that changes with the state of your check box. You could then put an if statement around the function call that will only trigger if the checkbox is checked.
http://jsfiddle.net/W5P8X/
//initialize some variables.
bike_checked = false;
car_checked = false;
//get elements by their ID from html
bike = document.getElementById("bike");
car = document.getElementById("car");
//add event listeners to the html elements we found above
bike.addEventListener("click", toggle_bike, false);
car.addEventListener("click", toggle_car, false);
//toggle bike_checked variable on click
function toggle_bike(){
if(bike_checked == true)
bike_checked = false;
else
bike_checked=true;
current_state();
}
//toggle car_checked variable on click
function toggle_car(){
if(car_checked == true)
car_checked = false;
else
car_checked=true;
current_state();
}
//output current state.
function current_state(){
if(car_checked == true)
alert('Car checked');
if(bike_checked == true)
alert('Bike checked');
}
I answered with only javascript and no jQuery, but you could probably make it a bit more concise with jQuery.
I hope this helps.
I tried making a jsFiddle for this, but it's not working right (I think because of the alerts I have set up to test my code), so hopefully someone can simply look at my JS and see the problem.
The issue is that when you close the div with the form (#verizoni516) and then re-open it, you get as many alerts as times you have closed the div and re-opened it, instead of the ONE alert I'm intending. Does that make any sense?
Here's the JS:
/*--------------Validation Functions-------------------*/
function chkradio() {
var elem = document.forms['vzi5'].elements['element_0'];
len = elem.length - 1;
chkvalue = '';
sevenPlus = false;
fourToSix = false;
threeMin = false;
for (i = 0; i <= len; i++) {
if(elem[i].checked) chkvalue = elem[i].value;
}
if (chkvalue == '') {
$('#radio-error').fadeIn('fast').effect("bounce", {times:3}, 'fast', function(){
setTimeout(function(){
$('#radio-error').fadeOut('slow');}, 2000);
});
}
if (chkvalue >= 7) {
sevenPlus = true;
} else if (chkvalue >= 4 && chkvalue <= 6) {
fourToSix = true;
} else {
threeMin = true;
}
};
function chkselect() {
var elem = document.forms['vzi5'].elements['element_1'];
len = elem.length - 1;
chkvalue = '';
likeNew = false;
minProb = false;
nonFunc = false;
for (i = 0; i <= len; i++) {
if (elem[i].selected) chkvalue = elem[i].value;
}
if (chkvalue == '') {
elem.focus();
$('#select-error').fadeIn('fast').effect("bounce", {times:3}, 'fast', function(){
setTimeout(function(){
$('#select-error').fadeOut('slow');}, 2000);
});
} else if (chkvalue === 'Like New - No Functional Problems') {
likeNew = true;
} else if (chkvalue === 'Minor Functional Problems') {
minProb = true;
} else {
nonFunc = true;
}
};
function chkbox() {
var elem = document.forms['vzi5'].elements['element_2[]'];
chkvalue = elem.checked;
iUnderstand = true;
if (chkvalue === true) {
iUnderstand;
} else {
iUnderstand = false;
elem.focus();
$('#check-error').fadeIn('fast').effect("bounce", {times:3}, 'fast', function(){
setTimeout(function(){
$('#check-error').fadeOut('slow');}, 2000);
});
}
};
//Calling the validation functions---------------------------
$('#verizon img.apple, #unlocked img.apple').click(function(){
$(this).closest('div').fadeOut(500).animate({"top": "-414px"}, 100).fadeIn('fast', function(){
});
$('#verizon516').animate({"top": "+=557px"}, 500, function(){
$(this).animate({"top": "-=20px"}, 200);
});
$('div.next').click(function(){
chkradio();
chkselect();
chkbox();
if (sevenPlus === true) {
if (likeNew === true && iUnderstand === true) {
alert('Condition is 7+ and functions like new.');
} else if (minProb === true && iUnderstand === true) {
alert('Condition is 7+ and has minor functional problems');
} else if (nonFunc === true && iUnderstand === true) {
alert('Condition is 7+ and device does NOT function.');
} else {
};
};
if (fourToSix === true) {
if (likeNew === true && iUnderstand === true) {
alert('Condition is 4-6 and functions like new.');
} else if (minProb === true && iUnderstand === true) {
alert('Condition is 4-6 and has minor functional problems');
} else if (nonFunc === true && iUnderstand === true) {
alert('Condition is 4-6 and device does NOT function.');
} else {
};
};
if (threeMin === true) {
if (likeNew === true && iUnderstand === true) {
alert('Condition is 1-3 and functions like new.');
} else if (minProb === true && iUnderstand === true) {
alert('Condition is 1-3 and has minor functional problems');
} else if (nonFunc === true && iUnderstand === true) {
alert('Condition is 1-3 and device does NOT function.');
} else {
};
};
});
});
Move the div.next click handler out of the other click handler, it will cause a new handler to get registered every time you click on one of the #verizon img.apple, #unlocked img.apple elements which intern gets called one after another.
/*--------------Validation Functions-------------------*/
function chkradio() {
var elem = document.forms['vzi5'].elements['element_0'];
len = elem.length - 1;
chkvalue = '';
sevenPlus = false;
fourToSix = false;
threeMin = false;
for (i = 0; i <= len; i++) {
if (elem[i].checked) chkvalue = elem[i].value;
}
if (chkvalue == '') {
$('#radio-error').fadeIn('fast').effect("bounce", {
times: 3
}, 'fast', function () {
setTimeout(function () {
$('#radio-error').fadeOut('slow');
}, 2000);
});
}
if (chkvalue >= 7) {
sevenPlus = true;
} else if (chkvalue >= 4 && chkvalue <= 6) {
fourToSix = true;
} else {
threeMin = true;
}
};
function chkselect() {
var elem = document.forms['vzi5'].elements['element_1'];
len = elem.length - 1;
chkvalue = '';
likeNew = false;
minProb = false;
nonFunc = false;
for (i = 0; i <= len; i++) {
if (elem[i].selected) chkvalue = elem[i].value;
}
if (chkvalue == '') {
elem.focus();
$('#select-error').fadeIn('fast').effect("bounce", {
times: 3
}, 'fast', function () {
setTimeout(function () {
$('#select-error').fadeOut('slow');
}, 2000);
});
} else if (chkvalue === 'Like New - No Functional Problems') {
likeNew = true;
} else if (chkvalue === 'Minor Functional Problems') {
minProb = true;
} else {
nonFunc = true;
}
};
function chkbox() {
var elem = document.forms['vzi5'].elements['element_2[]'];
chkvalue = elem.checked;
iUnderstand = true;
if (chkvalue === true) {
iUnderstand;
} else {
iUnderstand = false;
elem.focus();
$('#check-error').fadeIn('fast').effect("bounce", {
times: 3
}, 'fast', function () {
setTimeout(function () {
$('#check-error').fadeOut('slow');
}, 2000);
});
}
};
//Calling the validation functions---------------------------
$('#verizon img.apple, #unlocked img.apple').click(function () {
$(this).closest('div').fadeOut(500).animate({
"top": "-414px"
}, 100).fadeIn('fast', function () {});
$('#verizon516').animate({
"top": "+=557px"
}, 500, function () {
$(this).animate({
"top": "-=20px"
}, 200);
});
});
//move this out of the other click handler
$('div.next').click(function () {
chkradio();
chkselect();
chkbox();
if (sevenPlus === true) {
if (likeNew === true && iUnderstand === true) {
alert('Condition is 7+ and functions like new.');
} else if (minProb === true && iUnderstand === true) {
alert('Condition is 7+ and has minor functional problems');
} else if (nonFunc === true && iUnderstand === true) {
alert('Condition is 7+ and device does NOT function.');
} else {
};
};
if (fourToSix === true) {
if (likeNew === true && iUnderstand === true) {
alert('Condition is 4-6 and functions like new.');
} else if (minProb === true && iUnderstand === true) {
alert('Condition is 4-6 and has minor functional problems');
} else if (nonFunc === true && iUnderstand === true) {
alert('Condition is 4-6 and device does NOT function.');
} else {
};
};
if (threeMin === true) {
if (likeNew === true && iUnderstand === true) {
alert('Condition is 1-3 and functions like new.');
} else if (minProb === true && iUnderstand === true) {
alert('Condition is 1-3 and has minor functional problems');
} else if (nonFunc === true && iUnderstand === true) {
alert('Condition is 1-3 and device does NOT function.');
} else {
};
};
});
Demo: Fiddle
This is because you are binding the click event for div.next inside the click event for #verizon img.apple, #unlocked img.apple, so every time the outer event is clicked, you are re-binding the inner click event. Fix this by moving the event binding for div.next outside the click event for #verizon img.apple, #unlocked img.apple
$('#verizon img.apple, #unlocked img.apple').click(function(){
// .. contents here
});
$('div.next').click(function(){
// ... contents here
});
You are binding the click event to $('div.next') every time $('#verizon img.apple, #unlocked img.apple') is clicked. Which means it will fire once for each time it is bound. Move the code for $('div.next') out of the $('#verizon img.apple, #unlocked img.apple') click handler.