Toon posts:

Timing en console.log in javascript.

Pagina: 1
Acties:

Vraag


  • ActualFantasy
  • Registratie: December 2006
  • Laatst online: 08:52
Hoi, ik ben met een eigen projectje naast een cursus webdevelopment bezig, maar loop nu een beetje vast.

Voor mijn gevoel is het heel simpel, maar ik krijg het niet opgelost, en vraag mij af of het wel op te lossen is.

Heel simpel en in het kort wat code.

in de HTML code staat het volgende:

HTML:
1
<li id="list-item-1" data-field="1"></li>


In mijn javascript code voeg ik daar een click listener aan toe.

JavaScript:
1
2
memoryElement = document.getElementById("list-item-1");
memoryElement.addEventListener("click", checkNumber);


De functie bij de click listener:

JavaScript:
1
2
3
4
function checkNumber(event) {
  console.log(event.target);
  event.target.classList.toggle("clicked");
  console.log(event.target);


Als ik deze functie dus uitvoer, dan komt er bij beide console.logs identiek hetzelfde te staan.

Hoe kan dit? Dit zou toch nooit moeten kunnen? Ik zou verwachten dat bij de eerste keer

HTML:
1
<li id="list-item-1" data-field="1"></li>


en bij de tweede keer

HTML:
1
<li id="list-item-1" data-field="1" class="clicked"></li>


komt te staan.

[Voor 5% gewijzigd door RobIII op 21-12-2021 11:43. Reden: Wanneer je code post, gebruik dan code-tags a.u.b. :)]

iRacing Profiel

Alle reacties


  • rescla
  • Registratie: November 2012
  • Laatst online: 07-02 23:25
Waarschijnlijk komt het omdat de waarde pas uitgelezen wordt op het moment dat je het bekijkt in de console. Als het goed is zie je een [i] tje in de console staan bij de waarde die je logt, die aangeeft dat de waarde pas gelezen is op het moment dat je op het pijltje hebt geklikt om hem uit te klappen.

Je kan na de eerste console.log een regel toevoegen met "debugger;", als je dan de console open hebt terwijl die code uitgevoerd wordt dan kan je over "event.target" hoveren om de waarde te zien voordat de toggle uitgevoerd wordt. Als het goed is zie je dan de waardes die je verwacht.

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
ActualFantasy schreef op dinsdag 21 december 2021 @ 11:40:
Als ik deze functie dus uitvoer, dan komt er bij beide console.logs identiek hetzelfde te staan.
Klopt!.


Probeer dit eens:
JavaScript:
1
2
3
4
function checkNumber(event) {
  console.log(event.target.outerHTML);
  event.target.classList.toggle("clicked");
  console.log(event.target.outerHTML);
ActualFantasy schreef op dinsdag 21 december 2021 @ 11:40:
Hoe kan dit? Dit zou toch nooit moeten kunnen? Ik zou verwachten dat bij de eerste keer
En of het kan. Je moet het zien als een queue waarbij "console.log" onderaan de queue belandt zodat eerst alle andere code wordt uitgevoerd.
Eigenlijk is het resultaat dan zeg maar:
  1. event.target.classList.toggle("clicked");
  2. klaar met script
  3. print object
  4. print object

[Voor 38% gewijzigd door DJMaze op 21-12-2021 11:50]

Maak je niet druk, dat doet de compressor maar


  • hellfighter87
  • Registratie: Mei 2008
  • Laatst online: 07-02 14:00
Dat komt omdat de console de variable `by reference` benadert, dit betekent dat jij in principe 2 keer hetzelfde object console logged, en dus de veranderingen mee genomen worden in de eerste print.

Hoe je dit kan voorkomen is door zoiets te doen:
JavaScript:
1
2
3
  console.log(event.target.classList);
  event.target.classList.toggle("clicked");
  console.log(event.target.classList);


En als dat niet helpt kan je dit proberen, hier maak je een clone van je object aan:
JavaScript:
1
2
3
  console.log({...event.target});
  event.target.classList.toggle("clicked");
  console.log({...event.target});


En als bovenstaande ook niet lukt is dit de nuke option:

JavaScript:
1
2
3
  console.log(JSON.parse(JSON.stringify(event.target)));
  event.target.classList.toggle("clicked");
  console.log(JSON.parse(JSON.stringify(event.target)));


Door het object te converteren naar JSON en weer terug, weet je zeker dat het een nieuw object is en dus niet verwijst naar het oude object

[Voor 25% gewijzigd door hellfighter87 op 21-12-2021 11:52]


  • RobIII
  • Registratie: December 2001
  • Nu online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

ActualFantasy schreef op dinsdag 21 december 2021 @ 11:40:
Hoi, ik ben met een eigen projectje naast een cursus webdevelopment bezig, maar loop nu een beetje vast.
Wanneer je code post, gebruik dan code tags a.u.b. En, als het effe kan, maak meteen even een fiddletje :)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • ActualFantasy
  • Registratie: December 2006
  • Laatst online: 08:52
DJMaze schreef op dinsdag 21 december 2021 @ 11:46:
[...]

Klopt!.


Probeer dit eens:
JavaScript:
1
2
3
4
function checkNumber(event) {
  console.log(event.target.outerHTML);
  event.target.classList.toggle("clicked");
  console.log(event.target.outerHTML);



[...]

En of het kan. Je moet het zien als een queue waarbij "console.log" onderaan de queue belandt zodat eerst alle andere code wordt uitgevoerd.
Eigenlijk is het resultaat dan zeg maar:
  1. event.target.classList.toggle("clicked");
  2. klaar met script
  3. print object
  4. print object
Het werkt met jouw aanpassingen, alleen volg ik je logica nog steeds niet helemaal.

Want als je die volgt dan zou hij toch nog steeds de console.log twee keer achteraan moeten doen? En dan staat er toch nog steeds twee keer hetzelfde?

JavaScript:
1
2
  console.log(event.target.outerHTML);
  console.log(event.target.outerHTML);


Wat ik dus niet snap is waarom die outerHTML ervoor zorgt dat hij het wel uitvoert voor en na de click, en zonder de outerHTML dus blijkbaar niet? Wat is de gedachte daarachter?

Zelfde geld trouwens voor @hellfighter87 . Zijn toevoeging van classList zorgt er blijkbaar ook voor dat er wel wat in de console gezet wordt voor en na de

JavaScript:
1
 event.target.classList.toggle("clicked");


Dus eigenlijk, waarom is dit

JavaScript:
1
2
3
4
function checkNumber(event) {
  console.log(event.target.outerHTML);
  event.target.classList.toggle("clicked");
  console.log(event.target.outerHTML);


kwa volgorde anders dan

JavaScript:
1
2
3
4
function checkNumber(event) {
  console.log(event.target);
  event.target.classList.toggle("clicked");
  console.log(event.target);


dit.

[Voor 12% gewijzigd door ActualFantasy op 21-12-2021 12:03]

iRacing Profiel


  • reputatio
  • Registratie: Mei 2017
  • Laatst online: 11:45
Eigenlijk zoals @hellfighter87 zegt, als je `event.target` logged, log je de referentie naar het object. Niet per se een kopie van het object op dat moment. Op het moment dat de eerste gelogged is, zie je dus niet de `clicked` class, maar bij de tweede keer wel. Alleen omdat het een referentie is, wordt de 1e log aangepast op het moment dat hij zichtbaar is, want je logged de referentie naar `event.target`

Daarentegen, als je `classList` of `outerHTML` logged, log je een op dat moment gecreëerde string en dus geen referentie naar het object zelf. Dus de eerste log wordt niet meer aangepast, want het is geen referentie.

Hoop dat je het nog snapt :+

  • ActualFantasy
  • Registratie: December 2006
  • Laatst online: 08:52
reputatio schreef op dinsdag 21 december 2021 @ 12:09:
Eigenlijk zoals @hellfighter87 zegt, als je `event.target` logged, log je de referentie naar het object. Niet per se een kopie van het object op dat moment. Op het moment dat de eerste gelogged is, zie je dus niet de `clicked` class, maar bij de tweede keer wel. Alleen omdat het een referentie is, wordt de 1e log aangepast op het moment dat hij zichtbaar is, want je logged de referentie naar `event.target`

Daarentegen, als je `classList` of `outerHTML` logged, log je een op dat moment gecreëerde string en dus geen referentie naar het object zelf. Dus de eerste log wordt niet meer aangepast, want het is geen referentie.

Hoop dat je het nog snapt :+
Ok, dat klinkt allemaal logisch, maar dan vraag ik mij af waarom als ik een breakpunt zet op alle drie de regels, en ik dus netjes erdoorheen stap met F11, hij wel eerst het ene item laat zien zonder de class, en dan na de click het andere item met de class.

Haal ik de breakpoints weg, dan laat ie dus twee keer alleen met de class zien.

Dat is dan gewoon een timing dingetje of zo, dat de dom niet snel genoeg update voor mijn console.log commando?

Als het zon reference naar zou zijn, dan zou hij na de laatste stap de eerste stap ook moeten aanpassen weer, en dat gebeurt dus niet in de console. Bovenste is dus met Step into en breakpunt op eerste regel.
Onderste is console zonder breakpunten.

[Voor 18% gewijzigd door ActualFantasy op 21-12-2021 12:22]

iRacing Profiel


  • DJMaze
  • Registratie: Juni 2002
  • Niet online
ActualFantasy schreef op dinsdag 21 december 2021 @ 12:15:
Dat is dan gewoon een timing dingetje of zo, dat de dom niet snel genoeg update voor mijn console.log commando?
Zoiets.

Stel, je script past 10 dingen in de DOM aan.
Die worden allemaal uitgevoerd, maar je ziet ze niet totdat de browser zegt "gebruik nu aangepaste DOM".
Hierdoor hoeft de browser niet bij elke wijziging de hele DOM op je scherm te verversen.
Bij een breakpoint ververst de browser de DOM.
Na het uitvoeren van je script (of dus de breakpoint) ververst de browser de console.

In praktijk is het ingewikkelder dan ik je nu zeg en je moet het ook niet letterlijk nemen.
Zoals: https://www.html5rocks.com/en/tutorials/speed/rendering/

Wat wel belangrijk is, is dat je weet wat een object reference is.

Stel, een object is 1MB. Elke keer als je een clone maakt komt er 1MB in het geheugen bij.
Je kan dan wel de clone aanpassen zonder dat het oorspronkelijke object wordt aangepast.
Om je leven (en het geheugen gebruik) makkelijk te maken wordt er dus gebruik gemaakt van referenties.
event.target is een object reference en alles wat je aanpast is dus op dat object.

event.target.innerHTML is geen referentie, maar een functie die het object omzet in een string.
console.log(string) is dus zijn eigen string object en niet de referentie naar het HTMLElement.

Je moet dus wel altijd opletten of een object functie een nieuw (clone) object terug geeft, of dat het het huidige object aanpast.

Een goed voorbeeld is het Array object met:
Array.prototype.splice() "in place"
Array.prototype.filter() "creates a new array"

Maak je niet druk, dat doet de compressor maar


  • dejoma
  • Registratie: Maart 2013
  • Laatst online: 14-08-2022
Ik kan mij vaag iets herinneren uit de tijd dat ik nog wat deed met reactJS dat hier gewoon een soort javascript bugje aan de hand was en dat je een delay in moet bouwen om dit te voorkomen.

Dit zou dus hier ook het geval kunnen zijn, probeer maar iets als:

code:
1
2
3
console.log("Hello");
// jouw actie
setTimeout(() => {  console.log("World!"); }, 20);
Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee