chrome crash while setting popupWindow.innerHTML = largeString - javascript

I have to get log every minutes
var log = '';
setInterval(function(){
log += document.getElementById('div').innerHTML; //full of html tag
},60000);
and after couple hours
log.length // > 300000
and now show it in new window
var logWindow = window.open("", "MsgWindow", "width=400,height=600");
logWindow.document.getElementsByTagName("body")[0].innerHTML = log;
after this process my chrome got crashed and all freeze. any proper way to do this? I test by different pc and the results are same.

As a workaround consider creating many elements:
var log = [];
setInterval(function() {
log.push(document.getElementById('div').innerHTML);
}, 60000);
log.forEach(function(html) {
logWindow.document.body.insertAdjacentHTML('beforeend', '<span>' + html + '</span>');
});

Consider using an array of elements rather than a string to store your log. This way you can use appendChild to gradually add elements (using a loop) to logWindow and possibly avoid a crash.
Log code:
var log = [];
setInterval(function() {
log.push(document.getElementById('div'))
}, 60000);
Pop up code:
for (var i = 0; i < log.length; i++) {
logWindow.document.getElementsByTagName("body")[0].appendChild(log[i])
}

Related

Problem with infinite loop when manipulating DOM

I'm learning about DOM manipulation and, to practice, I'm trying to get the first 100 Twitter users who have twitted about #Javascript (see link). As, for now, Twitter doesn't allow you to use console.log() function in the browser console, I have managed to show any string visually in the HTML, in this case, under the search textbox.
This is my "custom" console.log()
function consoleLog(data) {
var searchTextBox = document.querySelector("#doc > div.topbar.js-topbar > div > div > div > div > div");
var p = document.createElement("p");
var innerText = document.createTextNode(data);
p.appendChild(innerText);
searchTextBox.appendChild(p);
}
For getting the usernames, I keep scrolling the page every 4 seconds and looking for usernames until I have 100 or more of them in my usernames variable.
var scrollPage = setInterval(function() {
window.scrollTo(0, document.body.scrollHeight);
}, 4000);
var usernames = [];
while (true) { // <------ PROBLEM
if (usernames.length < 100) {
consoleLog("Getting usernames again");
usernames = getUsernames();
}
else {
consoleLog("We have ENOUGH usernames. BREAK");
clearInterval(scrollPage);
printUsernames();
break;
}
}
function printUsernames() {
for(var user of usernames) {
consoleLog(user);
}
}
function getUsernames() {
var results = [];
var usernameNodes = document.getElementsByClassName("username u-dir u-textTruncate");
var username = usernameNodes[0].textContent;
for(var node of usernameNodes) {
results.push(node.textContent);
}
return results.filter(isUnique);
}
function isUnique(value, index, self) {
return self.indexOf(value) === index;
}
The problem is that the while loop enters in infinte loop and I don't know why. I think the logic of the code is correct. In fact, if I first copy and paste all the declared functions to the browser console, then start the scrollPage interval and, lastly, start the while loop, it works well. The problem comes when I copy and paste all the code at one time in the browser console. It is like the executions of the interval and the while loop conflict in some way. But I can't understand.
Its better to have while conditioned like this:
var usernames = [];
// This will automatically end when length is greater or equall 100
// no need to break
while (usernames.length < 100) {
consoleLog("Getting usernames again");
usernames = getUsernames();
}
consoleLog("We have ENOUGH usernames.");
clearInterval(scrollPage);
printUsernames();

Watch a DOM property

I'm trying to monitor the DOM element on a third-party website. The element is non-existent until a countdown timer reaches, then it is created.
I've had some success playing around with: document.getElementsByClassName('countdown ng-hide').length
when it changes from 0 to 1 I want to effect a function.
How would I do this? I've tried using a Mutation Observer but it won't let me observe a null node.
Thanks!
EDIT: This is what I've got so far.
var timesDone = 0;
var songID = 0;
function clickit(xsongID) {
if(document.getElementsByClassName('lottery-countdown ng-hide').length == 1) {
document.getElementsByClassName('media submission ng-scope')[xsongID].click(); songName = document.getElementsByClassName('media-title submission-name ng-binding')[xsongID].outerHTML; timesDone++; }
}
setInterval(clickit, 29900, songID);
I did this recently by setting up an Interval function like this :
var timesTest = 0;
var checkExists = setInterval(function() {
if ($('.yourClassElement').length) {
// ok element found : do your stuff and clear the Interval...
// stuff...
clearInterval(checkExists);
timesTest = 0;
}
timesTest++;
// I won't let this run more than 5 seconds, so :
if (timesTest*100 > 5000)
clearInterval(checkExists);
}, 100);

Changing webpage by math.random using cookies

I am looking for a way to change webpage through a list without getting the same page twice. I have tried shuffling a list however when a new page is loaded it just reloads the script. So I guess I need to use some sort of cookie. However I am quite new to javascript. Can anyone please help me?
I was thinking something like this, just with a cookie of some sort:
var pages = ['sang1.html','sang2.html','sang3.html','sang4.html','sang5.html','sang6.html','sang7.html','sang8.html','sang9.html','sang10.html','sang11.html','sang12.html','sang13.html','sang14.html','sang15.html','sang17.html','sang18.html','sang19.html','sang20.html','sang21.html''sang22.html','sang23.html','sang24.html','sang25.html','sang26.html','sang27.html','sang28.html','sang29.html','sang30.html','sang31.html','sang32.html''sang33.html','sang34.html','sang35.html'];
var page = Math.floor((Math.random() * pages.length) + 1);
window.location.href = pages[page];
pages.splice(page);
var page = pages[Math.floor(Math.random() * pages.length)]
window.location.href = pages[page]
Here is a basic solution using localstorage as cookies would not be a good idea due to round trip
var pages = ['sang1.html', 'sang2.html', 'sang3.html', 'sang4.html', 'sang5.html', 'sang6.html', 'sang7.html', 'sang8.html', 'sang9.html', 'sang10.html', 'sang11.html', 'sang12.html', 'sang13.html', 'sang14.html', 'sang15.html', 'sang17.html', 'sang18.html', 'sang19.html', 'sang20.html', 'sang21.html'];
var page, visitedPages = JSON.parse(localStorage.getItem("visitedPages"));
if (visitedPages === null) {
visitedPages = [];
}
var unVisitedPages = difference(visitedPages, pages);
if(unVisitedPages.length === 0){//All pages visited at once
//add your logic when all page visited
}
else{
page = unVisitedPages[Math.floor(Math.random() * unVisitedPages.length)];
localStorage.setItem("visitedPages", JSON.stringify(visitedPages.push(page)));
window.location.href = page; //append if you want to kill cache"?ck="+new Date().getTime()
}
function difference(a,b){//b -a
var c = [];
for(var i=0; i< b.length; i++){
if(a.indexOf(b[i]) === -1){
c.push(b[i]);
}
}
return c;
}

retrieving data after right-click paste

I am trying to evaluate some data entered into a textarea after a paste has occurred. When I use onkeyup it detects if fine and does the evaluation okay when the user uses Cntl-V to paste. It does nothing when they right-click and select paste. I changed to onkeyup to onpaste which detects both the Cntl-V and Right-click paste but the data is not there. I know that the onpaste is triggered before the actual paste is performed so I tried to delay the evaluation with a setTimeout(), but even with a 5 second delay it never gets the data until after function function completes. No matter what I do I can't seem to get a count of the number of items that were entered. Here is my code:
function delayStart() {
alert("delayStart() function");
var inData = " ";
setTimeout(function()
{inData = document.getElementById("loanNumberPaste").value},
5000);
var iData = inData.value;
alert("iData = " + iData);
setTimeout(fnUpdCt(iData),5000);
}
function fnUpdCt(vId) {
var strVId = vId.value;
alert("fnUpdCt() function \n" +
"vId = " + strVId);
var i;
var iVal = vId.value;
var vCt = 0;
iVal = iVal.replace(/\s/g,' ');
iVal = iVal.split(' ');
for (i=0; i < iVal.length; i++) {
if (iVal[i].length > 0) {vCt++;}
}
document.getElementById("loanNumberCount").value = vCt;
}
<textarea id="loanNumberPaste" rows=17 cols=37 tabindex="1"
onpaste="delayStart();";onkeyup="fnUpdCt(this);"></textarea>
Any advise you can provide will be greatly appreciated.
The timeout isn't working because instead of passing the function by reference you're calling it immediately and trying to return its value.
Just wrap fnUpdCt in an anonymous function and it should be fine.
setTimeout(function(){fnUpdCt(iData)},5000);
Also, you don't need to wait 5 seconds - its not the fact that its waiting x amount of time, its the fact that its asynchronous.

Javascript - Images not cycling/rotating

I'm working on a script to rotate/cycle through images in javascript while respecting a limit on the amount of times it cycles through the images. What I have is below:
<a id="imageurl"><img id="Rotating1" border="0"></img></a>
<script language="JavaScript">
var delay = 3000; //6000 = change to next image after 6 seconds
var cycles = 2;
var currentCycle = 0;
function RotateImages(Start, delay)
{
var a = new Array("frown.gif","grim.gif","smile.gif", "bomb.gif");
var c = new Array("url1", "url2", "url3", "url4");
var b = document.getElementById('Rotating1');
var d = document.getElementById('imageurl');
var totalCycles = cycles * a.length;
// alert ("currentCycle: " + currentCycle);
// alert ("totalCycles: " + totalCycles);
if (Start>=a.length)
Start=0;
b.src = a[Start];
d.href = c[Start];
if (currentCycle < totalCycles) {
window.setTimeout("RotateImages(" + (Start+1) + ")", delay);
currentCycle++;
}
}
RotateImages(0, delay);
</script>
The script acts like it's working when I uncomment the alert boxes. When I comment them out, the rotation seems to stop. Any ideas on what is really going on and how to fix it?
Thanks!
perhaps you would like to change this line:
window.setTimeout("RotateImages(" + (Start+1) + ")", delay);
into:
window.setTimeout("RotateImages(" + (Start+1) + ", " + delay + ")", delay);
so that the next time RotateImages is called, it will keep the delay.
One fundamental issue to take into consideration is with setTimeout. The first parameter can be a reference to a function, whether it be an actual reference or a string reference, but you cant pass parameters along with it.
To do what you want, you need to pass a anonymous function to setTimeout. Also, Riyono is right that you should also pass the delay
setTimeout(function(){ RotateImages(Start++, delay) }, delay);
As far as your alert issue, I don't know what to tell you. But I know that the above will correct some issues.

Categories

Resources