[JS] BBCode na wielu inputach

0

<font size="3">Witam.</span>

W JavaScript napisałem sobie funkcję BBTextMod(). Po jej wywołaniu, pobiera ona zaznaczony tekst i dodaje na jego początku i końcu znaczniki - przekazane do funkcji jako ostatnie 2 parametry.
Pierwszy parametr jaki przyjmuje to obiekt na którym dokonywane jest zaznaczenie. I tutaj zaczynają się schody.

Potrzebuję, aby przycisk który wywołuje funkcję BBTextMod(), nie odwoływał się na sztywno do jakiegoś tam konkretnego TEXTAREA o nazwe TRESC, tylko do dowolnego pola typu INPUT w całym formularzu, w którym obecnie został zaznaczony tekst.

Oto kod:

...
<script>
...
function BBTextMod (input, startTag, endTag){ ... }
</script>
...
<form>
<textarea name="tresc"></textarea>
<input type="submit" value="Pogrubienie" onClick="BBTextMod(this.form.tresc, '[b]', '[/b]');">
<form>
...

Czy jest jakaś metoda, która zwraca obiekt, na którym dokonywane jest zaznaczenie?
Proszę o pomoc :)

0

Widzę dwa niebezpośrednie sposoby na implementację, oba związane z tym, że aby tekst w jakimś polu był zaznaczony, to musi ono posiadać focus.

  1. Dać wszystkim elementom formularza zdarzenie focus, które ustawia jakąś zmienną focused_element na this (czyli na element, na którym nastąpiło zdarzenie focus). Dodatkowo, w każdym elemencie możesz dodać zdarzenie blur, które ustawiałoby focused_element na null. W ten sposób zmienna focused_element zawsze będzie ustawione na element, który ma focus, lub na null (jeśli zainicjujesz ją nullem).

Ten sposób jest o tyle dobry, że łatwo ograniczyć działanie focused_element tylko do elementów formularza. Dodam jeszcze, że NIE NALEŻY wstawiać na pałę zdarzeń onfocus/onblur bezpośrednio w HTML, tylko użyć interfejsu umożliwiającego dostęp do drzewa dokumentu -- czyli DOM, czy ew. rozszerzenia przeglądarek typu form.elements.

  1. Skorzystać z obiektu document.activeElement. Działa on podobnie jak nasz utworzony w punkcie 1 focused_element, tyle że dostarcza go sama przeglądarka. Uwzględnia on jednak wszystkie elementy w dokumencie, nie tylko te z jakiegoś tam formularza, więc prawdopodobnie musiałbyś sprawdzać, czy document.activeElement należy do formularza.
0

Rozwiązanie nr 1. wydaje się być sensowniejsze :)

A więc:

...
<script>
...
function BBTextMod (input, startTag, endTag){ ... }
var focusedObj = null;
</script>
...
<form>
<textarea name="tresc" onFocus="focusedObj = this"></textarea>
<input type="submit" value="Pogrubienie" onClick="BBTextMod(focusedObj, '[b]', '[/b]');">
<form>
...

I działa :)
Dzięki bswierczynski

0

[facepalm]

Widzę, że moją sugestię nr 1 potraktowałeś bardzo wybiórczo... Spoko, jak się trochę więcej postarasz, to może Ci się uda jeszcze bardziej zaśmiecić HTML :[

I może jeszcze wciśniesz do niego więcej błędów, bo w końcu przeglądarki je wybaczają, więc po co się trzymać głupich specyfikacji, co nie? Microsoft tak samo myślał olewając na parę lat rozwój IE i teraz jest fajnie, że nadal użeramy się z IE6 i jego zgodnością ze standardami, hm? A nie, czekaj... ;)

0

Twoje rozwiązanie zaimplementowałem sobie na miarę swoich potrzeb.
Nie będę rozmawiał z Tobą o błędach o 01:20, bo ledwo widzę na oczy ;>
Jutro rano na to jeszcze spojrzę.
"może jeszcze wciśniesz do niego wiecej bledow" xD

Bywasz strasznie atakujący w swoich wypowiedziach panie Webmaster ;)

0

No wiesz, jak się nawet nie czyta wypowiedzi w całości:

Dodam jeszcze, że NIE NALEŻY wstawiać na pałę zdarzeń onfocus/onblur bezpośrednio w HTML, tylko użyć interfejsu umożliwiającego dostęp do drzewa dokumentu -- czyli DOM, czy ew. rozszerzenia przeglądarek typu form.elements

Bywasz strasznie atakujący w swoich wypowiedziach panie Webmaster ;)

Nie przejmuj się, niektórzy mają gorsze fazy...

0
rav88 napisał(a)

Bywasz strasznie atakujący w swoich wypowiedziach panie Webmaster

Przepraszam za to co odebrałeś jako osobisty atak. Nie napisałem wyraźnie jednej rzeczy: bywam atakujący, ale atakuję kod. To nic osobistego. Dodatkowo nie twierdzę, że np. ja tworzę zawsze idealny kod. Co prawda nie był to żaden atak otwarcie osobisty, ale też otwarcie nie napisałem, że taki nie jest, a ludzka mózgownica działa jak działa i dlatego jeśli chcesz zastosować skuteczną konstruktywną krytykę to powinieneś najpierw sobie obić tyłek blachą (tj. np. napisać, że nie piszesz o tym i o tamtym).

Muszę jeszcze przyznać, że coś osobistego i nieobiektywnego w tej mojej wypowiedzi było. Uznałem -- być może mając ku temu zbyt małe podstawy -- że Twój poziom jest na tyle wysoki, że mogę Cię trochę... zmotywować do pisania kodu o wyższej jakości. Bywają przypadki beznadziejne (choć mam nadzieję, że tylko chwilowo) i być może prędzej odpuszczę takim, bo ich i tak nie jestem w stanie zreformować w kilku postach (choć staram się to robić małymi kroczkami).

Wiesz w ogóle, co to specyfikacja (X)HTML? Zdajesz sobie sprawę, że HTML może być poprawny lub nie? Słyszałeś o czymś takim jak validator?

Zauważyłem w Twoim kodzie parę dobrych rzeczy i stąd może niesłusznie wziąłem Cię za kogoś, kto jest na takim poziomie, że -- gdyby się przykładał -- pisał by kod frontendowy naprawdę wysokiej jakości. Nazwa Twojej funkcji sugeruje zastosowanie standardu nazewnictwa. Nawet fakt, że wyciąłeś z kodu jej (nieistotną w tym momencie) dobrze o Tobie świadczy. Podobnie jak sensowne i spójne nazewnictwo parametrów. Cały post też był w miarę składny.

Hmm, a może... może jesteś całkiem niezłym programistą, ale po prostu nie specjalizujesz się we frontendzie? Może HTML, CSS i JavaScript to nie to, co robisz najlepiej? Dość często bywa tak, że całkiem nieźli programiści lekceważą te języki. HTML dla nich to pestka. Prosty JavaScript też, choć nie wykorzystują w pełni możliwości tego języka (bo wcześniej nie programowali w języku funkcyjnym z dziedziczeniem prototypowym). Co do HTML-a to skupiają się na czymś, co działa, ale nie znają standardów jakości kodu. I wszystko to mimo tego, że w swoim oryginalnym języku (np. PHP) są naprawdę nieźli i przykładają się do tego, by kod był dobry.

Czy jesteś kimś takim? W takim razie masz prawo nie wiedzieć pewnych rzeczy o kodzie frontendowym. Apeluję tylko, byś je przyswoił. Jeśli będziesz chciał, to mogę nawet napisać o co chodzi.

Sęk w tym, że napisałem to już w pierwszym poście -- fragment cytował Demonical Monk. Ale radośnie to zignorowałeś ;). Zresztą czasami zastosowany przez Ciebie "śmiecący" sposób może być całkiem OK, jednak w ogólności warto znać technikę tzw. nieinwazyjnego JavaScriptu. I na pewno warto znać reguły pisania poprawnego HTML-a. Walidacja kodu to tak jakby kompilacja. Wyobraź sobie, że gdy używasz XHTML-a, to parser przeglądarki po napotkaniu błędu składni może zamiast Twojej strony wyświetlić tzw. żółty ekran śmierci. To odpowiednik błędu składni w innym języku. To, że amatorzy takie błędy olewają nie oznacza, że dobrzy programiści mogą sobie na to pozwolić.

Dlatego też całkiem się zdarza, że to ci dobrzy dostają ochrzan -- z nadzieją, że nie wezmą tego do siebie (to krytyka kodu, nie ich osoby) i że, jak na pragmatycznego programistę przystało, będą chcieli swój kod ulepszyć.

0

@bswierczynski dobrze pisze.

Podsumowując, każdy normalny człowiek powinien dążyć do nieustającego rozwoju...

@rav88 Jak już opanujesz podstawy js, poznaj jakąś bibliotekę, w stylu JQuery.
Takie rzeczy uzyskasz w dużo mniejszej ilości kodu, prościej, a co najfajniejsze w nich, to że ich projektanci z góry przyjęli, że nikt nie będzie już syfił html kodem js, dlatego takie pozytywne zabiegi robi się dzięki nim w bardzo bezstresowy sposób.

Poza tym, warstwa prezentacji aplikacji, to zawsze ciężka sprawa jest...:/

0

Widzę, że przeze mnie wywiązała się cała dyskusja :)

Wybacz moją ignorancję, bo z mojej wypowiedzi faktycznie wynikło, że nie przeczytałem dwóch linijek treści jaką podesłałeś. Po prostu szukałem prostego rozwiązania skupiając się na swoim algorytmie, umilając jednocześnie użytkownikowi pracę dzięki dobrom JavaScriptu. Wykorzystanie DOM ""dla idei" wymusiło by na mnie jakąś dodatkową godzinę poznania go :P

Zarazem moim zdaniem zastosowanie modelu DOM w tym skrypcie nie optymalizowało by kodu aż tak bardzo bo:

  • zdarzenia onFocus muszę dodać tylko do 3/4 pól tekstowych i każde jest generowane w pętli przez PHP.
    Przy bardziej skomplikowanych szablonach oczywiście ma to sens. Natomiast u mnie w kodzie jest to 2x onClick - raz na prototypie input'a, a raz na textarea :)

Tobie zapewne chodziło o coś takiego (na tyle na ile poznałem DOM):

<script type="text/javascript>
...
function Constructor()
 {
 document.getElementById("trescKomentarza").onfocus = setFocusedObj;
 }
function setFocusedObj()
 {
 focusedObj = this;
 }
</script>
...

<body onLoad="Constructor();">
...
</body>

...czy coś podobnego.
Przyznaję, że JS dopiero poznaję i na razie stosuję sporadycznie, a jak do tej pory - niechętnie. Stąd z resztą moja pytanie. :P Większość skryptów, które piszę wykonują się po stronie serwera w czystym PHP (paradygmat niestety na razie strukturalny).

Co do pisania stron wg. standardów grupy W3C, to stosuję się. Obecnie np. wszystko piszę w HTML 4.01 i często zmagam się z validatorem ;) Kod który wysłałem był pisany z palca na potrzeby mojego pytania i miał odzwierciedlać tylko problem. Prosił bym o nie sugerowanie się nim, bo W3 przyczepiło by się chociażby o to że elementy zawarte w <form> .. </form> nie są w tabeli albo el. blokowych.

0

Pomijając błędne (nieistniejące) "onFocus" zamiast "onfocus", to co jest nie tak w tym kodzie? Że jest parametr prosto w tagu, a nie dodany dynamicznie? To zakrawa o święty puryzm i czepianie się byle się przyczepić.

rav88: pisz onfocus, onload - nie onFocus, onLoad

0

@Marooned:
onFocus działa i jest poprawne w HTML-u, ale nie w XHTML-u (i nie w JavaScripcie) i być może dlatego -- jak zauważyłeś -- rzeczywiście uznawane jest za złą praktykę.

W kodzie oprócz tego brakuje paru atrybutów. Część z nich jest nieobowiązkowa w HTML-u 5, ale wątpię, by autor z niego właśnie korzystał. Brakuje czegoś w form, w script....

Generalnie o dziwo dopiero teraz wpadłem na pomysł, że kod może być tylko makietą stworzoną na potrzeby forum, a nie rzeczywistym, przeklejonym kodem z wyciętymi niepotrzebnymi fragmentami :D. Całkiem możliwe, że za bardzo się podjarałem.

Czy uważasz za rozdzielenie zachowania, struktury i prezentacji za "święty puryzm"? Hmm. Cóż... masz prawo. Skoro napisałeś jeszcze, że czepianie się do tego to "czepianie się byle się przyczepić", to sugeruje to, iż uważasz to rozdzielenie za rzecz niepraktyczną / mało istotną (skoro sama w sobie nie ma wystarczającego znaczenia, żeby to odnotować). I do tego masz prawo.

W pewnych warunkach zresztą takie wstawianie kodu w linię jest wydajniejsze. I często, gdy trzeba podpiąć zdarzenia do mniejszej liczby elementów, ilość całkowitego kodu jest sporo mniejsza niż gdyby użyć DOM (który jest koszmarnie niewygodnym, niezgrabnym interfejsem). Z drugiej jednak strony zmniejszenie plików HTML ma spore znaczenie dla szybkości działania strony, bo pliki te przeważnie nie mogą być buforowane przez przeglądarkę, w przeciwieństwie do zewnętrznych skryptów.

Zauważ też proszę, że w tamtym kodzie mamy wstawione w linię nie tylko wywołania funkcji z paroma argumentami, ale również pojawiło się nam... przypisanie do zmiennej globalnej. Czyli po prostu kawałeczki JavaScriptu.

A właśnie. Weź zdebuguj taki kod. Zmienna globalna -- nie wiadomo gdzie jest przypisywana. Przypisania rozsiane są po wielu miejscach kodu HTML. Zmienne globalne bywają źródłem wszelkiego zła! W przypadku małych skryptów często upraszczają ich pisanie i to jest OK, ale gdy na stronie masz tego więcej, robi się problem z utrzymaniem.

Dodatkowo, zauważ proszę, że takie coś przejdzie:

<input ... onclick="klikmieto_przycisk()">

Strona się załaduje bez błędu, mimo że jest tam literówka: klikmieto_przycisk. I teraz pytanie, czy ktoś to przetestuje przed opublikowaniem, czy na stronie będzie wisiał przez parę dni błąd.

Zaś jeśli byłoby coś takiego:

myapp.evt.addOnload(function() {
  var przycisk = ...;
  myapp.evt.addEventListener(przycisk, 'click', klikmieto_przycisk);

  function kliknieto_przycisk() { ... }
});

To interpreter JS wywali błąd od razu przy załadowaniu strony, bo nie ma identyfikatora klikmieto_przycisk.

Więc generalnie gdy masz sporo JavaScriptu to IMHO korzyści z rozdzielenia warstw są jak najbardziej praktyczne i wymierne. Jest jednak możliwe, że w tym wypadku za bardzo się podjarałem. @rav88 zdaje się mieć swój rozum i dobrze; chcę tylko zwrócić uwagę na rzeczy, które powinien sobie sam ocenić. A że niby zastosował moją radę, ale olał coś, co explicite napisałem, to inna sprawa ;).

A tak w ogóle to najfajniej może być, gdy elementy interfejsu mające sens tylko w JavaScripcie tworzysz... w JavaScripcie. Wtedy żadne googleboty czy mobilniacy z powyłączanymi skryptami nie dostają całego tego niepotrzebnego kodu (a pozostali mogą go mieć zcache'owanego!). Wymaga to oczywiście rozdzielenia warstw i jest zgodne z zasadą nieinwazyjnego JavaScriptu. No ale do tego trzeba użyć jakiegoś frameworka -- czy to swojego, czy to dostępnego ogólnie. Bo praca w czystym DOM i z ułomnością IE to prawdziwy ból (nawet w przykładzie powyżej nie mogłem po prostu użyć element.addEventListener, tylko wymyślić naprędce jakieś pseudo-środowisko aplikacyjne).

0

No właśnie, dopiero w tym poście wpadłeś na to, co ja uznałem za oczywistość - że w podanym przykładzie jest tylko to, co jest istotne dla przykładu, by nie zaciemniać kodu, bo po co nam tutaj method czy action dla formularza? po nic.

Nie uważam, że rozdzielenie warstw to rzecz niepotrzebna, ale nie uważam też, że należy do tego dążyć za wszelką cenę. Jeśli robię swojego hołmpejdża, na który przychodzą 3 strony na krzyż, to tylko sztuką dla sztuki może być rozbijanie tego w piękne warstwy, stosy plików etc. Tracimy też nieco na przejrzystości - porównaj swoją jedną linijkę z inputem i drugą wersję z kolejnymi linijkami w JS. Jeśli nie tworzymy wielkiego projektu, nad którym pracuje sztab ludzi, który ma być łatwo rozbudowywalny, to uważam to nieco przerostem formy nad treścią.

Podobnie uważam wystrzeganie się tabelek przy interfejsie zamiast divów/spanów z CSSem. Ostatnio w firmie mięliśmy taki przykład.. pewne fragmenty strony zostały zrobione na tabelkach, czas pracy liczony w minutach, śmiga na każdej przeglądarce z dowolną długością treści. Przybył inny człek, purysta, autor kilku książek o HTML/JS i rzekł: tak być nie może! Pozamieniał to na DIVy, dodał tonę styli i... do dziś to się rozjeżdża o parę pikseli zależnie od treści w środku.

Po prostu uważam, że czasem rozwiązania brzydsze są skuteczniejsze i to jest ten moment, kiedy należy ich użyć. Stąd moja awersja do ideologicznych negacji takich rozwiązań.

0

@Marooned:
Tylko trzeba to wszystko robić odpowiedzialnie. Ale tak na serio odpowiedzialnie. A nie że mi się nie chce, to nie zrobię.

Tak jak niektórzy piszą kod bez komentarzy, bo dobry kod czyta się prawie jak komentarz. Faktycznie można tak pisać, ale w rzeczywistości potrafią to tylko nieliczni. A prawdopodobnie znacznie więcej osób myśli, że oni są w tej grupie, gdy tak niestety nie jest.

Co do strony domowej, to ja jakbym robił swoją stronę, to postarałbym się, by była zrobiona przynajmniej bardzo porządnie (o ile nie chciałbym uzyskać ideału). Wszak strona jest pewną wizytówką programisty, szczególnie kogoś pracującego w branży web. Naturalnie nie każdy, kto potrzebuje strony domowej jest programistą (podobno).

Trudno też nieraz ocenić, przez kogo i jak długo nasz kod będzie wykorzystywany. Słyszałeś zapewne, że w większości przypadków kod jest w jakimś tam użyciu dłużej niż planowaliśmy?

Np. tutaj gościu robi jakąś wtyczkę, czy rozszerzenie dla PHP BB. Bardzo popularnego silnika forum. Fakt, wtyczka prawdopodobnie będzie do bani i nikt nie będzie jej używał (i nie mówię tego złośliwie, ani niczego nie oceniam, bo nie mam czego oceniać -- opieram to stwierdzenie jedynie na rachunku prawdopodobieństwa). A co jeśli jednak okaże się bardzo dobra -- czego autorowi szczerze życzę -- i ludzie zechcą ją wstawiać i dostosowywać? Jak się zachowa w obecności innych wtyczek i innego kodu? Albo gdy będzie rozszerzana?

Zgadzam się, że nie warto być totalnym paranoikiem. Tzn. inaczej: są sytuacje, gdy bycie nim wcale nie popłaca, a tylko przeszkadza. Zwykle łatwiej jest jednak napisać jakiś badziew nie wtedy, gdy jest on zupełnie wystarczający, ale wtedy, gdy tak naprawdę przydałoby się to zrobić porządniej, ale po prostu nam się nie chce. I potem się za to płaci.

Co do mojego kodu z poprzedniego przykładu, to takie proste rzeczy z użyciem gotowego frameworka można też napisać jakoś tak:

$('input#moj_przycisk').click(kliknieto_przycisk);

nie potrzeba nawet żadnego DOMReady, bo zewnętrzny skrypt umieszczamy tuż przed </body>, co przyspiesza ładowanie strony. W tym momencie kod nie jest wcale taki wielki i przerażający, prawda?

0

Hm, może należałoby uściślić o jaką stronę domową nam chodzi. Np. taka moja nie jest absolutnie żadną wizytówką.. jeśli mowa o stronie, na której widnieje portfolio, a my szukamy pracy to się zgodzę, że powinna lśnić z każdej strony. Choć jak głosi stara maksyma, szewc bez butów chodzi ;-)

Ładowanie jQuery dla strony, która zajmuje 2kB też uważam za lekkie przegięcie.. chyba po prostu wszystko zależy od przeznaczenia strony - jeśli znamy standardy i umiemy napisać cud miód malinkę webową, to możemy sobie pozwolić na niedbalstwo wiedząc, że tak będzie szybciej, a dana strona ma ograniczony zasięg.

GhostDog - obadaj np. CK editor (dawniej znany jako FCK) - niedawno wyszła całkowicie przepisana od nowa wersja, co chwila wychodzą poprawki, jest dość mocno konfigurowalny. Myśmy go wykorzystali by (na)pisać [prace w toku] edytor dla MediaWiki - wraz z naszym autorskim rewers-parserem z HTMLa na Wikitext.

W HTMLu istnieje element, który można edytować w locie, on jest używany przez edytory WYSIWYG.

0
Marooned napisał(a)

GhostDog - obadaj np. CK editor (dawniej znany jako FCK) - niedawno wyszła całkowicie przepisana od nowa wersja, co chwila wychodzą poprawki, jest dość mocno konfigurowalny. Myśmy go wykorzystali by (na)pisać [prace w toku] edytor dla MediaWiki - wraz z naszym autorskim rewers-parserem z HTMLa na Wikitext.

W HTMLu istnieje element, który można edytować w locie, on jest używany przez edytory WYSIWYG.

Posta z pytaniem usunąłem, bo wystarczyło google, ale dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1