Optimizing long on click event - javascript

I have the following code which changes the text in a certain element on click depending on the text value present in the element at the time the event is fired.
http://jsfiddle.net/TNDhL/
$('#left').on('click', function (){
if ($("#textContainer:contains('something')").length) {
$('#textContainer').text('third text replacement');
$('.elsewhere').text('more here');
}
else if ($("#textContainer:contains('third text replacement')").length) {
$('#textContainer').text('now the next item');
$('.elsewhere').text('something new here');
}
else if ($("#textContainer:contains('now the next item')").length) {
$('#textContainer').text('new text here');
$('.elsewhere').text('something else here');
}
else if ($("#textContainer:contains('new text here')").length) {
$('#textContainer').text('something');
$('.elsewhere').text('text here');
}
});
$('#right').on('click', function (){
if ($("#textContainer:contains('something')").length) {
$('#textContainer').text('new text here');
$('.elsewhere').text('something else here');
}
else if ($("#textContainer:contains('new text here')").length) {
$('#textContainer').text('now the next item');
$('.elsewhere').text('something new here');
}
else if ($("#textContainer:contains('now the next item')").length) {
$('#textContainer').text('third text replacement');
$('.elsewhere').text('more here');
}
else if ($("#textContainer:contains('third text replacement')").length) {
$('#textContainer').text('something');
$('.elsewhere').text('text here');
}
});
Please see fiddle above for working version.
I'd like to find a way to make this more manageable in order to make extending this further easier. Is there a better way to handle this case? Condensing this into a function and using variables to store the value of #textContainer would be more ideal. Any suggestions?

Seems like a perfect case for a closure which can track your progress with a simple counter.. Could look something like this:
var myTextRotator = (function () {
var myPhraseArray = ["first phrase", "second phrase"],
counter = 0;
return {
clickLeft: function () {
counter -= 1;
return myPhraseArray[counter]; //return array item or do your processing here
},
clickRight: function () {
counter += 1;
return myPhraseArray[counter]; //return array item or do your processing here
}
};
}());
Tie the clickLeft and clickRight methods to an jQuery .on(). May have to add a conditional in there so the counter doesn't go below 0 or above the array length.
You would use this like:
$(".left").on("click", function () {
myTextRotator.clickLeft();
});
$(".right").on("click", function () {
myTextRotator.clickRight();
});

Related

SetInterval does not work when it is in another function?

When I put setInterval(autoAdmit, 1000) just below the autoAdmit() function, it works but when I place it in the if statements of another function, it does not work. Any ideas on why this is happening? I can't find anything that's wrong with it. forgot to mention: the part not working is the autoAdmit() function. When I put a console.log in the function, it still logs but what is inside the for loop is not executed for some reason.
let clickIntervalId = null;
function autoAdmit() {
for (let element of document.getElementsByTagName('span')) {
if (element.innerHTML === 'Admit') {
console.log('There is someone waiting to join this meeting, automatically admitting them...');
element.click();
}
}
}
//setInterval(autoAdmit, 1000) (if it is placed here it works)
document.addEventListener('DOMContentLoaded', function() {
var checkbox = document.querySelector('#auto-admit .mdc-switch__native-control');
function isChecked() {
if (checkbox.checked ) {
// do this
if(clickIntervalId) clearInterval(clickIntervalId);
clickIntervalId = setInterval(autoAdmit, 1000); //(if it is placed here, it doesn't work)
console.log('checked')
} else {
// do that
clearInterval(clickIntervalId);
console.log('not')
}
}
checkbox.addEventListener('change', function() {
isChecked();
});
function check() {
isChecked();
}
setTimeout(check, 2000)
}
);

Why does my second if statement run 2 times in a row after my first if statement is true?

Hello guys I have a problem with my checkRight() function.
I tried to build a quiz webpage with js.
Here is my complete code: https://www.codeply.com/go/qoCnPUDDxG
My questions consists of a class with: question (string), answers(array of strings) and answer (string) attributes.
If I click on the right answers my counters go very confusing up.
function checkRight (){
$(".answer").click(function() {
check = $(this).html();
if(check===qAry[i].rightAnswer){
rightCounter++;
$(".richtigZaehler").text(rightCounter);
i++;
askQ();
}
else if(check!=qAry[i].rightAnswer){
console.log("Update");
wrongCounter++;
$(".falschZaehler").text(wrongCounter);
}
});
}
How about adding the click handler outside? Otherwise you will need to unregister them.
var rightCounter=0; //counter for rightAnswer
var wrongCounter=0; //counter for wronganswer
$(".answer").on("click", function() {
checkRight(this);
})
Then in your checkRight function:
function checkRight (evt){
check = $(evt).html();
if(check===qAry[i].rightAnswer){
debugger;
rightCounter++;
$(".richtigZaehler").text(rightCounter);
i++;
askQ();
}
else if(check!=qAry[i].rightAnswer){
console.log("Update");
wrongCounter++;
$(".falschZaehler").text(wrongCounter);
}
}

Function never calls the second function

I have this javascript code
function editRerenderFix() {
console.log("edit render start");
textAreaFix();
console.log("edit render middle");
setupDates();
console.log("edit render end");
}
/** Function to auto expand out the text area to hold all content **/
function textAreaFix() {
jQuery('textarea').on( 'change keyup keydown paste cut', function (event){
jQuery(this).height(100);
jQuery('textarea').each(function() {
jQuery(this).height(jQuery(this).prop('scrollHeight'));
});
});
return null;
}
/** Function to fix and set the custom date/time picker **/
function setupDates() {
jQuery('.dateFormat').remove();
var inputs = jQuery('.inputDate');
jQuery(inputs).each(function() {
var input = jQuery(this).val().split('/')[2];
if(input.length > 4) {
input = input.split(" ")[0];
}
if(input < '2015') {
jQuery(this).val("");
}
});
console.log("Setup Dates function ran");
jQuery('.inputDate').datetimepicker();
}
This function is called using the onComplete ajax method. The problem is that when it runs only textAreaFix() is called. In the console only "edit render start" and "edit render middle" show up.
The reason that "Setup Date function ran" first is because I have this function,
jQuery(document).ready(function() {
jQuery.material.init();
textAreaFix();
setupDates();
tourStep();
easterEgg();
});
How can I get the setupDates() function called?
EDIT:
I added more debugging to setupDates(),
/** Function to fix and set the custom date/time picker **/
function setupDates() {
jQuery('.dateFormat').remove();
var inputs = jQuery('.inputDate');
console.log(inputs);
jQuery(inputs).each(function() {
var input = jQuery(this).val().split('/')[2];
console.log(input);
if(input.length > 4) {
console.log("Input > 4");
input = input.split(" ")[0];
console.log(input);
}
if(input < '2015') {
console.log("Fix 2015 dates");
jQuery(this).val("");
}
});
console.log("Setup Dates function ran");
jQuery('.inputDate').datetimepicker();
}
When I run this I get,
I am not sure where the "undefined" comes from though.
My guess is that it is displaying undefined because the loop is repeating and jQuery(this).val().split('/')[2] is causing a problem. Maybe console.log on this and this.val() right at the beginning of the loop's block? – James Nearn 30 mins ago

not .isAfter jQuery Ajax

I am trying to show separate messages if a div exists after a certain div or does not exist based the end of an ajax function
Here is the code I came up with:
.ajaxComplete(function() {
// Pilots page code.
if ($('body').hasClass('page-pilots')) {
$.fn.isAfter = function(sel) {
return this.prevAll(sel).length !== 0;
}
$('#quicktabs-tabpage-107_display-0 .view-content').each(function() {
if ($(this).isAfter("#quicktabs-tabpage-107_display-0 .view-filters")) {
console.log(".view-content is after, hide message");
$('.pilots-result-message').hide();
}
if (!$(this).isAfter("#quicktabs-tabpage-107_display-0 .view-filters")) {
console.log(".view-content is not after, show message");
$('.pilots-result-message').show();
}
});
}
});
The isafter is working, but I can't figure out how to implement a function which is the opposite (would be nice if there was a isNotAfter jQuery function).
I have also tried instead of the second if statement:
else {
console.log(".view-content is not after, show message");
$('.pilots-result-message').show();
}
There is no method called isAfter(), you can check whether the next element of #quicktabs-tabpage-107_display-0 .view-filters is the current(this) element like
if ($('body').hasClass('page-pilots')) {
$.fn.isAfter = function (sel) {
return this.prevAll(sel).length !== 0;
}
$('#quicktabs-tabpage-107_display-0 .view-content').each(function () {
if ($("#quicktabs-tabpage-107_display-0 .view-filters").next().is(this)) {
console.log(".view-content is after, hide message");
$('.pilots-result-message').hide();
} else {
console.log(".view-content is not after, show message");
$('.pilots-result-message').show();
}
});
}

How can I stop/pause a function from another function?

I have a simple jquery-ui slider which I am continuously automatically looping through values. I successfully have a button which starts the movement, but I forget how I can pause/stop the movement when another button is pressed? I know this is something really simple, but am having an absolute mind blank and google is not giving me what I want. (probably because i'm searching for the wrong wording). What can do I put in the pauseSlider function to ... pause the slider!
function scrollSlider() {
var slideValue;
slideValue = $("#slider").slider("value");
if (slideValue >= 0) {
if (slideValue == 2013) {
slideValue = -1;
}
$("#slider").slider("value", slideValue + 1);
console.log($("#slider").slider("value"));
setTimeout(scrollSlider, 1000);
}
}
$('#startSlider').click(function() {
scrollSlider();
});
$('#pauseSlider').click(function() {
//What do I put in here?
});
setTimeout returns a random number which you'll have to store in a variable and then use it to clear the setTimeout in $('#pauseSlider')'s click handler.
var id;
function scrollSlider() {
// (...) code
id = setTimeout(scrollSlider, 1000);
// (...) more code
}
$('#pauseSlider').click(function() {
clearTimeout(id);
});

Categories