Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  9 4611
Hei Folkens.

Sitter her med en liten nøtt.
Nå er ikke jeg super god i JavaScript, men prøver å lære.

Jeg har en funksjon. La oss si den er sånn her:

Kode

function somethign() {
   if(dayOne < dayTwo) {
       return "test";
   }
}
Så har jeg en javascript generert html som er sånn her:

Kode

table.innerHTML += "<tr data-target=''><td> Noe som står her! </td></tr>";
Veldig forkortet JavaScript her nå da.

Nå skal jeg opprette en data-target inni <tr> her ved å injecte return stringen fra funksjonen her.
Hvordan er løsningen for å få det som returneres fra funksjonen inn i data-target her?

Har sittet her i en stund å googlet, men kommer ikke fram til en løsning her akkurat nå.
Tenker noe av problemer er at du starter litt i feil ende når du lager HTML med string-concatinering. Det gjør det veldig vanskelig for deg. Ville heller gått for å faktisk lage DOM-objekter med javascript og appende disse.

Altså noe som_

Kode

const tableRow = document.createElement('tr');
const tableCell = document.createElement('td');
tableCell.innerText = 'Noe som står her';
tableRow.appendChild(tableCell);
tableRow.attributes["data-target"] = something();

document.getElementById("myTable").appendChild(tableRow);
Sist endret av etse; 15. mai 2019 kl. 14:00.
Trådstarter
Takk etse. Skal sjekke dette.
Limited edition
Moff's Avatar
Det du trenger er en referanse som lar deg "få tak i" <tr>-elementet i JavaScriptet ditt. Det etse foreslår vil forsåvidt fungere, fordi JavaScriptet oppretter <tr>-elementet, og dermed har du en referanse til det.

Hvis du imidlertid ikke ønsker å opprette elementet via JavaScript (det blir ofte litt rotete), så kan du gi elementet en ID. JavaScript er i stand til å søke opp HTML-elementer, men søk etter objekter med ID er ofte det mest effektive alternativet.

I HTML kan du skrive noe slikt:

Kode

<tr id="dingseboms" data-target="">
Og i JavaScript gjør du slik:

Kode

// Velg <tr>-elementet og sett "data-target" til resultatet av somethign()
document.getElementById("dingseboms").setAttribute("data-target", somethign());
En klassisk tabbe man ofte gjør som fersk JS-utvikler er at man kjører JavaScriptet før nettsiden er ferdig å laste inn. Hvis du plasserer JavaScript i <head>, der det helst bør være plassert, så må du ha en funksjon som sørger for at skriptet ikke kjører før hele HTML-dokumentet er ferdig å laste inn. Ellers vil skriptet kjøre så fort nettleseren har passert <head>, og på det tidspunktet er ikke noen elementer i <body> rendret ennå. getElementById() vil da returnere undefined, fordi elementet ikke eksisterer. Det er veldig lett å fikse hvis du bruker et JavaScript-rammeverk som for eksempel JQuery, men du kan også skrive det selv. JavaScript er et veldig, veldig vanskelig språk å forholde seg til fordi mange nettlesere mangler støtte for flere funksjoner (eller implementerer de feil). Jeg pleier ikke å anbefale at nye utviklere hopper rett på tredjeparts rammeverk fra början, men når det kommer til JavaScript, så føler jeg at JQuery er et must-have, fordi du slipper å skrive redundans for hver bidige ting du prøver å gjøre. Hvis du vil ha en document-ready-funksjon som virker i alle nettlesere, så må du skrive minst 4 ulike funksjoner;

Kode

document.addEventListener("DOMContentLoaded", readyFunction, false);
window.addEventListener("load", readyFunction, false);
document.attachEvent("onreadystatechange", readyFunction);
window.attachEvent("onload", readyFunction);
I JQuery, så er alt dette bakt inn i én funksjon, som sørger for å sjekke hvilken av disse 4 som er tilgjengelig i brukerens nettleser. JQuery fungerer altså som et interface som sørger for at alle funksjoner du bruker fungerer for 99% av alle brukere.
Sitat av Moff Vis innlegg
Det du trenger er en referanse som lar deg "få tak i" <tr>-elementet i JavaScriptet ditt. Det etse foreslår vil forsåvidt fungere, fordi JavaScriptet oppretter <tr>-elementet, og dermed har du en referanse til det.

Hvis du imidlertid ikke ønsker å opprette elementet via JavaScript (det blir ofte litt rotete), så kan du gi elementet en ID. JavaScript er i stand til å søke opp HTML-elementer, men søk etter objekter med ID er ofte det mest effektive alternativet..
Vis hele sitatet...
Nå skal det sies at objektet i eksempelet ble opprettet med string-concatinering i innerHTML, dette er et vepsebol - og noe man burde bare lære av seg med en gang. Det er så lett å introdusere alvorlige sikkerhetshull og bugs om man skriver kode på denne måten - og det mest reelle alternativet her er document.createElement. Ja det er kanskje litt mer tungvindt i starten - men det andre er litt som å pisse i bukse for å holde seg varm.

Jeg er veldig for å skille logikk og design. og det beste er om det meste av HTMLen kan være skrevet separat. Men om du ønsker å bruke plain javascript og vill opprette DOM-noder så er createElement måten å gjøre det på.

Angående jQuery vil jeg komme med en brannfakkel: men det er veldig 2010. I dag finnes det egentlig nesten ingen gode grunner til å bruke jQuery - det er et bloated rammeverk som har utgått på dato og for lengst burde bli glemt. Og jeg har brukt alt for mange timer av arbeidsdagen min til å skrive om fra jQuery til plain javascript. Siden funksjonaliteten vi trenger (getElementById o.s.v.) er godt støttet i alle nettlesere som folk faktisk bruker. Så i dag vil jeg aldri oppfordre folk til å ta det i bruk :

Og angående det siste (om hvordan kjøre etter siden er lastet) så funker det nesten alltid bare å hive på attributtet "defer" i script-tagen. Detter vil utsette kjøringen av scriptet til etter hele HTML-dokumentet er parset. Dette er støttet i alle moderne nettlesere (til og med IE10 støtter det).

Edit: Og de gangene "defer" ikke er godt nok, og man må garantere kjøring etter DOMen er ferdig, er det letteste å bare putte scriptet i slutten av body-elementet i HTMLen. Ikke noe behov for jQuery.

Altså:

Kode

<html>
    <head>
        <title>Min sidetittel</title>
    </head>
    <body>
        <article>
             <h1>En kul overskrift</h1>
             <p>En morsom tekst</p>
        </article>
        <script src="mitt-script.js" type="text/javascript"></script>
    </body>
</html>
Sist endret av etse; 15. mai 2019 kl. 17:00. Grunn: Automatisk sammenslåing med etterfølgende innlegg.
NOOOOOOOOOOOOOOOOOO-
robhol's Avatar
Data-target hører visst til Bootstrap, det kan godt hende de har en bedre løsning på hva det enn er du prøver på.
Limited edition
Moff's Avatar
Sitat av etse Vis innlegg
Angående jQuery vil jeg komme med en brannfakkel: men det er veldig 2010. I dag finnes det egentlig nesten ingen gode grunner til å bruke jQuery - det er et bloated rammeverk som har utgått på dato og for lengst burde bli glemt.
Vis hele sitatet...
Njæææ, jeg er ikke enig. Det er sant at JQuery hadde performance-problemer da smarttelefoner fortsatt var en ny greie, men nå i dag, hvor mannen i gata har nærmest fri bruk av data og en lynrask multi-core-prosessor i telefonen sin, så er JQuery helt innafor. Først og fremst, så er det viktig å huske at nærsagt ingen trenger å bruke data på å laste ned JQuery i dag, hvis man bruker et veletablert CDN. Da gjenstår kun performance-argumentet, og for de mer avanserte operasjonene, så er det så utrolig behagelig å jobbe med JQuery sammenlignet med native JS at jeg fortsatt synes det er verdt det - selv om det er tregere. Ajax-kode, for eksempel, er et helvete hvis du ikke skal lage noe rammeverk for det. Og hvis du uansett lager deg et rammeverk for å gjøre ting lettere - hvorfor ikke bare bruke JQuery, som brukeren mest sannsynlig allerede har cachet likevel?

For de som ikke snakker JQuery, her er et praktisk eksempel på forskjellen mellom selectors:

Kode

// JQuery (samme metode for alle typer selectors)
$("#something")

// Native
document.getElementById("something") // ID-selector
document.getElementsByClassName("something") // Klasse-selector
document.querySelectorAll("[data-something='something']") // CSS-selector
document.getElementsByTagName("div") // Element-selector
Jeg tok en kjapp performance-test for å gi et visst inntrykk av hvor stor (eller liten) forskjellen er:

Kode

// 10 000 operasjoner
getElementById - 1.40625 ms
getElementsByClassName - 2.126953125 ms
querySelectorAll - 10.977783203125 ms
getElementsByTagName - 1.60986328125 ms

$(id) - 8.24169921875 ms
$(class) - 20.3828125 ms
$(attribute) - 28.355712890625 ms
$(element) - 16.838134765625 ms
For 10 000 operasjoner kom native JS ut 57,54 ms raskere, og for 1 operasjon var forskjellen 0,51 ms (tusendels sekund).

Det er smak og behag; jeg skriver mye JavaScript, og jeg kan ikke fordra Angular eller React. De er alt for intrusive. Jeg synes native er veldig uoversiktlig, mye rett og slett fordi funksjonsnavnene er så forbasket lange og ulogiske. JQuery er kanskje ikke så raskt som det burde være, men om jeg sparer flere dager med utvikling per år fordi koden er ren og pen, mens hver bruker taper 0,5 millisekunder av sitt liv ved hver page load - da er valget lett for meg. Med det sagt, så bruker jeg altså ikke JQuery som en erstattning for absolutt alle funksjoner bare for å bruke JQuery - der native er lett og gir mening, så bruker jeg native.

Det er litt det samme som med PHP; det var en periode hvor PHP var ansett for å være poop det også, men nå i versjon 7, så er det faktisk helt greit igjen. JQuery har ikke tatt noen grep for å fikse seg selv med tanke på performance, men den raske utviklingen av mobile enheter med gode prosessorer gjør at problemet ikke er... vel, problematisk lengre.
Problemet mitt med jQuery er ikke performance, men at man egentlig ikke trenger det. querySelector og getElementById gjør akkurat samme nytten - er tydelig og er egentlig mer lesbart. (selv om litt verbost). jQuery var nyttig på den tiden man måtte støtte IE9 og browser-kombalitet faktisk var et problem for slike enkle ting. Det er det ikke i dag.

Rett og slett er det et rammeverk som i dag ikke løser et problem. Skal du skrive små enkle ting: Bruk native javascript og drop jQuery og alt slikt.
Skal du lage større apper som manipulerer DOMen så har man betrydelig mange bedre rammeverk (react, angular, vue...).

jQueru har utspillt sin rolle.


... og ajax er enkelt. Du bruker fetch. (som desverre ikke støtter av IE11, men alle moderne nettlesere støtter det. Og du kan bruke polyfill om du absolutt må støtte IE11.) Og vil og påstå fetch er betydelig penere enn ajax med jQuery.
Sist endret av etse; 16. mai 2019 kl. 15:20.
Trådstarter
Ser folk fortsatt diskuterer her, og det er bra så man får vite litt mer

Grunnen til at jeg har gjort det som jeg gjør er pga at jeg henter en del data fra XML som kjøres og da var det egentlig bare ganske enkelt å greit å bruke javascript til å generere 1 <tr> og 4 <td> linjer for å vise data i tabellen.


Jeg har jo nå rundt 2000 linjer med <tr> i html'en og skal KUN vise 8 stk før man utvider tabellen med en knapp.
Dette fungerer til en viss grad, MEN jeg har fitrering i tillegg som fungerer og som filtrerer ut ifra hvilke data som skal vises.

Jeg har nå satt opp en kjapp funksjon som kun viser de første 8 linjene i <tbody>, men dette blir feil i filtreringen da linje 10 kan være første element i den ene filtreringen og da vises ingen data i tabellen.

Her må jeg da legge inn en funksjon som kjører hver gang filtreringsmenyen er trykket på og som ignorerer de med klassen ".hidden" og kun viser de første 8 linjene som er aktuelle.

Først tenkte jeg en slice funksjon som tok de første 8, men dette gjorde akkurat det samme som i første forsøk, så nå tenker jeg at jeg må finne en måte å skjule alle table rows utenom de første 8 og ikke ta med de som har klassen ".hidden".

OPPSUMMERT:

Jeg har 200 rader. Jeg skal kun vise de første 4 aktuelle. De første 3 har allerede klassen ".hidden" og da vises kun linje 4 da linje 1-2-3 blir tatt med men er hidden. Her skal klassen ".hidden" ignoreres og linje 4-5-6-7 skal vises. Dette skal gjøres i Javascript.


Noen tips?
Dette hadde nok vært mye enklere med et rammeverk som Vue eller React. Men om jeg skulle løst det uten ville jeg gjort noe sånt:

Kode

const items = []; // Liste med all data.

const renderRows = function(filterValue = false, limit = 8) {
  const itemsToRender = items.filter(function(item) {
    if (filterValue) {
      // Gjør en sjekk om item matcher filterValue.
      return true; // Eller false om item ikke matcher.
    }
    return true; // Har du ikke satt noe filter tar du med alle.
  }).slice(0, limit); // Kutter ned resultatene til de 8 første.

  // itemsToRender inneholder nå de elementene som matcher filterer og er begrenset til så mange du vil ha.

  // Kode for å generere rader i tabellen.
};
Så når brukeren gjør en endring på filteret kaller du funksjonen og tegner opp tabellen på nytt. Da trenger du ikke ta hensyn til at linje 10 skulle være først i en filtrering.