• 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

VPS Starter Arubacloud
0 głosów
575 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 173 wizyt
pytanie zadane 27 listopada 2016 w HTML i CSS przez Paweł Łozowski Nowicjusz (180 p.)
0 głosów
1 odpowiedź 5,647 wizyt
0 głosów
1 odpowiedź 236 wizyt
pytanie zadane 27 grudnia 2018 w JavaScript przez KubaLaska Początkujący (350 p.)

92,452 zapytań

141,262 odpowiedzi

319,077 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...