Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Przedszkole _ [HTML][JavaScript] insertBefore + forEach

Napisany przez: stellatus 26.03.2020, 14:55:12

Utworzyłem element "newItem" (<h3>Water</h3>). Chciałbym go wstawić przed każdym bezpośrednim dzieckiem "div.facetwp-facet-tags" z klasą "facetwp-checkbox". Robię więc pętlę forEach, która za pomocą "insertBefore" wkleja ten "newItem" przed każdym "https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore", czyli zmiennej "element" w tym przypadku. Czy ten tok myślenia jest dobry? Jeżeli tak, to dlaczego to nie działa? Pojawia się: "TypeError: list.insertBefore is not a function".

https://codepen.io/rudolph-reti/pen/QWbJQJr

Kod
<div class="facetwp-facet-tags">
  <div class="facetwp-checkbox" data-value="arbeit">
    Arbeit <span class="facetwp-counter">(4)</span>
    <span class="facetwp-expand">[+]</span>
  </div>
  <div class="facetwp-depth">
    <div class="facetwp-checkbox" data-value="arbeitsrecht">
      Arbeitsrecht <span class="facetwp-counter">(4)</span>
    </div>
    <div class="facetwp-checkbox" data-value="gastronomie">
      Gastronomie <span class="facetwp-counter">(4)</span>
    </div>
  </div>
  <div class="facetwp-checkbox" data-value="autarkie">
    Autarkie <span class="facetwp-counter">(2)</span>
  </div>
  <div class="facetwp-checkbox" data-value="bach-johann-sebastian">
    Bach, Johann Sebastian <span class="facetwp-counter">(1)</span>
  </div>
  <div class="facetwp-checkbox" data-value="ludwig-van-beethoven">
    Beethoven, Ludwig van <span class="facetwp-counter">(1)</span>
  </div>
  <div class="facetwp-checkbox" data-value="behinderten">
    Behinderten <span class="facetwp-counter">(1)</span>
  </div>
  <div class="facetwp-checkbox" data-value="bioinformatik">
    Bioinformatik <span class="facetwp-counter">(1)</span>
  </div>
  <div class="facetwp-checkbox" data-value="christentum">
    Christentum <span class="facetwp-counter">(4)</span>
    <span class="facetwp-expand">[+]</span>
  </div>
</div>

<script>
  const list = document.querySelectorAll("div.facetwp-facet-tags > div.facetwp-checkbox");
  //console.log(list)

  let newItem = document.createElement("h3");
  let textnode = document.createTextNode("Water");
  newItem.appendChild(textnode);

  //console.log(newItem)

  list.forEach(function(element, index, array) {
    list.insertBefore(newItem, element);
  });
</script>

Napisany przez: nospor 26.03.2020, 15:13:37

Komunikat bledu chyba dosc jasno nakierowuje....

list to twoja lista nie element. Element masz w paramatrze funkcji
list.forEach(function(element, index, array) {
element.insertBefore(newItem, element);
});

edit: zas w dokumentacji widze ze to maby rodzic na ktorym jest wykonywany insertBefore wiec

tuMaBycRodzic.insertBefore(newItem, element);

Napisany przez: stellatus 26.03.2020, 15:45:59

Dzięki. Błąd zniknął, ale to insertBefore nie działa tak jak oczekiwałem. Nie wkleja "newItem" przed każdym elementem listy, tylko przed tym, na którym zatrzymuje się pętla. Co zrobić, żeby wkleić "newItem" przed każdym elementem listy?

Kod
const list = document.querySelectorAll("div.facetwp-facet-tags > div.facetwp-checkbox");
  //console.log(list)
const parent = document.querySelector("div.facetwp-facet-tags");
//console.log(parent)

  let newItem = document.createElement("h3");
  let textnode = document.createTextNode("Water");
  newItem.appendChild(textnode);

  //console.log(newItem.innerHTML)

  list.forEach(function(element, index, array) {
    parent.insertBefore(newItem, element);
  });



Napisany przez: nospor 26.03.2020, 15:48:14

Hehe, to dlatego ze zawsze wkladasz dokladnie ten sam element
newItem
I on wedruje pokolei z listy do listy wink.gif
Albo w petli tworz za kazdym razem nowy element do wlozenia, albo go klonuj

Napisany przez: stellatus 26.03.2020, 16:21:48

Dzięki. A jak to zrobić? Nie mam kompletnie żadnego pomysłu (nawet na to co wpisać do googla).

Napisany przez: nospor 26.03.2020, 16:23:23

no toz napisalem co masz zrobic.... masz za kazdym razem tworzyc nowe element do wlozenia

Kod
  //console.log(newItem.innerHTML)

  list.forEach(function(element, index, array) {
let newItem = document.createElement("h3");
  let textnode = document.createTextNode("Water");
  newItem.appendChild(textnode);

    parent.insertBefore(newItem, element);
  });

I juz

Napisany przez: stellatus 27.03.2020, 10:33:44

Dziękuję Ci, bardzo mi pomogłeś.

Zastanawia mnie jedna rzecz. Nie wiem czy poprawnie formułuję to pytanie: dlaczego gdy w pętli deklarowana jest zmienna nie pojawia się błąd redeklaracji?

Napisany przez: nospor 27.03.2020, 10:35:02

Bo ona nie jest deklarowana w petli tylko w funkcji. A to roznica

Napisany przez: stellatus 27.03.2020, 10:44:46

OK, więc żeby lepiej zrozumieć o co tutaj chodzi, to powinienem przestudiować dobrze temat "zakres zmiennych", zgadza się?

Napisany przez: nospor 27.03.2020, 10:53:48

Deklarowana zmienna w funkcji to zmienna lokalna tylko dla tej funkcji.

Ale nawet jakby to nie bylo funkcja tylko petla jak myslales, to i tak to by nie wywolalo bledu. js pozwala na wielokrotne deklarowanie tych samych zmiennych. js nawet pozwala na wielokrotne deklarowanie tych samych funkcji. Ot nowa zmienna/funkcja nadpisze stara. To nie php

Napisany przez: stellatus 27.03.2020, 11:22:57

OK, ale jak się robi redeklarację poza funkcją to wyskakuje błąd. Dlaczego tak jest?

Napisany przez: nospor 27.03.2020, 11:24:10

To pokaz sytuacje z takim bledem, bo ja nie raz w petli redeklarowalem zmienne i bylo wszystko ok

Napisany przez: stellatus 27.03.2020, 11:37:57

Sorry, nieprecyzyjnie się wyraziłem. Nie chodziło mi redeklarację w pętli. Mam zadeklarowane jakieś zmienne poza funkcjami. Uruchamiam kod w konsoli i wszystko gra. Gdy chcę go uruchomić po raz drugi pojawia się błąd redeklaracji. Jest to wkurzające, bo muszę odświeżać przeglądarkę albo wykomentować zmienne, żeby ponownie uruchomić kod.

Napisany przez: nospor 27.03.2020, 11:51:21

Przepraszam, nie rozumiem co piszesz.

Zrobilem teraz test:

var ala = 2;
var ala = 4;
alert(ala);

I zadnego bledu tylko alert wyswietla mi 4, czyli tak jak mowilem, ze nastepna deklaracja nadpisuje poprzednia

Napisany przez: stellatus 27.03.2020, 11:57:53

spróbuj proszę z letami i constami

Napisany przez: nospor 27.03.2020, 12:17:28

Skoro uzywasz CONSTow znaczy, ze uzywasz tez es6. No tam sytuacja jest inna. Tak, tam nie mozesz sobie zadeklarowac kilka razy tej samej zmiennej ot tak (nie liczac rzecz jasna petli i funkcji bo one sa traktowane inaczej)

Napisany przez: stellatus 27.03.2020, 12:22:00

OK. No więc właśnie dlatego m.in. miałem problem z tym skryptem. Myślę, że temat zamknięty. Dziękuję bardzo i pozdrawiam.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)