🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

6 total messages Started by Jivanmukta Sun, 11 Nov 2018 20:49
getElementById zwraca null
#408746
Author: Jivanmukta
Date: Sun, 11 Nov 2018 20:49
68 lines
2716 bytes
Napisałem:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="pl">
<head>
...
<script type="text/javascript">
$(document).ready(function () {
     ...
     // tu przypisania funkcji submitForm i animateMainTitle
     ...
});
</script>
</head>
...
<body>
...
<table id="top" border="0">
<caption><h1 id="main_title">...</h1></caption>
...
</table>
...
<form action="http://localhost/~robert/announcement/insert" 
id="announcement" name="announcement" enctype="multipart/form-data" 
method="post" accept-charset="utf-8">
...
<div id="property_pictures_field">
     ...
     <input multiple='multiple' type='file' id='property_pictures' 
name='property_pictures[]' class='multi' 
accept='gif|jpg|jpeg|jpe|bmp|png|gif87|gif89a|mpg|mpeg|mpe|mov|avi|wmv|vob|ogm|ogv' 
value='Wybierz plik' tabindex='61'>        </div>
     ...
</div>
...
</form>
...
</body>
</html>

Czasami mam błędy JavaScript w konsoli przeglądarki (testowałem pod 
FireFoxem, Operą, Chrome):

function submitForm() {
     ...
     alert(document.getElementById("property_pictures_field")); // OK
     var pp = document.getElementById("property_pictures").value; // 
CZASAMI BŁĄD: getElementById JEST null
     ...
}

function animateMainTitle() {
     ...
     mainTitle = document.getElementById("main_title").innerHTML;    // 
CZASAMI BŁĄD: getElementById JEST null
     ...
}

Pliki .html, .css, .js przechodzą pomyślnie walidację.
Nie mam innego elementu o id='property_pictures' ani innego o 
id="main_title", literówki w id nie ma.
DOM dokument jest załadowany w chwili wywołania.
Nie usuwam elementów property_pictures ani main_title przy pomocy 
JavaScript.
Przejrzałem w Google strony "getElementById returns null" i nie 
znalazłem przyczyny mojego błędu.
Prosiłbym o podpowiedź co robię źle.
Re: getElementById zwraca null
#408747
Author: Marek S
Date: Sun, 18 Nov 2018 17:56
38 lines
2613 bytes
W dniu 2018-11-11 o 21:49, Jivanmukta pisze:

> Pliki .html, .css, .js przechodzą pomyślnie walidację.
> Nie mam innego elementu o id='property_pictures' ani innego o 
> id="main_title", literówki w id nie ma.
> DOM dokument jest załadowany w chwili wywołania.
> Nie usuwam elementów property_pictures ani main_title przy pomocy 
> JavaScript.
> Przejrzałem w Google strony "getElementById returns null" i nie 
> znalazłem przyczyny mojego błędu.
> Prosiłbym o podpowiedź co robię źle.

Taki błąd powstaje raczej tylko w przypadku gdy DOM nie jest w pełni 
załadowany. Nic innego mi do głowy nie przychodzi. A kiedy może się tak 
dziać? Z praktyki webdewelopera  najczęściej to:

1. Jakiś skrypt zmienia / przebudowuje strukturę dokumentu. Również może 
to być refresh.

2. Strona ładuje się i następuje chwilę potem przekierowanie do jej 
samej (3xx). Sprawdź po stronie sieci w narzędziach czy nie ma czegoś 
takiego.

Ustaw też w na początku funkcji animateMainTitle jakiś log do konsoli by 
sprawdzić czy nie następuje podwójne wywołanie w samym JS.

3. Ponadto z nazwy w/w funkcji wnioskuję iż naruszasz strukturę DOM by 
coś zanimować. Nie wiem jak konkretnie animujesz więc tylko zgaduję. 
Jeśli np. używasz innerHTML gdzieś dalej do zapisu, to wtedy takie cuda 
mogą się dziać. Nie należy używać do tego celu innerHTML bo jest 
strasznie wolne gdyż wymusza odświeżanie _CAŁEJ_ struktury DOM. Wtedy 
okresowo możesz tracić dostęp do DOM mimo iż pozornie wydaje Ci się, że 
nic się w niej nie zmienia. To dość częsty błąd początkujących 
programistów JS a i zaawansowani czasem też o tym nie wiedzą.

-- 
Pozdrawiam,
Marek
Re: getElementById zwraca null
#408748
Author: Jivanmukta
Date: Mon, 19 Nov 2018 07:54
33 lines
2299 bytes
> 3. Ponadto z nazwy w/w funkcji wnioskuję iż naruszasz strukturę DOM by 
> coś zanimować. Nie wiem jak konkretnie animujesz więc tylko zgaduję. 
> Jeśli np. używasz innerHTML gdzieś dalej do zapisu, to wtedy takie cuda 
> mogą się dziać. Nie należy używać do tego celu innerHTML bo jest 
> strasznie wolne gdyż wymusza odświeżanie _CAŁEJ_ struktury DOM. Wtedy 
> okresowo możesz tracić dostęp do DOM mimo iż pozornie wydaje Ci się, że 
> nic się w niej nie zmienia. To dość częsty błąd początkujących 
> programistów JS a i zaawansowani czasem też o tym nie wiedzą.
> 

// Animuj literkę w napisie tytułowym:

var letterIndex = -1;
var mainTitle;

function animateMainTitle() {
     'use strict';
     if (mainTitle === undefined) {
         mainTitle = document.getElementById("main_title").innerHTML;
     }
     letterIndex = (letterIndex + 1) % mainTitle.length;
     var s = mainTitle.substr(0, letterIndex) +
             '<span class="selected_letter">' +
             mainTitle.substr(letterIndex, 1) +
             '</span>' +
             mainTitle.substr(letterIndex + 1);
     document.getElementById("main_title").innerHTML = s;
     setTimeout(animateMainTitle, 100);
}

Czy gdybym zamiast innerHTML umieścił wszystkie literki w span'ach i 
ustawiał tylko atrybut class odpowiedniej literki to byłoby lepiej?
Re: getElementById zwraca null
#408749
Author: Jivanmukta
Date: Mon, 19 Nov 2018 08:31
48 lines
2894 bytes
W dniu 19.11.2018 o 08:54, Jivanmukta pisze:
> 
>> 3. Ponadto z nazwy w/w funkcji wnioskuję iż naruszasz strukturę DOM by 
>> coś zanimować. Nie wiem jak konkretnie animujesz więc tylko zgaduję. 
>> Jeśli np. używasz innerHTML gdzieś dalej do zapisu, to wtedy takie 
>> cuda mogą się dziać. Nie należy używać do tego celu innerHTML bo jest 
>> strasznie wolne gdyż wymusza odświeżanie _CAŁEJ_ struktury DOM. Wtedy 
>> okresowo możesz tracić dostęp do DOM mimo iż pozornie wydaje Ci się, 
>> że nic się w niej nie zmienia. To dość częsty błąd początkujących 
>> programistów JS a i zaawansowani czasem też o tym nie wiedzą.
>>
> 
> // Animuj literkę w napisie tytułowym:
> 
> var letterIndex = -1;
> var mainTitle;
> 
> function animateMainTitle() {
>      'use strict';
>      if (mainTitle === undefined) {
>          mainTitle = document.getElementById("main_title").innerHTML;
>      }
>      letterIndex = (letterIndex + 1) % mainTitle.length;
>      var s = mainTitle.substr(0, letterIndex) +
>              '<span class="selected_letter">' +
>              mainTitle.substr(letterIndex, 1) +
>              '</span>' +
>              mainTitle.substr(letterIndex + 1);
>      document.getElementById("main_title").innerHTML = s;
>      setTimeout(animateMainTitle, 100);
> }
> 
> Czy gdybym zamiast innerHTML umieścił wszystkie literki w span'ach i 
> ustawiał tylko atrybut class odpowiedniej literki to byłoby lepiej?

Zrobiłem tak i jest dobrze:

var letterIndex = 0;
function animateMainTitle() {
     'use strict';
     document.getElementById('letter' + letterIndex).className = '';
     letterIndex = (letterIndex + 1) % 24;
     document.getElementById('letter' + letterIndex).className = 
'selected_letter';
     setTimeout(animateMainTitle, 100);
}

Dzięki za pomoc.
Re: getElementById zwraca null
#408750
Author: Marek S
Date: Mon, 19 Nov 2018 21:57
19 lines
1524 bytes
W dniu 2018-11-19 o 08:54, Jivanmukta pisze:

>      document.getElementById("main_title").innerHTML = s;

No więc widzę, że trafiłem w sedno :-) Standardowy błąd.

> Czy gdybym zamiast innerHTML umieścił wszystkie literki w span'ach i 
> ustawiał tylko atrybut class odpowiedniej literki to byłoby lepiej?

Zdecydowanie lepiej. A jeśli z jakiegoś powodu musisz zmieniać HTML, to 
rób to tym:

https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

Po to powstała ta funkcja by nie używać innerHTML.

-- 
Pozdrawiam,
Marek
Re: getElementById zwraca null
#408751
Author: Jivanmukta
Date: Mon, 17 Dec 2018 14:04
24 lines
1887 bytes
W dniu 2018-11-19 o 22:57, Marek S pisze:
> W dniu 2018-11-19 o 08:54, Jivanmukta pisze:
>
>>      document.getElementById("main_title").innerHTML = s;
>
> No więc widzę, że trafiłem w sedno :-) Standardowy błąd.
>
>> Czy gdybym zamiast innerHTML umieścił wszystkie literki w span'ach i
>> ustawiał tylko atrybut class odpowiedniej literki to byłoby lepiej?
>
> Zdecydowanie lepiej. A jeśli z jakiegoś powodu musisz zmieniać HTML, to
> rób to tym:
>
> https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
>
> Po to powstała ta funkcja by nie używać innerHTML.
>

Programowania z wykorzystaniem innerHTML nauczyłem się z książek...
Dzięki za pomoc.

---
Ta wiadomość została sprawdzona na obecność wirusów przez oprogramowanie antywirusowe Avast.
https://www.avast.com/antivirus
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads