Czasem będziesz chciał, żeby kilka elementów odpowiadało na wydarzenia albo zmiany statusu i robiło to z łatwością. Aby tego dokonać można użyć rozgłaszaczy.
Przekazywanie atrybutu polecenia
Widzieliśmy już, że elementy takie jak przyciski mogą być podczepione do komend. Dodatkowo, jeśli umieścisz atrybut
w elemencie disabled
, jakikolwiek element podczepiony do niej również stanie się nieaktywny. Jest to użyteczny sposób aby jak najbardziej skrócić pisany przez Ciebie kod. Technika ta działa również na inne atrybuty. Na przykład jeśli umieścisz atrybut command
w elemencie label
, każdy przycisk podczepiony do niej będzie miał taką samą etykietę.command
<command id="my_command" label="Otwórz"/> <button command="my_command"/> <checkbox label="Open in a new window" command="my_command"/>
W tym przykładzie przycisk nie ma atrybutu
, ale jest podczepiony do komendy, która go ma. Przycisk będzie dzielił nalepkę/podpis z komendą. Pole wyboru ma już etykietę, jednak będzie ona nadpisana przez nalepkę komendy. Rezultat będzie taki, że zarówno przycisk jak i pole wyboru będą miały taką samą etykietę 'Otwórz'.label
Jeśli chciałbyś zmodyfikować atrybut
polecenia, etykieta przycisku i pola wyboru zostaną odpowiednio dostosowane. Widzieliśmy już coś takiego w poprzedniej sekcji, gdzie atrybut label
był dostosowywany raz i status ten propagował się na inne elementy.disabled
To przekazywanie atrybutu jest bardzo użyteczne w kilku przypadkach. Na przykład powiedzmy, że chcemy zdezaktywować akcję Wstecz w przeglądarce. Powinniśmy zdezaktywować komendę Wstecz w menu, przycisk Wstecz na pasku zadań, skrót klawiaturowy (np. Alt+Lewo) i wszelkie inne komendy Wstecz na menu popup. Chociaż moglibyśmy napisać skrypt, który by to robił, to jest to trochę uciążliwe. Posiada ponadto tę wadę, że musielibyśmy znać wszystkie miejsca gdzie Wstecz mogłoby się znajdować. Jeśli ktoś dodałby nowy przycisk Wstecz używając linku, nie byłby on obsłużony. Dlatego wygodniej jest po prostu zdezaktywować akcję Wstecz i sprawić, że wszystkie podczepione elementy same się zdezaktywują. Możemy użyć przekazywania atrybutu komend, aby uzyskać taki efekt.
Rozgłaszacze
Podobnym elementem jest
. Rozgłaszacze wspierają przekazywanie atrybutów w taki sam sposób jak komendy. Różnicą jest to, że komend używa się do akcji, a rozgłaszaczy do przekazywania informacji o statusie. Na przykład broadcaster
będzie użyta do akcji takiej jak Wstecz, Wytnij albo Usuń. command
byłby użyty np. do przekazania flagi oznaczającej czy użytkownik jest online czy nie. W pierwszym przypadku elementy menu i przyciski paska zadań musiałyby być zdezaktywowane, gdy nie istniała żadna strona, do której można by wrócić, albo nie było tekstu do wycięcia czy usunięcia. W drugim przypadku wiele elementów UI musi być zaktualizowanych, gdy użytkownik przechodzi z modu offline do online.broadcaster
Najprostszy rozgłaszacz jest pokazany poniżej. Powinieneś zawsze używać atrybutu
, żeby inne elementy mogły się do niego odnosić.id
<broadcasterset> <broadcaster id="isOffline" label="Offline"/> </broadcasterset>
Każdy element obserwujący rozgłaszacza będzie automatycznie zmodyfikowany, gdy tylko rozgłaszacz zmieni swój atrybut
. Rezultatem będzie posiadanie przez te elementy nowej nalepki. Podobnie jak inne nie wyświetlane elementy, element label
służy jako przechowalnia dla rozgłaszaczy. Powinieneś zdeklarować wszystkich rozgłaszaczy w elemencie broadcasterset
, żeby mogły być przetrzymywane razem.broadcasterset
Making elements observers
Elementy, które obserwują rozgłaszacza nazywane są obserwatorami. Aby zrobić z elementu obserwatora, dodaj do niego atrybut
. Jest to analogiczne do używania atrybutu observes
, podczas dołączania elementu do command
. Na przykład w celu uczynienia przycisku obserwatorem rozgłaszacza z poprzedniego przykładu:command
<button id="offline_button" observes="isOffline"/>
Atrybut
został nałożony na przycisk i jego wartość została ustawiona na wartość observes
rozgłaszacza. Tutaj przycisk będzie obserwował rozgłaszacza, który ma id id
isOffline
. Jeśli wartość atrybutu
rozgłaszacza zmieni się, obserwatorzy będą zaktualizowani i ich atrybuty label
też się zmienią.label
Moglibyśmy kontynuować z dodatkowymi elementami, ponieważ jeden rozgłaszacz może być obserwowany przez tyle elementów, ile tylko chcesz. Możesz także mieć tylko jednego obserwatora, ale mało na tym zyskasz, ponieważ głównym celem rozgłaszacza jest powiadamianie wielu elementów na raz. Powinieneś używać rozgłaszaczy tylko wtedy, gdy chcesz, aby wiele elementów obserwowało jeden atrybut. Poniżej zdefiniowano kilka dodatkowych obserwatorów:
<broadcaster id="offline_command" label="Offline" accesskey="f"/> <keyset> <key id="goonline_key" observes="offline_command" modifiers="accel" key="O"/> </keyset> <menuitem id="offline_menuitem" observes="offline_command"/> <toolbarbutton id="offline_toolbarbutton" observes="offline_command"/>
W tym przykładzie zarówno
jak i label
będą przekazane od rozgłaszacza do klucza, elementu menu i przycisku. Klucz nie zrobi użytku z żadnego otrzymanego atrybutu, ale będzie on zdezaktywowany w tej samej chwili co rozgłaszacz.accesskey
Możesz użyć rozgłaszacza do obserwacji jakiegokolwiek atrybutu chcesz. Obserwatorzy wyłapią wszystkie wartości każdego atrybutu rozgłaszacza, jeśli tylko się zmienią. Gdy tylko wartość jakiegokolwiek atrybutu rozgłaszacza się zmieni, obserwatorzy zostaną powiadomieni i sami odpowiednio dostosuję swoje atrybuty. Jednak, jeśli obserwatorzy posiadają atrybuty, których nie ma rozgłaszacz, to nie będą one zmienione. Wyjątek stanowią atrybuty
i id
; one nigdy nie są zmieniane. Możesz też używać swoich własnych atrybutów, jeśli chcesz.persist
Rozgłaszacze nie są tak często używani jak komendy, ponieważ te ostatnie mogą dokonać więcej. Jedna rzecz godna odnotowania to fakt, że w rzeczywistości nie ma różnic pomiędzy elementem
a elementem command
. Obydwa wykonują tę samą funkcję. Różnica jest bardziej znaczeniowa. Używaj komend do akcji, a rozgłaszaczy do statusów. W rzeczywistości każdy element może być rozgłaszaczem, póki tylko go obserwujesz za pomocą atrybutu broadcaster
.observes
Element observes
Jest również sposób na to, aby dokładniej określić który atrybut rozgłaszacza ma dany element obserwować. Wymaga to elementu
. Tak jak jego odpowiednik atrybutu, pozwala Ci na zdefiniowanie elementu-obserwatora. Element observes
powinien być umieszczony jako potomny elementowi, którego chcemy uczynić obserwatorem. Przykład jest podany poniżej:observes
<broadcasterset> <broadcaster id="isOffline" label="Offline" accesskey="f"/> </broadcasterset> <button id="offline_button"> <observes element="isOffline" attribute="label"/> </button>
Do elementu
dodano dwa atrybuty. Pierwszy - observes
- wyszczególnia id rozgłaszacza do obserwowania. Drugi - element
- wyszczególnia atrybut do obserwacji. Rezultatem jest to, że przycisk otrzyma swoją nalepkę od rozgłaszacza, a gdy ona się zmieni, nalepka przycisku też odpowiednio się zmieni. Element attribute
nie zmienia się, ale element, którego jest on częścią się zmienia, jest to w tym przypadku przycisk. Zauważmy, że observes
nie został przekazany przyciskowi, ponieważ to nie on jest obserwowany. Jeśli chcesz, żeby był, musisz dodać kolejny element accesskey
. Jeśli nie chcesz używać żadnych elementów observes
, a zamiast tego użyć atrybutu observes
bezpośrednio dla przycisku, to obserwowane będą wszystkie atrybuty.observes
Zdarzenia rozgłaszacza
Jest jeszcze dodatkowy manipulator wydarzeń, którego możemy umieścić w elemencie
ustawionym na observes
onbroadcast
. Wydarzenie jest wywoływane gdy tylko obserwator zauważy zmianę atrybutu rozgłaszacza, któremu się przygląda. Poniżej podany jest przykład:
<broadcasterset> <broadcaster id="colorChanger" style="color: black"/> </broadcasterset> <button label="Test"> <observes element="colorChanger" attribute="style" onbroadcast="alert('Color changed');"/> </button> <button label="Observer" oncommand="document.getElementById('colorChanger').setAttribute('style','color: red');" />
Zostały stworzone dwa przyciski, jeden oznaczony "Test", a drugi - "Obserwator". Jeśli klikniesz na przycisk "Test", nic specjalnego się nie stanie. Jednakże, jeśli klikniesz na przycisk "Obserwator", wydarzą się dwie rzeczy. Najpierw przycisk zmieni się i pojawi się na nim czerwony tekst, a potem ukaże się okno komunikatu z informacją "Zmienił się kolor" ( "Color changed" ).
To co się dzieje, to wywołanie manipulatora
, gdy użytkownik naciska przycisk. Skrypt dostaje odnośnik do rozgłaszacza i zmienia jego styl, tak aby oncommand
color
był czerwony (
red
). Sam rozgłaszacz nie reaguje na tą zmianę, ponieważ nie jest wyświetlany na ekranie, ale pierwszy przycisk jest obserwatorem i zauważa zmianę stylu.
i element
w attribute
wykrywają tą zmianę. Styl zostaje zaaplikowany na przycisk natychmiastowo.observes
Następnie, ponieważ pojawiła się informacja do rozgłoszenia, zostaje wywołany manipulator wydarzeń onbroadcast
. Rezultatem tego jest pojawiające się okno komunikatu. Zauważmy, że informacja do rozgłoszenia pojawia się tylko wtedy, gdy atrybuty w elemencie
się zmieniają. Bezpośrednia zmiana stylu przycisków nie spowoduje jej pojawienia się, a więc nie ukaże się też okno komunikatu.broadcaster
Jeśli spróbujesz skopiować kod pierwszego
kilka razy, skończy się to tym, że pojawi się seria komunikatów, po jednym dla każdego przycisku. Dzieje się tak, ponieważ każdy z nich jest obserwatorem i będzie powiadamiany, gdy zmieni się styl.button
Następnie zajmiemy się używaniem Obiektowego Modelu Dokumentu (Document Object Model, DOM) z elementami XUL.