[JS] Jak skrócić te 10 linijek kodu?


(Lightextract) #1
function aha() {

	alert("Ehh!")

}


function wypisz() {

	var c = document.getElementById("clk")

	c.addEventListener("click", aha, false)

}


document.addEventListener("DOMContentLoaded", wypisz, false)

Wszystko ok, fajnie, działa. Chciałbym jednak poznać sposób skrócenia takiego kodu? JS jest dla mnie innym światem i mimo że dałbym radę odnaleźć się w przykładach to dużo szybciej będzie zobaczyć skrócony kod na własnych przykładach. Przyzwyczaiłem się do tradycyjnych języków programowania. Zaleca się wykorzystywanie DOMContentLoaded w addEventListener i uparcie tutaj się tego właśnie trzymam, przez co wywołuje funkcje która przypisuje do zmiennej 'c' element 'clk', a następnie znów nasłuchuje zdarzenie tym razem "click" które jak zostanie wywołane, wykonywana jest zaś kolejna już druga funkcja... i to wszystko tylko po to, aby po kliknięciu w element img wyświetlono alert o treści "Ehh!"...


(mordesku) #2

możesz użyć biblioteki jquery, wtedy kod będzie wyglądał tak:

$(document).ready(function(){

   $("#clk").click(function() {

      alert("Ehh!");

   });

})

(Pablo_Wawa) #3

W Internet Explorerze nie ma funkcji (metody) addEventListener, za to jest attachEvent (uwaga: nieco inna składnia!).

jQuery rozwiązuje problemy zgodności różnych przeglądarek.


(Lightextract) #4

Hehe, wiem że w IE jest attachEvent. Jednak dalej nie wiem jak skrócić ten kod bez żadnych bibliotek... nie da się za bardzo? Oczywiście mając na uwadze zastosowanie DOMContentLoaded do wielu funkcji... chociaż w tym kodzie jest tylko jedna. Spotkałem się z opinią, że zdarzenie DOMContentLoaded powinno wykonywać się tylko raz. Niby było tam jakieś logiczne wytłumaczenie (był to post na forum), jednak trochę dziwne mi się to wydaje...

W JS da się tworzyć funkcje w funkcjach, zgadza się? W takim razie mógłbym wyklecić mniej więcej coś takiego:

document.addEventlistener("DOMContentLoaded", start, false) 

{

     function _a()

          {

          }


     function _b()

          {

          }


     ...

}

Nie sprawdzałem czy działa, napisałem tak mniej więcej. Jak będę pod Linuxem to sprawdzę. Może krótsze to nie bardzo jest, ale przynajmniej lepiej wygląda.


(Pablo_Wawa) #5

Możesz sobie napisać mały kod, który obsłuży te kwestie i podpiąć pod jakąś swoją zdefiniowaną funkcję, a potem dołączać ten kod do swoich skryptów.

To zdarzenie wywołuje przeglądarka, nie masz na to wpływu, na pewno zdarzenie odpali się przynajmniej raz. Nie słyszałem, że może wystąpić kilka razy, ale można się przed tym zabezpieczyć jakąś zmienną, na podstawie której podejmiesz stosowne działanie.


(Lightextract) #6

No ok. Od początku prób nauki JS'a staram się uwierzyć, że jest on niebywale elastyczny, bo taki też mi się wydaje. Zatem trochę pokombinuje i myślę, że do czegoś dojdę. Za bardzo jestem przyzwyczajony do tych mniej elastycznych języków, które mają bardziej restrykcyjne i poszufladkowane zasady :slight_smile: Szkoda tylko, że JS jest kaleczony przez Microsoft, który na siłę nie trzyma się standardów.

Na jQuery przejdę może wtedy, kiedy poznam JS'a do tego stopnia, że nauczę się pisać coś dosyć małego - średniego, ale zaaawansowanego i przede wszystkim o krótkim kodzie :stuck_out_tongue: Tzn. jak najkrótszym się da w JSie.


(Pablo_Wawa) #7

Ten przykład, który podałeś, chyba nie za bardzo jest funkcjonalny (i błędny składniowo). Pomijając też fakt, że nic nie zrobi (każda funkcja musi zostać jakoś wywołana - tu masz tylko deklaracje dwóch funkcji), to dodatkowo jest niefunkcjonalny - nie da się go użytkować uniwersalnie.

Zastanówmy się, co chcesz w ogóle uzyskać i dopiero wtedy napiszemy kod. Jeśli chodzi Ci o uruchomienie jednej lub kilku swoich funkcji w momencie załadowania DOM (czyli zdarzenia DOMContentLoaded), to można to zrobić takim wywołaniem:

function start(f)

{ 

  document.addEventlistener("DOMContentLoaded", f, false);

}

a wywołanie/użycie takiej funkcji wyglądałoby tak:

start(function () { _a(1); _b(2,3); _c(); });

gdzie _a(), _b() i _c() to poszczególne funkcje (z jakimiś parametrami). Oczywiście zamiast takiej konstrukcji można zadeklarować osobną funkcję i w niej umieścić wywołania poszczególnych funkcji (_a, _b i _c). Ale może się tak zdarzyć, że nie wiemy/nie mamy od razy wykazu wszystkich funkcji/akcji, które należy wykonać po załadowaniu DOM. Wtedy można stworzyć tablicę z wywoływanymi funkcjami/akcjami i zmodyfikować nieco przykład

document._atStart=[]; // inicjalizacja tablicy

document.addEventlistener("DOMContentLoaded", function () { for (var i=0;i

function atStart(f)

{ 

  document._atStart.push(f);

}

i wtedy użycie wygląda tak:

atStart(function () { _a(1); });

atStart(function () { _b(2,3); });

atStart(_c);

i może wystąpić w dowolnym miejscu kodu. Jak widać dla przekazywanych parametrów trzeba zrobić dodatkową "otoczkę". Gdyby nie było parametrów, kod byłby o wiele prostszy:

atStart(_a);

atStart(_b);

atStart(_c);

(Lightextract) #8

Właśnie o to mi chodziło. Mimo że wystarczająco wierzyłem, że da się to zrobić w jakiś niekoniecznie skomplikowany i prostszy sposób, to właśnie Ty tu i teraz udowodniłeś mi tak jak niektóre kursy z sieci, że JS jest bardzo elastycznym językiem. Tak elastycznym, że nawet przeczytanie kursu nie wystarczy, aby sobie to wpoić i trzeba praktykować, praktykować i... praktykować. No bo niby że rozumie człowiek jak działa JS i że jest to cudowne, ale trudno jest się do tego przyzwyczaić. Dzięki wielkie :slight_smile: Te dwa pierwsze kawałki kodu już by wystarczyły :stuck_out_tongue:


(Pablo_Wawa) #9

Kod pisałem w notatniku (Notepad++) i nie przetestowałem go w praktyce (ale powinien działać).

Potem można ten kod rozbudować o sprawdzanie błędów (czy podane parametry są funkcjami) oraz uogólnić na inne przeglądarki (głównie IE).

A potem można to jeszcze uogólnić na dowolne zdarzenie - i w efekcie końcowym dostaniemy taką funkcjonalność, jaką daje odpowiednia funkcja jQuery (lub innego frameworka). :slight_smile:

P.S. Dla celów edukacyjnych (żeby się samemu nauczyć JavaScriptu) sugeruję właśnie taką drogę - potem, jak już człowiek dobrze opanuje język, można się przerzucić na używanie jakiegoś frameworka.


(Lightextract) #10

Tyle czytałem o JS'ie, aby zrozumieć jego filozofię działania, sporo zapamiętałem... a przez to, że uważałem że to język bardzo, bardzo zawiły nawet nie miałem świadomości, że da się jakoś normalnie wystartować funkcje typu " nazwaFunkcji(); ". Jakoś przyjąłem myślenie, że tak się da zrobić tylko poprzez onload, DOMContentLoaded w HTMLu i innych zdarzeniach, heh :slight_smile:


(Pablo_Wawa) #11

Ja nie uważam, żeby JavaScript był bardzo zawiły. No ale ja swego czasu programowałem nawet w asemblerze i kodzie maszynowym (sic!), więc mam inne spojrzenie. :slight_smile:

Pamiętaj, że funkcja w JS może zostać przypisania zmiennej (wtedy używasz samej nazwy funkcji - bez nawiasów"()"), a potem wywołana poprzez użycie tej zmiennej (ale już z nawiasami, w których możesz podać parametry do tamtej funkcji). To bardzo elastyczne i wygodne podejście. A "agregować" wywołanie kilku funkcji możesz poprzez "dynamiczne" stworzenie funkcji:

duza = function (a,b,c) { func_a(a); func_b(b); func_c(c); };

duza(1,2,3);

(Lightextract) #12

No to akurat wiem :smiley: Właśnie najwięcej o tego typu sprawach się dowiedziałem, jeżeli chodzi o JS'a, czytając o nim. Po prostu każda zmienna może być wszystkim, jeżeli dobrze zrozumiałem czytając różne kursy itp. :slight_smile: Np. zmienna window.x: obiekt "window", właściwość "x" - może przywierać dowolną postać, jak każdy obiekt w JavaScript. Może to być metoda (funkcja), zwykła właściwość o jakiejś wartości, kolejny obiekt itd. itp. No i to właśnie w JS jest świetne.

Wow - nasz wiek znacznie się różni: 41, a 20 lat to różnica prawie jak "nic" :smiley: