[SOLVED][JS] Funkcja getElementById zwraca null

0

Życie jest brutalne. W ramach pisania skryptu, dodającego pasek "podziel się tym", natknąłem się na problem, że wszystkie elementy, wybierane metodą getElementById. Elementy o podanym ID istnieją, a jakże.

var FH = document.getElementById('firstHeading');
FH.innerHTML = 'test';

A efekt zwraca taki:

Błąd: FH is null
Plik źródłowy: http://nonsensopedia.wikia.com/index.php?title=U%C5%BCytkownik:Michalwadas/monobook.js&action=submit
Wiersz: 140

Po siedmiu godzinach prób obejścia tego, nie mam pomysłu. Przepraszam.
EDIT: jeszcze jedno - implementacja jQuery odpada.

0

Jesteś w stanie zrobić paczkę z dokumentem i skryptem, który w ten sposób nie działa? I uploadować to na jakiś serwer do ściągnięcia? Ew. możesz wrzucić ten skrypt na Nonsensopedię i dać link do gotowej podstrony z błędem. Bo na stronie, którą masz w powyższym wykazie jako Plik źródłowy takiego błędu nie ma. Gdy wykonuję w jej kontekście podane przez Ciebie dwie linijki kodu, działają bez najmniejszego problemu (w Firefoxie 3.6 -- a Ty w czym sprawdzasz? to w sumie nie powinno mieć znaczenia; getElementById działa generalnie wszędzie z bardzo drobnymi odchyłami).

Zachowaj spokój :). Skupmy się na namierzeniu błędu. Na pewno jest to jakaś prosta rzecz. Funkcja getElementById na pewno nie jest zepsuta -- z pewnością ktoś by to już zauważył ;). Proszę o praktyczną, gotową stronę z (nie)działającym kodem. W ten sposób mógłbym to zdebugować i uwzględnić wszystko. Może np. odnosisz się do zmiennej FH nie tylko w tym miejscu, ale również wcześniej, gdy ma jeszcze wartość null pochodzącą z poprzedniej deklaracji z inicjalizacją? To pewnie coś takiego.

Ew. firstHeading znajduje się w innej ramce niż skrypt.

0

albo .. po prostu napisz tu deklarację elementu o id 'firstHeading' .. div , czy czego tam użyłeś.

Albo napisz kod całej strony.. jeśli nie jest zbyt wielki.

0

Sprawdzam w Firefoxie, sprawdzałem też w Operze.
Opera daje coś takiego:

JavaScript - http://nonsensopedia.wikia.com/index.php?title=U%C5%BCytkownik:Michalwadas/monobook.js&action=submit
Uncaught exception: TypeError: Cannot convert 'FH' to object
Error thrown at line 2, column 0 in http://nonsensopedia.wikia.com/index.php?title=U%C5%BCytkownik:Michalwadas/monobook.js&action=submit:
    FH.innerHTML = 'test';

Ew. możesz wrzucić ten skrypt na Nonsensopedię i dać link do gotowej podstrony z błędem.

To tak nie działa - nie można wrzucać skryptów na stronę konkretną, nie posiadając uprawnień administratora. Można tylko dodawać skrypty, które będą używane tylko po stronie konkretnego użytkownika. Więc najprostsza metoda to założyć konto, wejść na stronę Użytkownik:Nazwa_użytkownika/monobook.js, wpisać tam podany kod, wcisnąć przycisk "Podgląd".

Może np. odnosisz się do zmiennej FH nie tylko w tym miejscu, ale również wcześniej, gdy ma jeszcze wartość null pochodzącą z poprzedniej deklaracji z inicjalizacją

Niestety nie. Ten prosty kawałek sprawia problem.

Jesteś w stanie zrobić paczkę z dokumentem i skryptem, który w ten sposób nie działa?

Nie jestem niestety.

albo .. po prostu napisz tu deklarację elementu o id 'firstHeading' .. div , czy czego tam użyłeś.

Ten sam rezultat dla każdego elementu. Niezależnie od nazwy. Ale na życzenie:
<h1 id="firstHeading" class="firstHeading">Nonsensopedia:Głosowanie na administratora/Ciemnowidz (2)</h1>

Ew. firstHeading znajduje się w innej ramce niż skrypt.

Wątpię, czy to, że skrypt jest uruchamiany z zewnętrznego pliku, może robić różnicę.

<script type="text/javascript" src="/index.php?title=U%C5%BCytkownik:Michalwadas/monobook.js&amp;action=raw&amp;ctype=text/javascript"></script>
</head>
0

Hmm a nie możesz po prostu wkleić tu kodu HTML strony, na której to testujesz? Sam kod HTML. Weź zrób sobie ten "Podgląd" czy cokolwiek i wstaw tu kod HTML, jaki to wypluje. Zewnętrzne skrypty nie będą działały gdy sobie zrobię z tego plik na localu, ale ustawię sobie <base /> i skrypty powinny się wczytać.

To, że skrypt jest dodawany z zewnątrz nie ma znaczenia.

Oprócz jednej rzeczy...

Skrypt dodajesz w head. Jeśli w tym skrypcie natychmiast odnosisz się do jakiegoś elementu z ciała dokumentu (z wnętrz elementu body), to to nie zadziała. Bo skrypt jest ściągany i wykonywany NATYCHMIAST gdy przeglądarka zobaczy tag <script ...>. Czyli skrypt jest odpalany gdy przeglądarka będzie kończyła przetwarzanie znacznika <head>, ale jeszcze nie zacznie <body>. Więc skrypt nie zobaczy niczego w <body>.

Rozwiązanie: sprawić, by kod odnoszący się do elementów DOM był wykonywany dopiero po załadowaniu strony. Pogooglaj o "onload", ale lepiej metodą addEventListener/attachEvent.

Prawdopodobnie to właśnie jest problemem. Jest to zachowanie jak najbardziej poprawne i logiczne i na szczęście lekarstwo jest bardzo proste.

edit:

A co mi tam, sam wykazałeś się chęciami, więc dam Ci gotowca (pisałem z palca i bez sprawdzania, czyt. mogą być literówki)...

addEventListener(window, 'load', initShare);

function initShare() {
  // tu Twój kod
  var FH = document.getElementById('firstHeading');
  FH.innerHTML = 'test';
}

function addEventListener(element, eventName, callback, useCapture) {
  if (element.addEventListener) {
    element.addEventListener(eventName, callback, useCapture || false);
  } else if (element.attachEvent) {
    element.attachEvent('on' + eventName, callback);
  } else {
    return false;
  }
  return true;
}

Być może Nonsensopedia ma już jakąś funkcję będącą odpowiednikiem addEventListener...

0

Rozwiązanie: sprawić, by kod odnoszący się do elementów DOM był wykonywany dopiero po załadowaniu strony. Pogooglaj o "onload", ale lepiej metodą addEventListener/attachEvent.

Tak, to było to. Problem rozwiązany. Dziękuję.

Być może Nonsensopedia ma już jakąś funkcję będącą odpowiednikiem addEventListener...

Jest i znalazłem.

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