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

Podpinanie jednej funkcji z argumentem pod addEventListener

Object Storage Arubacloud
0 głosów
828 wizyt
pytanie zadane 20 lipca 2017 w JavaScript przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 20 lipca 2017 przez plkpiotr

Piszę stronę z formularzem rejestracji w HTML/PHP. Chciałbym, aby po kliknięciu na kolejne elementy formularza (input-text, input-password, date, select) pojawiała się poniżej każdego z nich informacja jak poprawnie wypełnić to pole...

Chciałbym zapytać, czy istnieje możliwość podpięcia jednej funkcji (wyświetlającej podpowiedź) z argumentem, będącym liczbą/obiektem, coś na wzór mojej funkcji, czy może każdy element formularza trzeba podpiąć do odpowiadającej mu funkcji?

Niedziałający skrypt:

var allFormElements = document.querySelectorAll('.field');

var allInformation = document.querySelectorAll('.info');
len = allInformation.length;
for (var i = 0 ; i < len; i++)
    allInformation[i].innerHTML = "&#8203;";

function displayInfo(number) {
    switch(number) {
        case 0:
            allInformation[0].innerHTML = "tip first";
            break;
        case 1:
            allInformation[1].innerHTML = "info first";
            break;
        case 2:
            allInformation[2].innerHTML = "next info";
            break;
        case 3:
            allInformation[3].innerHTML = "next tip";
            break;
        case 4:
            allInformation[4].innerHTML = "next tip";
            break;
        case 5:
            allInformation[5].innerHTML = "next tip";
            break;
        case 6:
            allInformation[6].innerHTML = "next tip";
            break;
        case 7:
            allInformation[7].innerHTML = "next tip";
            break;
        case 8:
            allInformation[8].innerHTML = "next tip";
            break;
    }
}

allFormElements[0].addEventListener('click', displayInfo(0));
allFormElements[1].addEventListener('click', displayInfo(1));
allFormElements[2].addEventListener('click', displayInfo(2));
allFormElements[3].addEventListener('click', displayInfo(3));
allFormElements[4].addEventListener('click', displayInfo(4));
allFormElements[5].addEventListener('click', displayInfo(5));
allFormElements[6].addEventListener('click', displayInfo(6));
allFormElements[7].addEventListener('click', displayInfo(7));

Struktura strony:

<!DOCTYPE HTML>
<html lang="en-GB">
<head>
    <meta charset="utf-8">
    <meta name="description" content="Registration form web application's for group of squash players">
    <meta name="keywords" content="squash, team, games, matches, players, society, app, registration, sign, in">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Join | Squash Court</title>
    <link rel="icon" href="img/ball.png">
    <link rel="stylesheet" href="css/style.css">
    <link href="https://fonts.googleapis.com/css?family=Titillium+Web:400,700&amp;subset=latin-ext" rel="stylesheet">
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
          integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
    <script src="js/jquery-3.2.1.min.js"></script>
    <script src="js/samePositionBackAndReload.js"></script>
</head>
<body>
    <header>
        <div class="bar">
            <a href="get-to-know-squash-court-better">Home</a>
        </div>
    </header>
    <main>
        <div class="container">
            <header>
                <h1>
                    Join
                </h1>
            </header>
            <article>
                <form method="post">
                    <input type="text" name="name" placeholder="name" id="cursor" class="field">
                    <div class="info"></div>
                    <input type="text" name="surname" placeholder="surname" class="field">
                    <div class="info"></div>
                    <input type="text" name="nick" placeholder="nick" class="field">
                    <div class="info"></div>
                    <input type="password" name="password_first" placeholder="password" class="field">
                    <div class="info"></div>
                    <input type="password" name="password_second" placeholder="confirm password" class="field">
                    <div class="info"></div>
                    <input type="text" name="team" placeholder="team" class="field">
                    <div class="info"></div>
                    <input type="text" name="birthday" min="1901-01-01" max="2013-12-31" placeholder="birth"
                           onfocus="(this.type='date')" class="field">
<!--                    change in js-->
                    <div class="info"></div>
                    <select name="sex" class="field">
                        <option value="" disabled selected>woman/men</option>
                        <option value="woman">woman</option>
                        <option value="man">man</option>
                    </select>
                    <div class="info"></div>

                </form>
            </article>
        </div>
    </main>
    <script src="js/setInfoOnJoinPage.js"></script>
    <aside>
        <div class="socials">
            <span class="tile1">
                <a href="https://github.com/plkpiotr">
                    <i class="fa fa-github-alt" aria-hidden="true"></i>
                </a>
            </span>
            <span class="tile2">
                <a href="https://forum.pasja-informatyki.pl/user/Za%C4%87wilichowski">
                    <i class="fa fa-code" aria-hidden="true"></i>
                </a>
            </span>
            <span class="tile1">
                <a href="https://plus.google.com/u/0/100065018101140624093">
                    <i class="fa fa-google" aria-hidden="true"></i>
                </a>
            </span>
        </div>
    </aside>
    <footer>
        <p class="signature">All rights reserved &nbsp;|&nbsp; SquashCourt &nbsp;|&nbsp; 07/2017</p>
    </footer>
</body>

 

1 odpowiedź

+1 głos
odpowiedź 20 lipca 2017 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 21 lipca 2017 przez plkpiotr
 
Najlepsza
allFormElements[0].addEventListener('click', displayInfo(0));

Jako drugi parametr powinieneś przekazać referencję do funkcji, która zostanie dopiero wywołana z przekazaniem jej jako parametr obiekt zdarzenia.

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

target.addEventListener(type, listener[, options]);

listener

    The object which receives a notification (an object that implements the Event interface) when an           event of the specified type occurs. This must be an object implementing the EventListenerinterface,     or a JavaScript function.

Jeśli chcesz przekazać własne parametry, to przekaż funkcję anonimową, w której dopiero wywołasz swoją funkcję:

element.addEventListener( 'click', function() {
    myFunction( parameter );
} );

Sposób, w który przekazałeś drugi parametr zadziałałby, gdyby wywołana funkcja zwracała jakąś funkcję - wtedy ona została by wywołana jako callback i do niej trafiłby obiekt zdarzenia, przykład:

function getEventHandler( dummyArg ) {
    return function( event ) {
       /** ta funkcja zostanie wywołana przez EventListener */
    }
}

element.addEventListener( 'click', getEventHandler( 'dummyParameter' ) );

Funkcje w JavaScript to obiekty, których kod możesz wywołać (nazywają się konkretnie First Class Function) - do tego służą dwa okrągłe nawiasy na końcu, często z przekazaniem tam parametrów. Jako, że są to obiekty, możesz je po prostu przekazać jako parametr - co spowoduje że będą one mogły zostać wywołane ze środka jako callback. Jeśli przekazujesz funkcję, którą od razy wywołujesz, to de facto przekazujesz wynik wykonania danej funkcji.

Całość natomiast, żeby się nie powtarzać 8 razy - umieść w pętli albo zastosuj event delegation - podłączasz EventListener na wspólnym rodzicu wszystkim pól formularza i tam za pośrednictwem event.target wykrywasz, w które pole kliknąłeś i co ma się dziać.

1
komentarz 20 lipca 2017 przez ScriptyChris Mędrzec (190,190 p.)
edycja 20 lipca 2017 przez ScriptyChris

Przykład, dlaczego funkcje są obiektami - możesz im przypisywać normalnie propertisy, jak zwykłym obiektom:

function foo( arg ) {
    console.log('foo invoked');
}
foo.prop = 'Test prop';

console.log(foo);
foo();

/** Rezultat wyswietlenia funkcji w konsoli i wywolania jej kodu */
//
//  function foo( arg )
//  prop: "Test prop"
//  arguments: null
//  caller: null
//  length: 1
//  name: "foo"
//  prototype: Object
//  __proto__: function ()
//  [[FunctionLocation]]: VM2236:1
//  [[Scopes]]: Scopes[1]
//    
//  foo invoked

Użycie console.dir() wyświetla zmienne w postaci obiektów (można zobaczyć ich propertisy, co console.log nie zawsze robi).

komentarz 21 lipca 2017 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 21 lipca 2017 przez plkpiotr

Dziękuję za pomoc! Wszystko wyjaśnione na różne sposoby i w dodatku z przykładami - bardzo pomocne dla kogoś kto dopiero raczkuje w JS.
Kod po refaktoryzacji i zastosowaniu porad wygląda znacznie lepiej:

var fields = document.querySelectorAll('.field');

var information = document.querySelectorAll('.info');
len = information.length;
for (var i = 0 ; i < len; i++) {
    information[i].innerHTML = "&#8203;";
    fields[i].addEventListener('focus', getEventHandler(i));
}

function getEventHandler(number) {
    return function(event) {
        switch(number) {
            case 0:
                information[0].innerHTML = "Name should have from 3 to 15 characters";
                break;
            case 1:
                information[1].innerHTML = "Surname should have from 3 to 20 characters";
                break;
            case 2:
                information[2].innerHTML = "Nick should have from 6 to 10 characters";
                break;
            case 3:
                information[3].innerHTML = "Password should from 6 to 15 characters";
                break;
            case 4:
                information[4].innerHTML = "Confirm your password, please...";
                break;
            case 5:
                information[5].innerHTML = "Enter name of team to meet your friends (from 6 to 20 characters)";
                break;
            case 6:
                information[6].innerHTML = "Enter your date of birth and ";
                break;
            // other options later...
        }
    }
}

 

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

Spróbuj jeszcze przerobić kod, aby wykorzystać Event Delegation.

Dodatkowo - poczytaj czym są domknięcia, ponieważ skorzystałeś w switch z parametru number, który został "zapamiętany" przez zwróconą funkcję anonimową przyjmującą event. Warto wiedzieć, dlaczego kod działa tak a nie inaczej, aby wraz z nabywanym doświadczeniem, bardziej świadomie go pisać.

Podobne pytania

0 głosów
3 odpowiedzi 181 wizyt
pytanie zadane 25 marca 2018 w PHP przez Mebya Użytkownik (700 p.)
0 głosów
2 odpowiedzi 641 wizyt
0 głosów
1 odpowiedź 203 wizyt

92,565 zapytań

141,416 odpowiedzi

319,597 komentarzy

61,948 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!

...