Block "stop execution of this script" message - javascript

I have an array with 2000 arrays which each have 2000 values (to stock a 2000x2000 image) in javascript in an HTA. I have this code to test how many "blue" values there are in the array (the array's name is image):
var bluePixels = 0;
for(i = 0; i < image.length; i++){
for(j = 0; j < image[i].length; j++){
if(image[i][j] == "blue"){bluePixels = bluePixels + 1}
}
}
alert(bluePixels);
The problem is that it shows a message where it says something like "Stop execution of this script? A script on this page is slowing down Internet Explorer. If it continues, your computer might not answer." (I'm not sure of the exact words because my computer is in French) and then, if I click on "no", it does the alert(bluePixels) like it should but if I push on "yes" it doesn't. How can I block this message? (I know that there are workarounds like telling the user in the beginning to press "no" but I want a real solution)

For IE versions 4 to 8, you can do this in the registry. Open the following key in Regedit: HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Styles. If this key doesn't exist, create it. In this key, create a DWORD value called MaxScriptStatements and give it the value 0xFFFFFFFF (don't worry if the value changes automatically when you click on OK, that's normal).
You can program JavaScript to do this automatically:
var ws = new ActiveXObject("WScript.Shell");
ws.RegWrite("HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Styles\\","");
ws.RegWrite("HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Styles\\MaxScriptStatements",1107296255,"REG_DWORD");

Seems like you have an answer here
From the answer:
"The only way to solve the problem for all users that might be viewing your page is to break up the number of iterations your loop performs using timers, or refactor your code so that it doesn't need to process as many instructions."
So the first approach can be attained using a timeout for each such large iteration.

You need to split the 2000x2000 for-loop's up in smaller pieces of code, eg threads or processes, so the browsers maximum execution time not is becoming exhausted. Here the image array is parsed for one row at a time, controlled by a timer :
var bluePixels = 0,
timer,
i = 0;
function countBluePixels() {
for (var j = 0; j < image[i].length; j++){
if (image[i][j] == "blue") {
bluePixels = bluePixels + 1;
}
}
i=i+1;
if (i>image.length) {
clearInterval(timer);
alert(bluePixels);
}
}
timer = window.setInterval(countBluePixels, 0);
The code is the same, just splitted up in 2000 processes instead of 1.

Related

Discord.js Set Interval function not activating. Need confirmation of cause

I am currently having an issue with the setinterval function and was wondering if anyone could help. So oddly enough, it works for short intervals like 10 or 20 seconds but when I scale it to a day or half a day it fails to run. I'm on version 11.5.1 of discord.js
bot.setInterval(function(){
var Holiday = new Date();
var month = Holiday.getMonth()+1;
var day = Holiday.getDate();
var check = month+'/'+day;
var greeting = "";
for(var i = 0; i < Events.length; i++){
if(check == Object.keys(Events[i]) && check != "12/25"){
greeting = "Happy "+Object.values(Events[i]);
}
if(check == "12/25"){
greeting = "Merry Christmas";
}
}
for(var j = 0; j < c.length;j++){
var channel = bot.channels.get(c[j]);
if(greeting != ""){
channel.sendMessage(greeting);
}
//channel.sendMessage('test');
}
}, 3600000,)
This is the function in the ready event. Events is a json file with an array of key value pairs. c is an array with channel ids. so in the json file I have a test date that when I ran for the current day it would work, but when I change the day to the next and then wait for that time to come, nothing happens but the time should have passed and the variables should have all been reset so any ideas? Also, I have the bot hosted on glitch sending itself ping requests as well as using uptime robot which has indicated there has not been a down for 60 hours. The only reason I could think of for the cause is that maybe glitch puts the bot to sleep for a split second and it causes the interval to constantly reset, but then that would mean the pings and uptime robot are having no effect. Also, if anyone has a clever work around I would be grateful. The best I could do was just have a command that does this.
maybe because you didn't break function at the end like this
}
//channel.sendMessage('test');
}
}, 3600000);
and maybe that comma making the value act as an integer and more value going to be put in there.
Since I've updated to the new version of the library things have changed. However, this was long ago and I was hosting on glitch at the time, and that ended up being the problem. Glitch will still put to sleep the bot even if you are pinging it with uptime robot as they prevent ping spam.

Javascript print output one at a time instead of entire page at once?

Just playing around a bit, but noticed it's taking way too long for page to load, is there anyway to get it to print out one line at a time instead of having to wait till the entire page is loaded.
limits(){
var a = 0;
for (var i = 0; i < 1000; i++) {
for (var ii = 0; ii < 1000; ii++) {
document.getElementById('foo').innerHTML += "<p>" + a + "</p>";
a * 2;
}
}
}
Now how would I be able to control this better to where regardless of how long it takes to load print as soon as ready and even slowing it down would be fine.
The javascript method window.requestAnimationFrame(callback) will call your callback function on the next animation frame. It's commonly used for animation, and will probably work well for what you're doing.
To modify your code to use requestAnimationFrame, you have to make your function print a small chunk on its own, with a reference to know what chunk to print. If you stored your page contents in an array, for example, that could just be a starting index and a length. Since you are printing the increasing powers of 2, you can just pass in the last power of two and the number of lines you want to print for each run of the function.
You'll also need an exit condition -- a check within limits that if true, returns without requesting the next frame. I simply put a hard cap on the value of a, but you could also check that the index is less than array length (for my array of page contents idea above).
Because requestAnimationFrame passes in a function name as a callback, you can't pass arguments into it. Therefore, you have to use bind to sort of attach the values to the function. Then, within the function, you can access them using this. config is just an object to hold the initial arguments you want the function to have, and then you bind it, which allows you to access them within the function with this.numLines and this.a.
Then, when you request the next frame, you have to bind the values to limits again. If you are alright with keeping the arguments the same, you can just do limits.bind(this). But if you want to change them, you can create another object in a similar way to how I wrote config and bind that instead.
The following code seems to be a basic example of roughly what you're looking for:
var foo = document.getElementById('foo');
var maxA = 1000000000000000000000000000000000;
function limits() {
for(var i=0; i<this.numLines; ++i) {
foo.innerHTML += "<p>" + this.a + "</p>";
this.a *= 2;
if(this.a > maxA) {
return;
}
}
requestAnimationFrame(limits.bind(this));
}
config = {
numLines: 3,
a: 1
};
requestAnimationFrame(limits.bind(config));
And is implemented in JSFiddle here. I've also implemented a version where it puts each line at the top of the page (as opposed to appending it to the bottom), so that you can see it happening better (you can find that one here).
You can do something like this:
limits(){
var a = 0;
for (int i = 0; i < 1000; i++) {
for (int ii = 0; ii < 1000; ii++) {
setTimeout(function(){
document.getElementById('foo').innerHTML += "<p>" + a + "</p>";
a * 2;
}, 0);
}
}
}
You can adjust the time in the setTimeout, but even leaving it as zero will allow a more interactive experience even while the page builds. Setting it to 10 or 100 will of course slow it down considerably if you like.

JavaScript For loop not working after a certain line in the code

I'm doing a simple exercise meant to be in JavaScript that consists of turning a binary into its respective decimal value... I feel I'm close to finishing the project but for some reason my for loops wont work after a certain line.
//function is called after the press of a button
function convertToBinary (){
oText= document.all?document.all("inout"):document.getElementById("inout");
//inout represents a textarea
sText= oText.value;
alert(sText);
aText = sText.split(/\n\r|\n|\r/g); //got this line after searching this site for solutions
/*alert(aText[1]);
alert(aText[2]);
alert(aText[3]);*/
aText does have values stored, checked a thousand times, but after this line everything goes down, and i can't seem to find the reason why. Here is the rest of the code copy/pasted from my text editor.
for(y = 0; y < aText.lenght;y++){
alert(aText[y]);
}
iCurrent=0;
aBina= aText[0].split("");
for(var x = aBina.lenght-1; x >= 0; x--){
iCurrent = (iCurrent*2) + parseInt(aBina[x]);
alert(iCurrent);
}
aAsci[0]=iCurrent;
alert(iCurrent); //Alerts 0
}
NOTE: variables and arrays are properly defined in the first few lines of the code, i have used them in a previous function that does the opposite(convert decimals to binary) and that works fine. I was sure to clean each array and variable after the function is done. ("o" is for objects, "s" for strings, "a" for arrays, "i" for int's).
There is no apparent syntax error to be seen. I would appreciate not posting the solution for the exercise unless it is really necessary, i might not be doing it right just yet but I like to think through the algorithms my self :p. My problem is for loops are as if the condition was not met, they are just being skipped. I'm using Opera Next as my web browser and the "inspect element" Console does not show any errors either.
Thank you in advance.
This should be,
for(y = 0; y < aText.length;y++)
and this
for(var x = aBina.length-1; x >= 0; x--){
instead
for(var x = aBina.lenght-1; x >= 0; x--){
for(y = 0; y < aText.lenght;y++)
you mispelled this one, "LENGTH"

My 1 page web app reduces a variable by 2 instead of 1 after completing a certain level

For some reason after the user guesses the right number and follows the confirm to play the game again but with fewer guesses (2 less than original), each time a user guesses a number the guesses remaining is deducted by 2 and sometimes just random numbers instead of the usual 1. I tried changing the code to deduct in various different ways but to no avail:
j--;
j -= 1;
j = j - 1;
Full code in Fiddle, if anyone could help that would be awesome I've been at this for hours! Thanks
partial for guess button click event
if (currentGuess < numberToGuess) {
$hintBox.html('<p class="blue">Try higher</p>');
} else {
$hintBox.html('<p class="blue">Go lower</p>');
}
j = j - 1;
$('.numberGuesses').html(j);
} // end of if guess is not correct
else if (currentGuess === numberToGuess) {
alert('Well done the correct number was '+ numberToGuess);
var playAgain = confirm("Let's see if you can do that again with less guesses.");
if (playAgain){
$('#gameDiv').hide('pulsate', 100, function(){
$('#mode').delay(200).show('pulsate', 500);
});
lowerGuesses = lowerGuesses - 2;
$('.numberGuesses').html(lowerGuesses);
} else {
location.reload();
}
}
You don't reset the counter j to lowerGuesses after you get the number right.
The code is very difficult to follow, and IMO a bit broken. Things need to be broken out much better. Isolate the "new game" code into something you call when there's actually a new game. Create a new random number. Clear out the numbers it remembers; after I fixed it it was the same number again (possible but unlikely, so I'm assuming that logic is also broken) so it both warned me that I'd already guess the number, and told me I guessed the number correctly.
Basically your game loop should be just for the game, not for preparing a new game, etc. Consider passing in the number of guesses the player should get into a newGame function (along with many other refactorings).

CS5 Hiding layers is painfully slow

Is it only me that thinks the CS5 scripts runs painfully slow?
These few lines takes over 1 minute to execute.
for (n=0; n<app.activeDocument.layerSets.length; n++) {
app.activeDocument.layerSets[n].visible = false;
}
The number of layerSets are 20.
I'm running the CS5.1 64bit version on a Vista Home Premium system, AMD Athlon 64 X2 Dual Core 5200+ with 8GB RAM.
I tried to Export the script as a .JSXBIN but it still takes over 1 minute. CPU usage for CS5.1 goes from 3% to 57% when the CS5.1 is running the .JSXBIN script.
There must be something wrong here, how can I speed up the scripts?
// Thanks
* EDIT *
It seems like CS5's own DOM implementation is the problem here. The script speeded up more than twice by reading DOM related values into local variables.
var LayerCount = app.activeDocument.layerSets.length;
var LayerRoot = app.activeDocument.layerSets;
for (n=0; n<LayerCount; n++) {
LayerRoot[n].visible = false;
}
...but still, it far to much time to just change a property in 20 objects. Any help with optimizing would be appreciated :)
The only thing I can think of is try try to loop through the individual layers in app.activeDocument.layers which contains all the layers and groups. When you do this you'll notice that grouped layers will still retain their original visible property but are hidden because their parent group is hidden.
#target photoshop
var myLayers = app.activeDocument.layers;
var myLayersLength = myLayers.length;
for (var i=0; i<myLayersLength; i++) {
myLayers[i].visible = false;
}
EDIT: So I tested this solution on a 400mb file with 50 layers and it worked in seriously less than a second. Are you sure the problem is with Photoshop?
If you have to iterate through every single layer and child-layer individually to perform an action you can do it recursively:
#target photoshop
var doc = app.activeDocument;
findLayers(doc);
function findLayers(set) {
for (var i=0; i<set.layerSets.length; i++) {
//recursive call
findLayers(set.layerSets[i]);
//iterate sub-layers and hide
for (var j=0; j<set.layerSets[i].layers.length; j++) {
set.layerSets[i].layers[j].visible = false;
}
}
//hide top-level layers
for (var l=0; l<set.layers.length; l++) {
set.layers[l].visible = false;
}
}
This takes a bit longer, ~20 seconds on my machine, but it will hit every single layer in a document.
NOTE: I also tested your original scripts from the question and they don't work on un-grouped layers because you're iterating through document.layerSets instead of document.layers
Have a look at this ps-scripts iteration over layers is slow - explanation
Which may be able to help you as well.

Categories