• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

JS - Otwarcie o okna wpisanie i wprowadzenie wartości do inputów w pętli

Object Storage Arubacloud
0 głosów
596 wizyt
pytanie zadane 21 lutego 2017 w JavaScript przez arek01996 Stary wyjadacz (12,100 p.)

Witam,

Mam poważny problem ze skryptem. Skrypt ma otworzyć okna jakiejś strony wprowadzić dane i kliknąć przycisk.

Wszystko było okej jak robiłem to dla jednego okna super to działało. Niestety kiedy chciałem to zrobić w pętli dla wielu okien skrypt nie działa. Co prawda otwiera okna ale nie wprowadza danych do input. Tylko dla ostatniej otwartej strony skrypt wprowadza dane do pola input. Nie rozumiem dlaczego to nie chce działać.\

Poniżej kod:

function tryGoOn(currentWindow)
        {
            var ile = 0;

            if (localStorage.click && currentWindow.document.readyState == "complete") {

                var errorDiv = currentWindow.document.getElementsByClassName("error_box");
                if(errorDiv.length == 0)
                {
                    var currentCookie = showCookie('coords');
                    if(currentCookie.charAt(currentCookie.length-1) != " "){
                        currentCookie = currentCookie + " " + localStorage.click + " ";
                    }else
                        currentCookie = currentCookie + localStorage.click + " ";

                    setCookie('coords', currentCookie);
                    currentWindow.close();
                }else
                {
                    currentWindow.close();
                }

                localStorage.clear();

            } else {
                var timmer = setTimeout(tryGoOn, 100, currentWindow);
            }
        }

 

/// JAKIŚ NIEISTOTNY KOD

//TUTAJ TA NIESZCZĘSNA PĘTLA

            for(i = 0; i<1; i++)
            {
                for(j = 0; j<2; j++)
                {
                    var index = (i*n+j);

                    var openWindow = window.open(url);
                    handle[index] = openWindow;

                    tryGoOn(handle[index]);

                    handle[index].addEventListener('load', function(){

                        var spearInput = handle[index].document.getElementById("unit_input_spear");
                        spearInput.value = 10;

                        var coordClass = handle[index].document.getElementsByClassName("target-input-field target-input-autocomplete")[0];
                        coordClass.value = coord;

                        var send = handle[index].document.getElementById("target_attack").click();

                        localStorage.setItem('click', coord); 
                    }, false); 
                }
            }

 

komentarz 21 lutego 2017 przez ScriptyChris Mędrzec (190,190 p.)

Cały addEventListener zamknij w IIFE

( function( idx ) {
 handle[idx ].addEventListener('load', function(){
          /** kod Twojej funkcji */
   }, false); 
}( index ) );

i zamiast odnosić się wewnątrz listenera do zmiennej index, odnoś się do idx (przekazanej jako parametr).

Druga opcja, to deklaruj oba iteratory (oraz j) słówkiem let.

komentarz 22 lutego 2017 przez arek01996 Stary wyjadacz (12,100 p.)
Działa chociaż nie mam pojęcia czym się to rózni od poprzedniej.

Jesteś w stanie wyjaśnić?

Dziękuje i pozdrawiam.
komentarz 22 lutego 2017 przez ScriptyChris Mędrzec (190,190 p.)

EventListener reaguje asynchronicznie, czyli pętla zdąży zakończyć się nim nastapi zdarzenie, które listener wykryje i odpali funkcje. Gdy pętla kończy swój obieg, to iterator pętli ma przypisaną ostatnią wartość, dlatego efektem jest działanie dla ostatniej strony.

Korzystając z IIFE, tworzysz nowy scope, w którym iterator zostaje przechowany jako lokalna zmienna, dzięki czemu mimo że listener już po zakończeniu pętli może wykryć zdarzenie to odpalony callback będzie miał dostęp do konkretnego iteratora, a nie ostatniego.

W przypadku deklaracji zmiennych przy pomocy let poczytaj to: http://www.2ality.com/2015/02/es6-scoping.html#%3Ccode%3Elet%3C%2Fcode%3E_in_loop_heads

komentarz 22 lutego 2017 przez arek01996 Stary wyjadacz (12,100 p.)
Dziękuje bardzo za obszerną odpowiedź!

Jednak na takim poziomie widać róznicę jak ktoś przestawia się z C# czy C++ :)

Najmocniej przepraszam, że dopytuje ale musze się dowiedzieć.

Skrypt aktualnie otwiera wszystkie karty od razu i mam problem z tym ze do zmiennej localStorage zapisuje się ostatnia wartość i z pętli i wszystkie karty na niej operują a ja chce żeby każda operowała na swojej wartości przypisanej w tryGoOn;

nie mogę podać zwykłej zmiennej bo skrypt odświeża stronę przez event .click();
Moje pytanie czy da się przekazać do tryGoOn w jakiś sposób dla każdego otwartego okna inne wartości?

Lub też czy da się zrobić tak że skrypt w pętli czeka, aż funkcja tryGoOn() zakończy działania po czym otworzy nową kartę itd aż do zakończenia pętli?

Bo funkcja tryGoOn działa na zasadzie wywołania siebie aż do załadowania strony potem wykonuje coś tam i funkcja już nie jest wywołana aż do kolejnego obrotu pętli.

Będę niezmiernie wdzięczny za pomoc!
komentarz 22 lutego 2017 przez ScriptyChris Mędrzec (190,190 p.)

Spróbuj przekazywać jako parametr albo do Storage obiekt, w którym kluczami będą nazwy okien (lub wyrażenie, po którym będziesz mógł je rozpoznać) a wartością będzie obecna zmienna. Dzięki temu dla konkretnego okna (klucz w obiekcie) przekażesz określoną wartość.

czy da się zrobić tak że skrypt w pętli czeka, aż funkcja tryGoOn() zakończy działania po czym otworzy nową kartę itd aż do zakończenia pętli?

Pętla nie może zaczekać - JavaScript jest jednowątkowy i synchroniczny. Działania asynchroniczne wykonuje przeglądarka, która gdy korzystasz z asynchronicznych funkcji zwraca zazwyczaj jakiś callback. Ten callback jest wykonywany gdy JS zakończy bieżące funkcje (aktualny stack trace).

Prosty przykład:

setTimeout( function() {
	console.log( 'Uruchamiam się na końcu :(' );
}, 0 );

function logSomething() {
	console.log( 'Hello world...'  );
}

var something = function() { return 2 + 3 };

logSomething(); // Hello world...
something(); // 5

// Uruchamiam się na końcu :(

Mimo, że setTimeout zapisany był na samym początku, to i tak uruchomił się na końcu - bo JavaScript wykonał kod synchronicznie i dopiero, gdy "nie miał nic do roboty" to odpalił callback z setTimeout.

komentarz 22 lutego 2017 przez arek01996 Stary wyjadacz (12,100 p.)

Ponownie jestem wdzięczny za obszerny komentarz.

Wracając do tego aby karty otwierały się po kolei. Czy byłby sposób zrobienia tego np w taki sposób?
 

var iterator = 0;

function x()

{

if... cos tam to otwórz okno wykonaj kod i zamknij okno, następnie zwieksz iterator o 1

else settimeout(x);

}

 

komentarz 23 lutego 2017 przez ScriptyChris Mędrzec (190,190 p.)

Twój powyższy kod może być. Wtedy będziesz miał lepszą kontrolę nad iteratorem - będziesz mógł go zwiększać pod określonym warunkiem i w konkretnym momencie. W pętli for iterator zwiększa się automatycznie za każdym razem, gdy kompilator dotrze do końca bloku pętli - możesz ten proces jedynie przerwać (słówko brake) albo pominąć iterację (słówko continue).

localStorage.setItem('click', coord); 

To jest to zapisywanie zmiennej dla wszystkich okien? A chciałbyś dla każdego okna oddzielną zmienną? Nie za bardzo rozumiem. Jeśli tak, to zapisuj po prostu jakąś nazwę zamiast "click" - dlaczego tak nie zrobisz?

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
2 odpowiedzi 175 wizyt
pytanie zadane 27 listopada 2016 w HTML i CSS przez Paweł Łozowski Nowicjusz (180 p.)
0 głosów
1 odpowiedź 5,692 wizyt
0 głosów
1 odpowiedź 241 wizyt
pytanie zadane 27 grudnia 2018 w JavaScript przez KubaLaska Początkujący (350 p.)

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,960 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...