Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Javascript] Wczytanie pliku do tablicy
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
bAb1k
Witam serdecznie.
Jestem jeszcze niezłym laikiem w JacaScript'cie, ale ogólne definicje programowania są mi znane.

Może wkleję na start jakiś fragment kodu, który by coś "zapoczątkował w temacie", a później opiszę o co mi chodzi:

  1. <!DOCTYPE HTML>
  2. <html lang='pl'>
  3. <head>
  4. <title>Pliki z cenami</title>
  5. <meta charset='utf-8' />
  6. </head>
  7. <body>
  8. <input type='file' id='plik' />
  9. <button id='przycisk'>Kliknij</button>
  10. <div id='wynik'></div>
  11.  
  12.  
  13. function Czytaj()
  14. {
  15. document.getElementById('wynik').innerHTML = 'cos sie dzieje';
  16. }
  17.  
  18. document.querySelector('#przycisk').onClick = Czytaj;
  19.  
  20. </script>
  21. </body>
  22. </html>


Jeszcze na wstępie chciałbym napisać, że nie oczekuję gotowców, chciałbym zrozumieć co piszę, abym nie musiał się upominać kolejnymi postami, czy tematami smile.gif

A zatem: Chciałbym wczytać po przez Input 'file' i (najlepiej) od razu załadować plik (o tym za moment), albo dopiero po naciśnięciu button'a. Aktywowałoby to funkcję Czytaj() która by dany plik wczytała i rozłożyła na tablicę (jedna linijka to jeden indeks w tablicy) oraz oczywiście wyświetlenie tych linijek w jakimś div'ie albo czymkolwiek wink.gif.

Z góry dziękuję za pomoc wink.gif

[Dalsze czytanie na własną rękę haha.gif]

Rzecz jasna, później chcę zrobić możliwość edycji danego fragmentu tekstu oraz na koniec funkcję, która by zapisała ten plik (już edytowany) - zatem można się spodziewać również takich pytań/tematów, ale jednak chcę na start zrobić podstawę.

W C# zrobiłbym po prostu wczytanie pliku, przypisanie do zmiennej typu string i splitowanie do tablicy znakiem ENTER (\n - jak się nie mylę?) - no ale w JS to wygląda chyba jakoś inaczej, bo nie mogłem nawet odczytać tego pliku wink.gif
Comandeer
Musisz skorzystać z FileReader: https://developer.mozilla.org/en-US/docs/Web/API/FileReader
A jak już odczytasz to faktycznie split po znaku nowej linii powinien starczyć
bAb1k
Niestety, ale jakoś mi to nie idzie zupełnie ;/.


  1. <!DOCTYPE HTML>
  2. <html lang='pl'>
  3. <head>
  4. <title>Pliki z cenami</title>
  5. <meta charset='utf-8' />
  6.  
  7. </head>
  8. <body>
  9.  
  10. <input type='file' id='plik' onchange='Otworz()'/>
  11. <br><br>
  12. <div id='wynik'>BRAK</div>
  13.  
  14. <script>
  15. var Otworz = function()
  16. {
  17. var plik = document.getElementById('plik');
  18. var fileReader = new FileReader();
  19.  
  20. fileReader.readAsText(plik);
  21. alert(fileReader);
  22. }
  23. </script>
  24. </body>
  25. </html>


No i nic ... nie możesz przeczytać pliku. Wiem, może dla was to banalne, ale w JS się serio gubię ;/.
Comandeer
No to tak:
  • Pole to pole. A Ty chcesz plik, który jest połączony z tym polem. To jednak ciut co innego wink.gif
  • JS to asynchroniczność, asynchroniczność i jeszcze raz eventy wink.gif Owszem, Twój kod plik odczytuje, ale… nic nie robisz z tym faktem. To, że każesz skryptowi czytać to za mało. Musisz sobie poczekać na dane, które FileReader rzuca jako event
  • Warto też poczytać o addEventListener


Wychodzi ostatecznie coś takiego: http://jsfiddle.net/Comandeer/LzpL1t9p/

Asynchroniczność i eventy = podstawa JS
bAb1k
Po wielkich trudach i literówkach (nie lubię kopiować) zaczeło coś wyświetlać. Dzięki wielkie za komentarze, jednak chciałbym się dopytać czy dobrze rozumiem:

Cytat
function(e){ // jakiś kod}


Jest to "indywidualna" funkcja wewnątrz zdarzenia, gdzie argument 'e' oznacza wartość inputa? ( - pytanie czy chodzi o "value" czy nie? a jak nie to o co...) I odwołując się do 'this' mamy na myśli właśnie to 'e'?


Cytat
fileReader.readAsText(file); //każemy mu odczytać nasz plik
jak mam rozumieć owy komentarz? Odczytuje plik w jakiej formie? (może też proste pytania, ale są wątpliwości...)

Samą metodę 'addEventListener' już widziałem - tylko muszę się z nią oswoić i biegnę już do dokumentacji nim zacznę cokolwiek więcej działać wink.gif. Na temat pierwszego parametru 'change' - wszystko jasne - nie ma wątpliwości, a parametr true/false też już rozumiem wink.gif.
Comandeer
Cytat
Jest to "indywidualna" funkcja wewnątrz zdarzenia, gdzie argument 'e' oznacza wartość inputa?

Nie, e oznacza zdarzenie, jakie zaszło (a nie miejsce, w którym zaszło). Pomocne zwłaszcza przy zdarzeniach związanych z klawiaturą czy myszką (gdzie umożliwia pobranie klawisza/przycisku). Samo miejsce zdarzenia to własność e.target
Natomiast this oznacza input jako cały (zatem nie tylko wartość, która jest własnością tego obiektu - this.value) i na którym zaszło zdarzenie e. this oznacza element, do którego przypięliśmy zdarzenie (w naszym przypadku #plik).
Warto też zauważyć, że niekoniecznie zachodzi równość this === e.target, ale to może temat na inny raz wink.gif

Cytat
jak mam rozumieć owy komentarz? Odczytuje plik w jakiej formie?

Jako tekst, więc rzutuje go na typ string.
bAb1k
Jeszcze Cię tutaj zapewne pomęczę (jeżeli nie masz nic przeciwko). Plus taki, że zaczyna mi się powoli wszystko układać w jedną całośc wink.gif. Minus taki, że mam kolejne pytania:


Cytat
var file = this.files[0]
I rozumiem tą linijkę na dwa sposoby.
a) Skoro 'this' oznacza input'a (czyli pewnie "tego inputa" na którym zaszło zdarzenie, to czy tablica plików oznacza, że dany input może mieć w tablicy kilka takich dokumentów/plików/etc. ?
cool.gif Rozumiem też tak, że w dokumencie może być kilka 'inputów' a my pobieramy wartość z tego pierwszego [0].

Cytat
fileReader.readAsText(file);
- zatem skoro piszesz, że odpczytuje go jako tekst (String) to dlaczego nie można go wyświetlić już teraz, tylko jest potrzebna kolejna funkcja do 'załadowania' ?

Znów pewnie proste pytania i banalne. Mimo wszystko proszę o cierpliwość i wyrozumiałość wink.gif.
Comandeer
Kod
this.files[0]

Dany input, jeśli ma nadany atrybut [multiple], może służyć do wybrania kilku plików. Wówczas wszystkie są one dostępne tutaj. Rozumienie na sposób b nie ma za bardzo sensu, bo to nie input jest pierwszym z kolekcji (bo jest tylko jeden), a plik

Cytat
zatem skoro piszesz, że odpczytuje go jako tekst (String) to dlaczego nie można go wyświetlić już teraz, tylko jest potrzebna kolejna funkcja do 'załadowania' ?

Wyobraź sobie, że próbujesz w taki sposób odczytać plik, który ma spory rozmiar (np. 100 MB). Taka operacja może długo potrwać i gdyby FileReader pracował synchronicznie, to cała karta przeglądarki byłaby zamrożona aż do czasu, gdy ten wielki plik by się nie wczytał. Jeśli natomiast całość jest asynchroniczna, to podczas, gdy przeglądarka ten plik wczytuje w tle, user wciąż może korzystać z reszty strony.

Cytat
To jak za pomocą 'addEventListener('click', function(e)...' wydostać zawartość tego <p> ?

Przy pomocy własności innerHTML
bAb1k
Dzięki wielkie wink.gif.

Pierwsza część za mną. Już udało mi się generować tablice i szukam nowego tematu, a jak nie to zakładam nowy, bo tym razem eventu mi nie wykrywa ;/.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.