This post comes from the first version of this blog.
Please send me an email if anything needs an update. Thanks!

Liczba “lubiących” stronę mojego blogu na Facebooku nieubłaganie zbliża się do 50, więc kilka dni temu stwierdziłem, że “zasugeruję” moim znajomym możliwość dołączenia do tego zacnego grona. Ze względu na to, że trochę tych znajomych już się na liście zebrało, fajnie byłoby w jakiś sposób zautomatyzować proces ich wybierania, zamiast “klikać” po kolei każdego z nich. Problem, jak każdy inny, wydał mi się ciekawy, a więc przystąpiłem szybko do poszukiwania rozwiązania. ;]

Facebook: Formularz "Suggest to Friends".

Jak wszyscy wiemy, język JavaScript został stworzony po to, aby pozwolić programiście na zarządzanie już załadowaną zawartością strony internetowej. Dzięki temu możliwe są tzw. "dynamiczne" operacje związane z wszelkiego rodzaju pokazywaniem, przesuwaniem, ukrywaniem, dodawaniem i innymi tego typu animacjami.

Facebook oferuje funkcjonalność o nazwie “Suggest to Friends”, której zadaniem jest wysyłanie tzw. “notyfikacji” do strony, która według nas zainteresuje naszych znajomych. Jak nietrudno zauważyć, w momencie kliknięcia linka do “formularza sugestii” zostaje nam podana jak na tacy lista znajomych, a więc następuje wspomniane wyżej “załadowanie zawartości”, na którą nie mamy dalszego wpływu. Aby wybrać osoby, którym chcemy wysłać informację, należy wpisać je w pole wyszukiwarki, bądź “wyklikać” na liście - nie ma tu żadnej zaawansowanej filozofii.

Ale czy na pewno tak jest? Jak wyżej napisałem, język JavaScript pozwala na wykonywanie operacji na zawartości już załadowanej strony. Spróbujmy więc wykorzystać tą możliwość do ułatwienia sobie życia w tym konkretnym przypadku.

JavaScript: Zaznaczanie wszystkich znajomych.

Przeglądając kolejne pozycje zwrócone przez wyszukiwarkę na różne zapytania związane z moim problemem w pewnym momencie natrafiłem na bardzo ciekawy fragment kodu JavaScript:
1
javascript:elms=document.getElementById('friends').getElementsByTagName('li');for(var fid in elms){if(typeof elms[fid] === 'object'){fs.click(elms[fid]);}}

Nie brzmi zbyt przyjaźnie, prawda? Strona, na której go znalazłem reklamowała go jako receptę na problem zaznaczania znajomych właśnie na liście formularza sugestii. Szybko przeskanowałem te kilka linijek oczami i stwierdziłem, że faktycznie, to może zadziałać. Wkleiłem kod w odpowiednie miejsce, [Enter]… po odczekaniu kilku chwil kod w końcu przestał się wykonywać, load spadł do kilku procent [ech, ten jeszcze jednordzeniowy procesor z HT ;]], a moim oczom ukazała się lista znajomych w piękny sposób podświetlona, co oznaczało ni mniej, ni więcej, niż sukces.

Ze względu na to, że nie lubię, jak coś “tylko działa”, niedługo po wysłaniu formularza przystąpiłem do studiowania tego fragmentu kodu, aby dowiedzieć się, co za tajemne sztuczki zostały w nim użyte. Pierwszym wartym uwagi elementem jest sama deklaracja:

1
javascript:

Otóż można wykonać kod JavaScript w zakresie aktualnie wyświetlanej zakładki / strony w… pasku adresu przeglądarki. Owo “odpowiednie” miejsce, w które wkleiłem kod z pierwszego listingu to właśnie pasek adresu - to bardzo przydatna sztuczka pozwalająca na szybkie testowanie krótkich fragmentów kodu.

Następnym ważnym elementem jest pierwsza instrukcja kończąca się średnikiem:

1
elms=document.getElementById('friends').getElementsByTagName('li');

Lista znajomych jest przechowywana w kontenerze o id #friends, gdzie, zgodnie z semantyką kodu HTML, w liście znajdują się kolejne elementy “li”, przez co ich pobranie i zapisanie kolekcji w zmiennej jest bardzo prostą czynnością. Najpierw, poprzez metodę getElementById() pobierany jest sam kontener, by potem można było wyciągnąć z niego wszystkie tagi metodą getElementsByTagName().

Drugą i właściwie ostatnią instrukcją w najwyższym bloku kodu jest pętla for:

1
for(var fid in elms){...}

Iterujemy w niej po wszystkich elementach, dla każdego wykonując instrukcje, które pozwoliłem sobie w tym miejscu wykropkować. Przejdźmy więc do umieszczonego w ciele pętli warunku:

jsif(typeof elms[fid] === 'object'){...}

W tym miejscu sprawdzamy, czy element pobranej w pierwszej instrukcji kolekcji na pewno jest obiektem, tj. czy na pewno możemy na nim operować, nie ryzykując nieprzyjemnego błędu, który mógłby zatrzymać wykonanie naszego skryptu. Język JavaScript potrafi czasem być aż za bardzo “dynamiczny”, przez co zawsze powinniśmy się upewniać, czy żądany zasób jest tym, czego oczekujemy. Ostatnim fragmentem kodu jest zawartość bloku warunku:

jsfs.click(elms[fid]);

Nie zaglądałem aż tak głęboko w kod Facebooka, ale jedynym elementem, który jak na razie “nie tłumaczy się sam” jest zmienna fs. Wygląda na to, że ta zmienna jest już zdefiniowana w formularzu sugestii, a więc możemy ją po prostu wykorzystać. Po sposobie wykorzystania widać, że najprawdopodobniej reprezentuje ona kod obsługujący sam formularz, poprzez metodę click() zaznaczającą, bądź odznaczającą konkretnego znajomego (elms[fid]) na liście. Sposób przekazania zmiennej do metody click() świadczy o tym, że oczekuje ona odwołania do elementu drzewa DOM (zmienna elms to właśnie kolekcja takich obiektów), stąd taka konstrukcja.

Mam nadzieję, że dzisiejszy wpis pomoże Wam w tej jakże trudnej sytuacji i oszczędzi nieco palce zniszczone przez ciągłe wykorzystywanie klawiatury i myszki. ;]