JS code injection into console freezes the website - javascript

I have created very simple JS script to automate tasks on specific website (Clicking element when it appears etc..) It has 3 functions in which are 3 while true loops, basically each of those has a infinite loop which is asking if specific element is present on website, and if yes then I click it and call another function which is composed the same way, looking for a element and if it appears, it should click it. So I do have 3 functions Main(), Function2(), Function3() and I start by calling Main(), If element appears in Main() I call function2() then function3 from f2() and from f3() back to Main(), should be an infinite looping, but after I copy paste the code into console the website instantly becomes lagged and I need to restart browser, why does this happen? How do I fix it to be able to run the script correctly? (Iam very new to JS, this might be coded very wrongly)
function function3(){
while (true) {
let BTN = document.querySelector("....")
if (BTN != null){
BTN.click()
main()
}
}
}
function function2(){
while (true){
let anotherElementButton = document.querySelector("...")
if (anotherElementButton != null){
anotherElementButton.click()
function3()
}
}
}
function main(){
while (true){
let elements = document.getElementsByTagName('tag-of-the-elements')
if (elements.length > 0){
Array.from(elements).forEach(btn => btn.click())
function2()
}
}
}
main()

This probably happened since each time you create a new instance of main, f2, and f3 and how it is in an infinite loop, the browser lags until it becomes completely unavailable.
If you want to check if an element is on the screen and then execute an action you probably should use something like Mutation observer to observe for changes on DOM or setInterval
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
https://www.w3schools.com/jsref/met_win_setinterval.asp

Related

How to safely send message to a running function in javascript

I tried to work this code:
var foo=0
window.onmouseup=function(){
foo=1
}
window.onmousedown=function(){
while(foo==0);
console.log("bar")
}
the "bar" is not shown and the browser (I use Edge) stuck there(unable to close the page), I had to use Ctrl+T and then Ctrl+W
I guess the problem is foo==0 is optimized, so it reads from the cache, but I don't know how to avoid it. Or are there other methods?
You could use setInterval() and put the if statement and the rest of the code in there:
var foo = 0
window.onmouseup = function() {
foo = 1
}
window.onmousedown = function() {
var interval = setInterval(() => {
if (foo !== 0) {
clearInterval(interval);
console.log("bar")
}
});
}
Actually, I think the problem is that your while loop will just continue running until it "breaks", or ends the loop. However, foo will always be 1 and never 0 after mouseup, therefore the program gets stuck in the while loop forever, and no other tasks on the browser including the important ones get run.
TL:DR program stuck on while

break out of setInterval loop javascript

I am new to javascript, and I am coding a game.
I would like to break out of the setInterval loop when a condition is met to display a game over screen. My code :
var timer = 0;
var i =0;
fond.onload= function()
{
timer = setInterval(boucle,50);
console.log("break");
}
function boucle()
{
i++;
if(i===4)
{
clearInterval(timer);
}
}
I never reach the break log because just after the clearInterval, the screen is stuck.
Thank you!
I am not sure what fond.onload represents in your code, but if you want the code to run when the page is loaded you should use window.onload or document.onload.
onload is a global event handler bound to all objects that gets executed when that object is loaded. I presume that in your case fond is never loaded as the rest of the code is fine, just never runs. It will run fine if you bind the function to window.onload.
You can read up more on that here

How would I go about using window.find() activate on that text only once

I use hack.chat a bit, and I saw that they have a bot, but the bot program wasn't working for me so I decided to make my own.
var finderBinder;
var searchFor = function(command){
finderBinder = window.find(command, true, true);
if(finderBinder){
if(command === "/hello"){
ws.send(JSON.stringify({cmd: "chat", text: "hello!"}));
}
else if(command === "/cry"){
ws.send(JSON.stringify({cmd: "chat", text: "wah waha wahhh"}));
}
else
{
console.log("it was found but it was not a command.")
}
}
else
{
console.log("Did not find the command");
}
}
var loopdeloop = 0;
while(loopdeloop === 0){
searchFor("/hello");
searchFor("/cry");
}
Now, the first part works if I just run that by itself on the page, and enter searchFor("/hello"); that would work, but if I wanted it to just automatically do that whenever a message popped up, I attempted the loop,(In a empty chatroom so it wouldn't spam a used room if it did) and it crashed my browser. I know why it did that. because it just checked forever, and it saw it forever so it kept on trying to do the code forever..
But how would I make it only run the searchFor when a new text showed up so it would run the text in it and if it was a command it would do the command? Or is there a better way to do this?
The simplest way to stop your function from looping to infinity (and beyond!) would be to call it once every X seconds/minutes/hours/lightyears.
Using setInterval(searchFor, 1000); where the second parameter is the time interval in milliseconds.
To pass a parameter to your searchFor function, you must create an anonymous function so it doesn't get called right away.
setInterval( function() { searchFor ("/hello"); }, 1000 );
This will call your function every ~1 second, although keep in mind there is some overhead to javascript and there will be a slight delay. Also be careful of looping your function too often, as it will be expensive, and browsers have a built in delay, for example, you will not be able to setInterval to 2 ms and have it function normally cross browser.
Edit: The more elegant solution of binding an event to a change in the textbox is also possible, depending on how the page is setup and your access to it, hard to answer without that structure known.

Query about setTimeout()

Since past couple of months, I have been doing a lot of JS, but I have never really learned it in a college/from a book etc.
Here is a question:
$scope.selectTab = function($index, tab) {
$scope.template = $scope.templates[$index];
$scope.data.tabSelected = tab;
setTimeout(function() {
console.clear();
console.log($scope.template);
console.log(document.getElementById("SomeDiv"))
console.log("Going to draw now...")
draw_analytics($scope); // Draw on SomeDiv
}, 0);
}
while the above code works; but the below one doesn't.
$scope.selectTab = function($index, tab) {
$scope.template = $scope.templates[$index];
$scope.data.tabSelected = tab;
console.clear();
console.log($scope.template);
console.log(document.getElementById("SomeDiv"))
console.log("Going to draw now...")
draw_analytics($scope);
}
I am using AngularJS for some tabbing thing, but that is irrelevant I guess.
In the top code, when I try to get SomeDiv dom, I actually get it's HTML content, while in the bottom code, null is returned.
When you use settimeout with an anonymous function, it doesn't execute it right away. It adds it to a queue to be executed after the current events finish.
This is opposed to running it without settimeout, which just executes it immediately.
If I had to guess, "SomeDiv" is being created or manipulated with the tab change. So running the code right away may cause a situation where the code executes before the div is actually created. While calling "settimeout" will wait until the current events complete before executing. Although it looks like it's inline with the event, it's really just scheduling the anonymous function to run at the end.
I created a fiddle to illustrate what I'm talking about.
http://jsfiddle.net/pS54r/
The first button using settimeout, the second button doesn't.
$('#clickme').click(function () {
WriteToDiv('First Button 1');
setTimeout(function () {
WriteToDiv('First Button 2');
}, 0);
WriteToDiv('First Button 3');
});
$('#clickme2').click(function () {
WriteToDiv('Second Button 1');
WriteToDiv('Second Button 2');
WriteToDiv('Second Button 3');
});

To execute Flex cleanup function when browser is closed by user

I have a Flex client application. I need a clean up function to run in Flex when the user closes the browser. I found the following solution on the net, but it only works half-way for me. How could I fix it? Thanks in advance for any responses!
Symptoms
CustomEvent triggered, but not executed. >> EventHandler for CustomEvent.SEND_EVENTS is defined by a Mate EventMap. All the handler does is to call an HTTPServiceInvoker. In debug console, I'm able to see the handler and HTTPServiceInvoker being triggered, but neither the resultHandlers nor the faultHandlers were called. I know this event handler has no problem because when I dispatch the same CustomEvent.SEND_EVENTS in a button click handler, it behaves exactly as I expected)
Browser seems to wait for cleanUp function to complete before it closes. (all traces were printed before browser closes down)
Code
I added the following into the index.template.html
window.onbeforeunload = clean_up;
function clean_up()
{
var flex = document.${application} || window.${application};
flex.cleanUp();
}
And used the following in the application MXML file
import flash.external.ExternalInterface;
public function init():void {
ExternalInterface.addCallback("cleanUp",cleanUp);
}
public function cleanUp():void {
var newEvent:CustomEvent = new CustomEvent(CustomEvent.SEND_EVENTS);
newEvent.requestObj = myFormModel;
dispatchEvent(newEvent);
// for testing purposes
// to see whether the browser waits for Flex cleanup to finish before closing down
var i:int;
for (i=0; i<10000; i++){
trace(i);
}
}
My Setup
FlexBuilder 3
Mate MVC Framework (Mate_08_9.swc)
FlashPlayer 10
Unfortunately, there is no solid way of doing such clean up functions that execute asynchronously. The result/fault events of the HTTPService occur asynchronously after the cleanUp method is returned. The browser waits only till the onbeforeunload function (the js clean_up function) returns. Unless you call event.preventDefault() from that function, the page will be closed. Note that calling preventDefault() will result in an ok/cancel popup asking:
Are you sure you want to navigate away from this page?
Press OK to continue, or Cancel to stay on the current page.
If the user selects OK, the browser will be closed nevertheless. You can use the event.returnValue property to add a custom message to the popop.
//tested only in Firefox
window.addEventListener("beforeunload", onUnload, false);
function onUnload(e)
{
e.returnValue = "Some text that you want inserted between " +
"'Are you sure' and 'Press OK' lines";
e.preventDefault();
}
You'll never be able to reliably detect the browser code 100% of the time. If you really need to run actions then the safest course of action is to have clients send "i'm still alive" messages to the server. The server needs to track time by client and when a client doesn't send a message within the specified amount of time (with some wiggle room), then run clean-up activities.
The longer you make the time the better, it depends on how time-critical the clean-up is. If you can get away with waiting 5 minutes that's great, otherwise look at 1 minute or 30 seconds or whatever is required for your app.
An alternate way to clean up the session on client side is to use JavaScript and external.interface class in as3. Here is sample code:
JavaScript:
function cleanUp()
{
var process;
var swfID="customRightClick";
if(navigator.appName.indexOf("Microsoft") != -1){
process = window[swfID];
}else
{
process = document[swfID];
}
process.cleanUp();
}
and in the as3 class where the clean up function is defined use this:
import flash.external.ExternalInterface;
if (ExternalInterface.available)
{
ExternalInterface.addCallback("cleanUp", cleanUp);
}
function cleanUp():void {// your code }

Categories

Resources