JavaScript for loop that loads resources (Improve loading) - javascript

I'm writing a short script that loops through an array and loads each of the results found although I'm having some issues with it loading. If I alert my results found in each loop I get the right data but when I attempt to load this data, it fails.
var arrayScripts = new Array (
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js',
'scripts/tiny_mce/tiny_mce.js',
'scripts/jquery.cycle.lite.js',
'scripts/javascript.default.js',
'scripts/jquery.default.js'
);
for (var i=0; i < arrayScripts.length; i++) {
scripts.add(arrayScripts[i]);
}
scripts.load();
I hope you can see what I'm doing wrong here. It appears to be my code inside of my loop.

Related

Project works fine on localhost but the build gets an issue

I am working on a Preact-CLI project with a Preact-Router and it works fine on the localhost. But the production doesn't work well after the build.
I have created a one page object which gets its content dynamically from a JSON file (inside the project not external). So I've loaded the same page object 2 times for each different page.
I get the page url (using this.props.permalink) and compare it with the JSONObject.title. If they are the same I want to get the corresponding JSON content to display it on the corrrct page. Works like a charm on localhost, but not in production.
Issue:
Somehow all pages get the content of the first JSON element. First I thought it was a server issue but I was wrong. The builded files are wrong after the prerendering/build. So the prerendered html of page B contains the content of the prerendered page A.
My guess is that during the build this.props.permalink doesn't work. How should I handle this?
Additional info:
I use the prerender function but not the service worker for the build.
Thanks!
UPDATE:
I have rewritten the function. I guessed I needed to set the dynamic content through a loop, so that during the build the compiler loops through it and is able to prerender all the pages.
The iteration and setting the state works, but only the final element of the PrerenderUrls array gets stored. So now all pages gets the JSON content of the first element.
componentWillMount() {
for (var i = 0; i <= PrerenderUrls.length; i++) {
// the code you're looking for
let removeDash = new RegExp("-")
var needle = PrerenderUrls[i].title
var needle1 = needle.replace(removeDash, " ")
alert("1")
// iterate over each element in the array
if (needle1 != "Homepage") {
for (var x = 0; x < Data.length; x++) {
// look for the entry with a matching `code` value
let removeDash = new RegExp("-")
var nodash = Data[x].title.replace(removeDash, " ")
var nocaps = nodash.toLowerCase()
if (nocaps == needle1) {
alert("needle2: "+ needle1 + " nocaps: " + nocaps)
//alert("data "+ Data[x].title)
this.setState({
pageTitle: Data[x].title,
descShort: Data[x].descShort,
description: Data[x].desc,
img: Data[x].img
})
alert("state "+ this.state.pageTitle)
}
}
}
}
From your description it seems you have a standard Javascript closure problem. I noticed you use both let and var. If let is supported, use it instead of var. It will automagically solve your closure issues, because let creates variables with the block scope, instead of a function scope. Otherwise, you can try to replicate how let does it under the hood - throw the variable to the callback function. Something in the lines of:
// ...
for (var x = 0; x < Data.length; x++) {
try { throw x }
catch(iterator) {
this.setState({
pageTitle: Data[iterator].title
});
}
}
PS. It is very difficult to follow your code, when it is so specific to your functionality. You could simplify it, and focus on the troubling issue. Most of the code you provided is not relevant to your problem, but makes us going through it anyway.

What is the Difference Between These Two HTMLCollections?

I'm trying to collect ratings for all products that have ratings on this page: https://www.theluxelens.com/pages/photoshop-overlays. While I can get the code below to work in my own browser (Chrome), it does not work on the page itself.
It is, however, able to get the elements that have the ratings, because the first console.log statement returns those elements.
var ratingsElements = document.getElementsByClassName("spr-badge");
console.log(ratingsElements);
var nonZeroRatings = [];
for(var i = 0; i < ratingsElements.length ; i++){
var rating = ratingsElements[i].getAttribute("data-rating");
console.log(rating);
if(rating != "0.0") {
nonZeroRatings.push(rating)
}
}
console.log("logging the ratings...");
console.log(nonZeroRatings);
There looks like a slight difference in what is returned when the code below is run in my own console vs from the page itself. When run from my browser console, the first console.log statement in my code returns an HTMLCollection that is slightly different - I believe this difference is why the code isn't working when run from the page itself, but I don't know why it is different. This code works, as you can see it delivers the ratings of products that have them (non-zero ratings) in an array:
VS. when the same code, run from the page, notice the HTMLCollection returned is slightly different:
This is the full script tag from the page:
<script type="text/javascript">
window.onload = function () {
var ratingsElements = document.getElementsByClassName("spr-badge");
console.log(ratingsElements);
var nonZeroRatings = [];
for(var i = 0; i < ratingsElements.length ; i++){
var rating = ratingsElements[i].getAttribute("data-rating");
console.log(rating);
if(rating != "0.0") {
nonZeroRatings.push(rating)
}
}
console.log("logging the ratings...");
console.log(nonZeroRatings);
};
</script>
Thanks for any insight here. This is a Shopify website, if that makes a difference.
When you log something from the page, it basically logs a reference which values are not filled in until the developer goes to look at the console entry. You may notice that little information icon beside it in the log entry, if you hover/click on that it should indicate this to you. Where, as when you're running this from the console it instead decides in this case to pull the collection data right away and log it.
That's the difference between runtime execution and developer intent in the console in some situations. This same concept applies at other times as well, I don't know all of them right off. That information icon showing up is a good indicator of the entry being a reference initially instead of a full data copy.

Iterate through multiple web pages in JS with sleep in between

I was checking some simple solutions for showing multiple web pages for some dashboard and currently fighting with simple HTML page with javascript inside to achieve what I want to see there.
var urls = new Array();
urls[0] = "https://stackoverflow.com/"
urls[1] = "https://www.google.com"
var arrayLength = urls.length;
for (var i = 0; i < arrayLength; i++) {
window.location.assign(urls[i]);
sleep(3000);
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
Currently this page opens only first page (after some time) and looks like it doesn't do iteration trough other pages. Maybe you could help me to make it work? I want to rotate those pages forever on screen (will add some infinite while loop after making this part working).
Currently this page opens only first page (after some time) and looks
like it doesn't do iteration trough other pages.
Once you change your window.location, and go to the first url from the array, you are losing all of your JS code (as it is not present in just opened url any more).
You can do this by installing a chrome plugin (which will not lose your JS after window.location change).
The plugin will run the added JS at DOMContentLoaded (no need to attach any event listener).
I needed also to do this, check things on the page, store some information and move on to the next page. I know, this can be done with Python and other stuff but by doing this it can be done on the FE side also.
I used the localStorage to store my information.
I pasted this into the browser console to prepare all the stuff and clean the localStorage:
// clear the localStorage
localStorage.clear();
// set an array that will keep all our pages to iterate into the localStorage
localStorage.setItem(
"pages",
JSON.stringify([
"https://my-page-1.html",
"https://my-page-2.html",
"https://my-page-3.html",
"https://my-page-4.html",
])
);
// set an array that will keep our findings
localStorage.setItem("resultArray", JSON.stringify([]));
// move to the first page of the iteration
window.location.href = "https://my-page-1.html";
After doing this, I opened the plugin interface and added the following code:
(function check() {
// array saved into the localStorage that contains all the pages to iterate
const pagesArray = JSON.parse(localStorage.getItem("pages"));
// array to store your stuff
const resultArray = JSON.parse(localStorage.getItem("resultArray"));
// whatever you want to check on that page
const myFancyCondition = true;
if (myFancyCondition) {
// push any data to the array so that you can check it later
resultArray.push({
page: pagesArray[0],
message: "I found what I was looking for!",
});
}
//remove the current page from the array
pagesArray.shift();
//reset the array value after the first page was already checked
localStorage.setItem("pages", JSON.stringify(pagesArray));
//store the array data
localStorage.setItem("resultArray", JSON.stringify(resultArray));
// quit if the iteration is over and there are no more pages to check
if(!pagesArray.length) return;
//go to the next page
window.location.href = pagesArray[0];
})();
Then, to check the results you just need to read the data from the localStorage like:
JSON.parse(localStorage.getItem('resultArray'))
I hope this helps :)!

Javascript giving a TypeError variable is undefined for code (photo gallery) run on server. Same code works locally

i'm putting together a personal website as a portfolio and i'm having trouble getting a photo gallery to work. I found a free Javascript gallery (http://ettrics.com/lab/demo/material-photo-gallery/) that I decided to implement. When putting the page together locally, the javascript runs no problem, however when I upload the page to the site (which already has plenty of other javascript running) I get the following error when scrolling on the page, or when trying to 'fullscreen' one of the images by clicking on it:
TypeError: this._fullImgs is undefined
I tried to isolate the issue and found that a line of code was executing differently on the server, than locally, the excerpt is below:
Gallery.prototype._loadFullImgsDone = function() {
var imgLoad = imagesLoaded(this._fullBox);
imgLoad.on('done', function(instance) {
var imgArr = instance.images;
this._fullImgs = [];
this._fullImgDimensions = [];
this._fullImgsTransforms = [];
for (var i = 0, ii = imgArr.length; i < ii; i++) {
var rect = imgArr[i].img.getBoundingClientRect();
this._fullImgs.push(imgArr[i].img);
this._positionFullImgs.call(this, imgArr[i].img, i);
this._fullImgDimensions.push(rect);
}
this._fullImgsLoaded = true;
}.bind(this));
};
I have found that the images are being found from their source location, however
imgLoad.on('done', function(instance) {
...
executes differently. The site is located at http://http://samueller.tech/photo-best.html id anybody would like to see for themselves the error I am getting.
Thanks in advance, i'm at a complete loss of how to fix this.
I'm seeing (on that site) the resizeHandler is getting called before the images are loaded
Gallery.prototype._handleScroll = debounce(function() {
this._resetFullImg.call(this);
}, 25);
Gallery.prototype._handleResize = function() {
this._resetFullImg.call(this);
};
Then this._resetFullImg fails because there are no images loaded yet which is why this._fullImgs is empty. The code seems to have another variable called _fullImgsLoaded and probably the _resetFullImg method should do nothing if images haven't been loaded.
You could try adding that like this:
// in material-photo-gallery.js line 1379
Gallery.prototype._resetFullImg = function() {
if (!this._fullImagesLoaded) {
return
}
this._fullImgsTransforms = [];
for (var i = 0, ii = this._fullImgs.length; i < ii; i++) {
...
I don't know how this will affect the reset of the gallery code, but it might work. It makes some sense that on your production system, the page load time (with extra JS and stuff) is such that these events might get called before things are ready which is something you don't see locally.
good luck.

How to find if a javascript is already loaded or not?

I am developing a chrome extension to ajaxify every non ajax website like wikipedia. etc. It works fine but it fail to load the js files. So, I have written a script to load js files thats are required for the page by getting src attribute from tag. But the problem is when i am loading another page of that website every scripts are loaded again. So it is useless to make it with a purpose to reduce bandwidth.
So, I want to know whether there is any way to match the script array of the new with its previous page. and to identify which scripts are new and load only them.
var array1 = [];
for (var i = 0; i < jsn; i++) {
var jssrc = document.getElementsByTagName("script")[i].src;
array1.push(jssrc);
}
var array2 = [how to find out array script source of the new page]
Array.prototype.diff = function(array2) {
var ret = [];
for(i in this) {
if(array2.indexOf( this[i] ) > -1){
ret.push( this[i] );
}
}
return ret;
};
ajaxpagefetcher.load("ajax-script", "", true, array1.diff(array2);)
How to find script src array of the new page that is to be loaded..
one more question, with out reloading the page if i delete the body tag through remove() function, are the scripts that already loaded also removed?
Thanks
I am waiting with eager for your replay....
At the end of the JS file:
window.iAmLoadedOnThisWindow = true;
And in the loader part:
if(! window.iAmLoadedOnThisWindow) {
// append the script with some dom method
}
If the JS file is a library, test the library : if(jQuery), if(_), etc.

Categories