Alright lets see if I can describe this.
I have a handful of functionality that was created sometime ago, and works swimmingly. However there is a new desired spec, so without having to rewrite the code base in a matter of speaking, and without having to double up on code to pull the same effect off I am trying to figure out how I can go about making something jump back higher in the code within the same function to repeat the run of the function rather then doing the same code again below.
What I have is a click based triggers ie:
$('.selector').click(function(){});
In this function is about 30 lines of functionality to create a new element and populate it accordingly. However unfortunately in that same bit of functionality there is conditions to wether it should or not.*The previous requirement was when the element it creates is open and populated just throw an alert() saying essentially wrap up what your doing, and then go on to the next. *Now the new requirement is just close that and open a new element. Which I've gotten to close out the existing, and do everything I want it to do, except the population of the new element which is above where the condition is currently. Knowing there is no "go to" type of logic in javascript (or last I knew). the only thing I can think of is taking the same code from above and putting it in the condition as well, doubling up on the code and having litterally 2 copies of the same bit. I want to avoid that, but cant think of a way to do it. So here I am looking for ideas
Knowing there is no "go to" type of logic in javascript (or last I
knew). the only thing I can think of is taking the same code from
above and putting it in the condition as well, doubling up on the code
and having litterally 2 copies of the same bit. I want to avoid that,
but cant think of a way to do it. So here I am looking for ideas
Why don't you just pull this piece of code out into a function? You can run the function if the conditional is true in the original instance, and run it all the time in your callback? This is fairly minimal refactoring, just move the code out of the logic into a separate function, keeping it as is and maybe making some of the referenced variables into parameters.
So something like this if you want to run all the actions regardless of the conditional statements:
...
if(condition){
actionA();
}
if(condition2){
actionB();
}
...
$('.selector').click(function(){
actionA();
actionB();
});
You're familiar with that pattern, right?
var aCallback = function(){........};
$('.selector').click(aCallback);
Related
I'm having a problem that seems very simple, but still I don't know how to solve it.
So, I have this tag in my HTML file:
<p id="best-individual-text" style="display: inline-block"></p>
For context, I'm building a simple genetic algorithm to evolve a population of individuals (strings) in order to reach a target phrase. In my .js file, I have a loop that creates the new population and finds the best individual of that population, and the loop only stops when one of the individuals is identical to the target phrase.
What I want to do is to update the best-individual-text text content with the string of the best individual in each generation. Since the while loop creates a new population in each iteration, there's going to be a new best individual at every iteration.
Inside this while loop, I have the following line of code:
document.getElementById("best-individual-text").textContent = getBestIndividual();
Note: getBestIndividual() returns a string
And here lies my problem: the HTML doesn't get updated. The tag remains blank until the loop stops, and only after that the tag is filled with the last best individual.
It works fine if I try this manually, that is, outside of the while loop. My only guess is that the while loop runs too fast for the HTML to be updated. Still, I think I've seen people update the HTML in a while loop, so I really don't understand the reason it is now working.
Also, I've tried making a setInterval instead of a while loop, but it still doesn't work. Even if it did work, it is not of my interest to have any sort of interval for each loop.
What could the problem be, and how can it be fixed?
Thank you in advance!
Here's the github in case anyone needs to see more of the code: https://github.com/pedroheck/genetic-algorithms/tree/main/Word%20Race
I tried out your code, and in the cases I hit where you enter some text, click "Submit", and nothing happens, what is actually happening is that your algorithm is in some sort of infinite, or long-running loop, and it never hits the point where you try to modify the HTML.
You can tell this by simply setting a breakpoint at the line that tries to modify the HTML, and notice that it simply doesn't get hit. Another clue is that the window becomes unresponsive.
My recommendation would be to look closer at your algorithm and try to set some limits. console.log statements will be your friend, because they'll help you see what parts of the code are running the most.
I've been learning Javascript online and have recently started to put it to use on a website. I'm still a little confused about what might be the most efficient/performant ways to do things, though. A few questions with that in mind...
If a webpage has multiple click events in different sections, each doing something different, one event listener in the body tag — with multiple if/else statements — would be the most efficient way to handle them all. Is that correct?
Is the search method a good way to handle if/else statements in this case? For example:
if (event.target.className.search("js-tab") !== -1) {
// do something
} else if (event.target.className.search("js-dropdown") !== -1) {
// do something else
}
The ID performance only applies to actually finding an element, right? There wouldn't be a difference between event.target.className.search and event.target.id.search, would there? (assuming there aren't an insane amount of class names to search through on that element). I'm currently using className for sections that have the same functionality (multiple tabbed sections on the same page, for example). I suppose I could just as easily use the or operator if it made a difference, like so:
if ((event.target.id.search("js-tab-one") !== -1) || (event.target.id.search("js-tab-two") !== -1))
When there are multiple elements that a click event could potentially be on (an icon inside of an anchor link, for example), how much of a performance hit is it to add additional if/else statements (i.e. check the tag type, and if it's not the a tag, move up)? I recently refactored my css so that my icons were set to width: 100% and height: 100% (ensuring that the click was always happening on the same element every time), but I wonder how much of a performance boost (if any at all) I actually got by doing this?
If a webpage has multiple click events in different sections, each
doing something different, one event listener in the body tag — with
multiple if/else statements — would be the most efficient way to
handle them all. Is that correct?
No. It's useful for handling events on elements that you add dynamically, but not so much for regular events.
Handling all the events in the body means that you will handle all the events. Every click that happens goes through your code to see if it comes from one of the elements that you are interested in.
Is the search method a good way to handle if/else statements in this
case?
No. The search method uses a regular expression, not a string, so the string will be parsed to create a RegExp object. Then a search is done using the regular expression, which is slower than a normal string search, and can give unexpected results.
To look for a string in another string you should use the indexOf method instead. You should however be aware that it will look for a match anywhere in the string, not matching whole class names. It will for example find "all-head" when the element has the class "small-header".
The ID performance only applies to actually finding an element, right?
Yes.
When there are multiple elements that a click event could potentially
be on (an icon inside of an anchor link, for example), how much of a
performance hit is it to add additional if/else statements (i.e. check
the tag type, and if it's not the a tag, move up)?
That means that every click event will have to go through the extra if statements.
If you bind the event to the element instead, you know that the event happened inside that element and you don't have to know which element did actually catch it.
A lot of what you're asking is subjective though and it fits in the context that is trying to happen. So there might be a reason why the below might be not good (as another commenter said, don't prematurely optimize). But there are some programming techniques that can be said about what you have done, namely modularity. There's a few performance considerations but they mostly revolve around writing good code:
1) it really depends on your handler, if you intend to delete and add DOM elements, this can be better because you watch the document instead of tying in a new click handler to each element. but this can be bad because its not modular if you have it do too much stuff. But if its just looking at the state, then this is not really good performance wise....
2) i wouldn't say that the search has any impact on the if else's, but in considering optimization of this particular situation you describe later on, I wouldn't do that. As each time you go through each if-else you end up doing another search and it can add up in the long run if you have a lot of if-elses in the way.
3) there shouldn't be a difference but why search in an id string? unless your id string is part of some unholy long part like musical-js-tab-one-musical-tab which I wouldn't suggest to use as an id like this anyway, you should split it up, you shouldn't tie functionality like that, use classes instead like class='musical' id='js-tab-one' since id's should describe a singular object on the page.
4) everytime you add an if-else, no matter how small it is, is another computer cycle and a little bit more memory. and it can add up, just attach your click handler by tag and by class at this point and let the browser decide to optimize it.
Since I've tried and not succeeded many times I figure it's time to ask. I would like have several elements on the screen on which the user can click. Once the user decides to double click somewhere on the body I would like to console.log the text elements of the array.
This isn't nearly as intuitive as I thought it was going to be. The following example isn't all that practical, just curious why I can't get it to work.
EDIT: I would like to NOT use a global variable.
Fiddle can be found here
You just need to alter the scope of the array textArray so that your function ferryArray() can access it and loop over.
Here is the working fiddle.
Ok, not sure if I am going to give myself any justice in trying to describe this. But..
I have an some code OOP style where you would call it like: objectName.functionName(properties, values, etc);
and as of the moment I seem to have reached a road block. I am multiple functions that do various things, but I have this one function that I want to act as a "Refresh" function for the many. Which would work if it was a single function I wanted to refresh from time to time. Overall i don't wish to reinvent the wheel either.
So my current click event looks like a call to the above. Where in the link I am using I have my hidden parameters per the needs of the functions which this works, fine But heres the catch 22 I recently ran into a need to have multiple refreshes on the same page for various functions. So I am wondering is there a way I can pass functionName as a variable to the object so it would work like
var funcNamVar = functionName;
objectName.[funcNamVar](properties, values, etc);
note the brackets [ and ] are just for representation of the concept I know they shouldnt be there
Sure. You can actually just do
objectName[funcNamVar](properties, values, etc);
Been looking for hours. At https://stackoverflow.com/questions/ask how does the "Tags" section make the blue boxes appear below?
I don't think they are using keyup event trigger, since the blue boxes are not being updated on every keypress.
You can test this by going to https://stackoverflow.com/questions/ask and typing:
"aadfadasdfasdfasdfasdfasfasdfsaf"
As you type, you will notice that the blue box "aadfadasdfasdfasdfasdfasfasdfsaf" will only appear a few seconds AFTER typing. Not during.
They probably call setTimeout and clearTimeout to run their code 1 second after the last keyup event.
It's just a case of autocomplete. There are many ways of accomplishing this.
One way is to store the list of words to autocomplete on the client end. This is very fast and there won't be any delay (unless you program one in).
The other way is to make an AJAX call to the server and have it return a list of autocomplete words. This is how SO does it. Since you don't want to make an ajax call every time the user types in a letter, there is a delay implemented to save bandwidth and improve performance.
If you want to implement a similar feature on your own website, I suggest looking into jQuery plugins to achieve this as there are many freely available ones out there.
EDIT: The trigger is likely a keyup event as you mentioned. However the trigger will likely wait for a second or so using setTimeout() before showing the list of possible autocompletes. clearTimeout() is used if another key has been pressed during the delay to prevent multiple calls from being made.
Check out the source code using Firebug or another web inspector. You'll see that there's a file called full.js. It's minimized, but you can expand the code using a variety of online tools; I go the very lazy approach of copying/pasting the whole thing into the "javascript" box in jsfiddle and hitting "tidy". I'm sure there are better (and faster) ways to do it.
Anyway, in that file, there are a few functions that may interest you: StackExchange.tagPreferences and it's subfunctions, initTagRenderer, and StackExchange.inlineEditing. I think the last function is the one that causes the specific delay you're referring to, but it's pretty hard to tell.