"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
Webbutvecklingsdagbok (Webbutveckling, 120 hp)
Då rekomenderar jag dig (och ts) att ta en titt på CSS grid istället (eller ännu bättre både CSS grid och flexbox)
Använder grid rätt mycket, men inte just positionering.
Man kommer ganska långt på flexbox.
Kör flexbox froggy! Kul spel
Webbutvecklingsdagbok (Webbutveckling, 120 hp) | Dag 6, 7 && 8 av 759
Dag 6, 7 && 8 av 759 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Räkna bokstäver i strängar var inte så svårt trots allt!
Helgen har passerat och jag har kodat ihop den 3:e av de 3 övningarna i kapitlet om Functions i EloquentJS. Det var faktiskt enklare än jag trodde. Jag verkar ha en tendens att överanalysera inom kodningen som om det måste vara "heliga kodskrifter" i det jag skriver!
Men först så lärde jag mig en viktig sak om if- och if else-satser (se bilden nedan):
Alla negativa tal i funktionen isEven(number) blir "undefinied" (-1), (-50) och (-75). Om jag förstår det rätt så beror det på att else if-satserna efter första if-satsen endast kör om första if-satsen är false men eftersom den är true (negativt tal är mindre än 0) så skippar den övriga else if-satser. Den får då inte returnera något men enligt läromedlet så returnerar en funktion alltid något även om det inte finns någon return. Då returnerar den alltså undefined?
Detta löses då genom att bara göra första else if-satsen till en if-sats så att den får köra de övriga else if-satserna om det visar sig att if(number == 0) är false. Jag insåg också att if(!(Number < 0)) var överflödigt (se bild nedan):
Jag lyckades även använda mig av ternary operator vilket verka innebär att: "expression true? ? if expression true : if expression false"? (Se bild nedan):
Här är mina lösningar på den 3:e av de 3 övningarna i Functions-kapitlet:
Första countString(string) visar positionen för varje bokstav i strängen och returnerar antalet bokstäver för strängen. Jag ville bara se om jag kunde få till det trots att det ej ingår i övningen.
Andra countBs(string) räknar antalet stora B i strängen och returnerar antalet bokstäver för strängen. Jag kände till att går att skriva:
string = string.toUpperCase();
innan for-loopen för att göra alla bokstäver stora så den räknar både små och stora.
Tredje countChar tar två parametrar: sträng och den storlekskänsliga bokstaven som ska räknas. Jag kom nyss på nu att jag kunde ha skrivit om:
if(string[i] == char)
till:
if(string[i] == char[0])
så den bara räknar antalet bokstäver genom att endast jämföra första bokstaven i char-parametern.
Verkar dessa tre funktioner i övning 3 lämpliga eller kunde de ha fått ännu mer "clean code"?
Nu hoppar jag på kapitel 4 i EloquentJS: https://eloquentjavascript.net/04_data.html (Objekt och Arrayer). Jag misstänker att en övning här kommer att bli "Bubble Sort Function" som jag minns från C++-programmeringstiden på gymnasiet men som jag aldrig förstod mig på då. Om jag minns rätt så handlar den om att sortera fram det största talet i en array av siffror?
Fråga: Jag såg i någon video om JS att stringArrayName[5][0] kan syfta på det första tecknet i det sjätte värdet i en array[]? Är det exempelvis sådan kod man vill använda om man vill börja loopa igenom varje tecken för varje sträng i en array[]?
Vi ses imorgon!
Mvh,
WKL.
Då rekomenderar jag dig (och ts) att ta en titt på CSS grid istället (eller ännu bättre både CSS grid och flexbox)
Använder grid rätt mycket, men inte just positionering.
Man kommer ganska långt på flexbox.
CSS Grid & Flexbox, "ingår" de i CSS3 eller är de separata packages man måste fixa likt tailwindcss i VSCode?
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
CSS Grid & Flexbox, "ingår" de i CSS3 eller är de separata packages man måste fixa likt tailwindcss i VSCode?
De ingår.
Dag 6, 7 && 8 av 759 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Räkna bokstäver i strängar var inte så svårt trots allt!
Helgen har passerat och jag har kodat ihop den 3:e av de 3 övningarna i kapitlet om Functions i EloquentJS. Det var faktiskt enklare än jag trodde. Jag verkar ha en tendens att överanalysera inom kodningen som om det måste vara "heliga kodskrifter" i det jag skriver!
Men först så lärde jag mig en viktig sak om if- och if else-satser (se bilden nedan):
<Uppladdad bildlänk>
Alla negativa tal i funktionen isEven(number) blir "undefinied" (-1), (-50) och (-75). Om jag förstår det rätt så beror det på att else if-satserna efter första if-satsen endast kör om första if-satsen är false men eftersom den är true (negativt tal är mindre än 0) så skippar den övriga else if-satser. Den får då inte returnera något men enligt läromedlet så returnerar en funktion alltid något även om det inte finns någon return. Då returnerar den alltså undefined?
Detta löses då genom att bara göra första else if-satsen till en if-sats så att den får köra de övriga else if-satserna om det visar sig att if(number == 0) är false. Jag insåg också att if(!(Number < 0)) var överflödigt (se bild nedan):
<Uppladdad bildlänk>
Jag lyckades även använda mig av ternary operator vilket verka innebär att: "expression true? ? if expression true : if expression false"? (Se bild nedan):
<Uppladdad bildlänk>
Här är mina lösningar på den 3:e av de 3 övningarna i Functions-kapitlet:
<Uppladdad bildlänk>
<Uppladdad bildlänk>
Första countString(string) visar positionen för varje bokstav i strängen och returnerar antalet bokstäver för strängen. Jag ville bara se om jag kunde få till det trots att det ej ingår i övningen.
Andra countBs(string) räknar antalet stora B i strängen och returnerar antalet bokstäver för strängen. Jag kände till att går att skriva:
string = string.toUpperCase();
innan for-loopen för att göra alla bokstäver stora så den räknar både små och stora.
Tredje countChar tar två parametrar: sträng och den storlekskänsliga bokstaven som ska räknas. Jag kom nyss på nu att jag kunde ha skrivit om:
if(string[i] == char)
till:
if(string[i] == char[0])
så den bara räknar antalet bokstäver genom att endast jämföra första bokstaven i char-parametern.
Verkar dessa tre funktioner i övning 3 lämpliga eller kunde de ha fått ännu mer "clean code"?
Nu hoppar jag på kapitel 4 i EloquentJS: https://eloquentjavascript.net/04_data.html (Objekt och Arrayer). Jag misstänker att en övning här kommer att bli "Bubble Sort Function" som jag minns från C++-programmeringstiden på gymnasiet men som jag aldrig förstod mig på då. Om jag minns rätt så handlar den om att sortera fram det största talet i en array av siffror?
Fråga: Jag såg i någon video om JS att stringArrayName[5][0] kan syfta på det första tecknet i det sjätte värdet i en array[]? Är det exempelvis sådan kod man vill använda om man vill börja loopa igenom varje tecken för varje sträng i en array[]?
Vi ses imorgon!
Mvh,
WKL.
Hej hej, bra jobbat!
Vill bara säga två saker:
Istället för
x = x+2
kan man skriva:
x += 2
och få ut samma sak.
Det andra:
Finns det någon anledning till att du inte använder Remainder Operator för att kolla om ett tal är jämnt eller udda?
Äsch...
Hej hej, bra jobbat!
Vill bara säga två saker:
Istället för
x = x+2
kan man skriva:
x += 2
och få ut samma sak.
På samma sätt kan
number = number * -1;
skrivas som
number *= -1;
Det andra:
Finns det någon anledning till att du inte använder Remainder Operator för att kolla om ett tal är jämnt eller udda?
Uppgiften var väl att göra det rekursivt!?
Annars kan funktionen skrivas mycket enklare, exempelvis, som du skriver, med modulo-operatorn
function isEven(x) {
return (x % 2 == 0);
}
eller
function isEven(x) {
return !(x % 2);
}
De ingår.
Tack! Då vet jag!
Hej hej, bra jobbat!
Vill bara säga två saker:
Istället för
x = x+2
kan man skriva:
x += 2
och få ut samma sak.
Det andra:
Finns det någon anledning till att du inte använder Remainder Operator för att kolla om ett tal är jämnt eller udda?
Som @PeCe var inne på så var uppgiften att skapa en rekursiv funktion. I tidigare kapitel i läromedlet löste jag samma uppgift fast då med restoperatorn. Tack för syntaxtipsen!
På samma sätt kan
number = number * -1;
skrivas som
number *= -1;
Uppgiften var väl att göra det rekursivt!?
Annars kan funktionen skrivas mycket enklare, exempelvis, som du skriver, med modulo-operatorn
function isEven(x) {
return (x % 2 == 0);
}
eller
function isEven(x) {
return !(x % 2);
}
Betyder
return !(x % 2);
att den skall returerna "false" i och med ! framför parentesuttrycket?
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
De ingår.
Njae, om man ska vara petig så ingår inte css grid i CSS3 men iom att webbvärlden (relativt nyligen) droppat stöd för ie11 så stödjer nu alla nya browsers css grid.
Webbutvecklingsdagbok (Webbutveckling, 120 hp) | Dag 9 av 759
Dag 9 av 759 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Äntligen har jag sorterat minst -> störst (och tvärtom) i en siffer-Array!
Jag är nu i kapitlet 4 i EloquentJS som handlar om Objekt och Arrayer. Då tyckte jag det var hög tid att ge mig på att sortera siffror i en array. Det hela började med väldigt mycket skräpkod med olika loopförsök och det blev bara en stor kodsoppa:
Senare så upptäckte jag något mystiskt med const som verkade ändå tilldelas nytt värde trots att det skall vara en konstant? Men i bilden nedan så ser man hur const = arg [...] skickas till olika funktioner och sedan konsolloggas const = arg [...] som magiskt då verkar ha fått större värde? Men sista konsolloggen är (skicka) som använder metoden reduce() på const = arg [...] som då magiskt nog summera det första ursprungliga värdet 67?
Fråga: Kan det ha varit något med Referensdatatyper kontra Primitiva datatyper som spökat här som jag inte förstått mig på?
Sedan fortsatte jag med att försöka skapa en "Bubble Sort Function" men egentligen blev det aldrig en sådan. Jag upptäckte också ett problem: jag behövde plocka bort delar från Arrayen som skulle sorteras in i en ny. Jag tror att det finns en sorteringsfunktion man brukar få koda som heter "comb" som ska kunna sortera direkt inuti en och samma array istället för att skapa en ny som i mitt fall?
Till slut kom jag på svaret: jag behövde en metod som kunde ta bort det senaste största upptäckta elementet i en array samtidigt som den tryckte in den i en ny array som sedan returnerades. Tyvärr så tar pop() bort bara sista elementet så jag fick tyvärr göra det jag inte ville göra: googla hur man gör något i JS = ta bort utvalt element i en array.
Jag blev också tvungen för allra första gången att läsa inuti VSCode när den presenterade vilka olika parametrar gjorde i en metod för att kunna använda den rätt. Så Splice() kom till undsättningen och jag lyckades producera följande:
Koden för den som vill visa hur den kan refaktoriseras ytterligare:
// Jag älskar att skriva kommentarer med // och inte HTML-varianten...
let listOfNumbers = [62, 131, 33, -235, 162];
let FirstArrayLength = listOfNumbers.length;
console.log("NewArray före: " + listOfNumbers);
console.log("Så många nummer storlekssorteras: " + FirstArrayLength);
function SortArrayByBiggest(listOfNumbers) {
let newArray = [];
// Jag ville använda while(newArray != []) men då kraschade kompilatorn
for (let j = 0; j < FirstArrayLength; j++) {
let max = listOfNumbers[0]; // Dessa deklareras och/eller tilldelas om vid varje körning i loopar?
let GetArrayPos;
for (let i = 0; i < listOfNumbers.length; i++) {
// Ändra >= till <= för att sortera åt andra hållet!
if (listOfNumbers[i] >= max) {
max = listOfNumbers[i];
GetArrayPos = i; // Hämta position för element i Array som skall splicas
}
}
newArray.push(max); // Lägg till senast största siffra
listOfNumbers.splice(GetArrayPos, 1); // Plocka bort element i Array i position i
}
return newArray;
}
console.log("NewArray efter: " + SortArrayByBiggest(listOfNumbers));
Ändrar man >= till <= på rad 19 så kan man även sortera åt andra hållet. Tack vare att den loopar igen utifrån antalet element i arrayen så kan den sortera hur korta/långa arrayer som helst!
Jag lärde mig också en hel del om det mer tekniska om JS i webbläsaren i denna korta YT-serie: https://www.youtube.com/watch?v=-G9c4CMMUKc&list=PLillGF-Rfqb...
Nu blir det att sätta sig in i "Datastrukturer: Objekt och Arrayer". Är det inte lustigt att JavaScript inte är objektorienterad programmering men en stor del hur det manipulerar i webbläsaren är via DOM?
Vi ses imorgon!
Mvh,
WKL.
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
Njae, om man ska vara petig så ingår inte css grid i CSS3 men iom att webbvärlden (relativt nyligen) droppat stöd för ie11 så stödjer nu alla nya browsers css grid.
96.81% support får väl anses dugligt.
Du förstod nog att jag menade att frågeställaren inte behöver installera något extra eller så, då det är väldigt osannolikt att han sitter med en totalt okänd/oduglig browser.
Fråga: Kan det ha varit något med Referensdatatyper kontra Primitiva datatyper som spökat här som jag inte förstått mig på?
Det är tillåtet att uppdatera värdet på elementen in en konstant array:
const myArr = [2,5,10];
myArr[2] = 50;
console.log(myArr); // [2, 5, 50]
Men den kan inte tilldelas ett nytt värde:
const myArr = [2,5,10];
myArr = [2,5,50]; // TypeError: Assignment to constant variable.
console.log(myArr); // Denna raden kommer inte exekveras
Sedan så har din variabel "skicka" redan beräknats och blivit tilldelad sitt värde på rad 84, och då var arg = [15,11,12,13,16].
Anropen till "output" sker först när de används i console.log(), och då blir elementen uppdaterade.
Betyder
return !(x % 2);
att den skall returerna "false" i och med ! framför parentesuttrycket?
x % 2 ger 0 om talet är jämnt och 1 om talet är ojämnt.
Sedan utnyttjas att det i många språk går att använda 0 som false och 1 (eller snarare allt utom 0) som true. Detta är en lite 'ful' genväg, då man egentligen bör använda en jämförelse med något för att få svaret som en faktisk bool och inte en int.
Det innebär att x % 2 ger falskt(0) om talet är jämnt, och sant(1) om talet är ojämnt.
Eftersom "frågan" är isEven, och inte isOdd, så vill vi ha sant om talet är jämnt och falskt om talet är ojämnt, alltså tvärtom mot vad x % 2 ger. Detta åtgärdas genom att negera hela uttrycket med ett ! framför, då !false = true och !true = false.
En mer lättläst kod är:
function isEven(x) {
return x % 2 == 0;
}
x % 2 ger 0 om talet är jämnt.
Jämförelsen 0 == 0, är true, så funktionen ger alltså true för ett jämnt tal.
x % 2 ger 1 om talet är ojämnt.
Jämförelsen 0 == 1, är false, så funktionen ger alltså false för ett ojämnt tal.
Koden för den som vill visa hur den kan refaktoriseras ytterligare:
// Jag älskar att skriva kommentarer med // och inte HTML-varianten...
let listOfNumbers = [62, 131, 33, -235, 162];
let FirstArrayLength = listOfNumbers.length;
console.log("NewArray före: " + listOfNumbers);
console.log("Så många nummer storlekssorteras: " + FirstArrayLength);
function SortArrayByBiggest(listOfNumbers) {
let newArray = [];
// Jag ville använda while(newArray != []) men då kraschade kompilatorn
for (let j = 0; j < FirstArrayLength; j++) {
let max = listOfNumbers[0]; // Dessa deklareras och/eller tilldelas om vid varje körning i loopar?
let GetArrayPos;
for (let i = 0; i < listOfNumbers.length; i++) {
// Ändra >= till <= för att sortera åt andra hållet!
if (listOfNumbers[i] >= max) {
max = listOfNumbers[i];
GetArrayPos = i; // Hämta position för element i Array som skall splicas
}
}
newArray.push(max); // Lägg till senast största siffra
listOfNumbers.splice(GetArrayPos, 1); // Plocka bort element i Array i position i
}
return newArray;
}
console.log("NewArray efter: " + SortArrayByBiggest(listOfNumbers));
Bra jobbat!
Här är ett sätt att lösa det utan en ny array, kallat "in place":
let listOfNumbers = [62, 131, 33, -235, 162];
console.log("Före: " + listOfNumbers);
// Iterera över alla element i listan
for (let j = 0; j < listOfNumbers.length; j++) {
// Iterera över resterade element i listan
// "i = j + 1" gör att vi börjar vid nästkommande index
for (let i = j + 1; i < listOfNumbers.length; i++) {
// Spara värdet vid index 'j', det värde vi ska jämför mot
let current = listOfNumbers[j];
// Spara värdet på efterföljade element
let next = listOfNumbers[i];
// Jämför om nuvarande element är mindre än nästa och om så är fallet, byter vi plats på dem
// Om inte så värdena lika eller redan sorterade och inget behöver göras
if (current < next) {
listOfNumbers[j] = next; // next innehåller värdet på index "i" och flyttas till "j"
listOfNumbers[i] = current // current innehåller värdet på index "j" och flyttas till "i"
}
}
}
console.log("Efter: " + listOfNumbers);
Din kommentar att du ville använda while(newArray != [])
fungerar inte av 2 anledningar:
Först så hade loopen aldrig ens startat eftersom newArray initieras till []
. Du kanske menade att skriva listOfNumbers?
Vilket smidigt leder till andra anledningen, att likhet mot []
aldrig ger sant. Den testar istället om båda leden hänvisar till samma objekt/instans, alltså "reference equality". När du skriver []
skapar du ett nytt anonymt objekt.
Kolla här:
let a = [];
let b = a; // b refererar till a
console.log(a == []); // false
console.log(b == []); // false
console.log(a == b); // true
console.log([] == []); // false, 2 olika anonyma objekt
Istället kan man titta på längden på arrayen precis som i en for-loop.
Lycka till och kämpa på!
Webbutvecklingsdagbok (Webbutveckling, 120 hp) | Dag 10, 11, 12 & 13 av 759
Dag 10, 11, 12 & 13 av 759 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Teoridagar för att förstå det fundamentala med ECMAScript
De senaste dagarna har präglats av mer teori än kodning. Jag har anlänt till vad som verkar vara halva kärnan i JS: datastrukturer. Andra antar jag är att göra något med dessa datastrukturer (metoder/funktioner?). Jag har förberett en laptop att komma igång med kodning när jag är på resande fot och så har jag fixat GitHub + Git så det fungerar.
För att försöka förstå det mest fundamentala med JS, men utan att försöka förstå mig på Assembly, så har jag tittat på flera YT-klipp om JS-motorn och JSRE för att förstå att hur detta är kopplat till kluriga koncept som bland annat "Variable Hoisting" och "Objects" med "Properties" och "Methods".
ECMAScript specificerar följande så kallade "Native Objects" (inbyggda objekt):
- Objects
- Arrays
- Promises (högre prioritet än EventHandler om jag förstått rätt)
- JSON
Webbläsare är en klientmiljö och erbjuder så kallade "Host Objects" (värdobjekt):
- Window
- Document
- History
- Navigator
- GPS i smartphones' webbläsare?
"Global object" är window (är document också det eller är det en nivå under window?), alltså webbläsarfönstret och här kan var-variabler lagras eller valfri variabel som tilldelas värde utan att deklareras först:
variabel_utan_variabeltyp = "hej"; // Denna hamnar under Global Scope och inte i Script Scope när kompilatorn behandlar den?
En sak som förvirrade mig för någon vecka sedan var varför jag inte kunde köra alert()-funktionen med terminalkommandot "node app.js". Svaret är att terminalen är servermiljön vilket i sin tur har helt andra objekt. Alert() är ett objekt i webbläsarens klientsida och inte ett objekt hos serversidan node.JS om jag fattat det korrekt nu?
Därför får jag felmeddelande om att alert inte är definierat för det objektet finns inte i servermiljön där jag försökte köra javaskriptet:
När jag körde index.html i webbläsaren så får jag upp första skriptet (som körs i <head>-taggen) och sedan andra skriptet som körs i slutet av <body>-taggen. I båda fall körs JS i en JSRE där objektet alert() finns inbyggt i webbläsarens objektsamling vilket tillgängliggörs innan?
"Variable Hoisting" verkar ha med att göra hur kompilatorn först deklarerar variabler (sätts till undefined först) i Global & Script Scopes innan den tilldelar dem värden? Även functions() deklareras här? Det hela har med "Execution Context Phases" att göra som jag tittade på här: https://www.youtube.com/watch?v=Fd9VaW0M7K4
Så för varje funktion som sedan anropas så skapas en ny Execution Context Phase? (01:57 i YT-klippet). Hursomhelst har denna teori jag förstått hittills klargjort tydligare för mig varför bland annat alert() i webbläsaren fungerar men inte i node.JS.
Rätta gärna allt som är svammel från mig!
Fråga: Varför används "this" överhuvudtaget? Vad är syftet med dess existens? Det enda jag vet om det är att det är kopplat till objekt. För mig också är det en av dessa förvirrande begrepp!
Mvh,
WKL.
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
Bra jobbat!
Här är ett sätt att lösa det utan en ny array, kallat "in place":
let listOfNumbers = [62, 131, 33, -235, 162];
console.log("Före: " + listOfNumbers);
// Iterera över alla element i listan
for (let j = 0; j < listOfNumbers.length; j++) {
// Iterera över resterade element i listan
// "i = j + 1" gör att vi börjar vid nästkommande index
for (let i = j + 1; i < listOfNumbers.length; i++) {
// Spara värdet vid index 'j', det värde vi ska jämför mot
let current = listOfNumbers[j];
// Spara värdet på efterföljade element
let next = listOfNumbers[i];
// Jämför om nuvarande element är mindre än nästa och om så är fallet, byter vi plats på dem
// Om inte så värdena lika eller redan sorterade och inget behöver göras
if (current < next) {
listOfNumbers[j] = next; // next innehåller värdet på index "i" och flyttas till "j"
listOfNumbers[i] = current // current innehåller värdet på index "j" och flyttas till "i"
}
}
}
console.log("Efter: " + listOfNumbers);
Din kommentar att du ville använda while(newArray != [])
fungerar inte av 2 anledningar:
Först så hade loopen aldrig ens startat eftersom newArray initieras till []
. Du kanske menade att skriva listOfNumbers?
Vilket smidigt leder till andra anledningen, att likhet mot []
aldrig ger sant. Den testar istället om båda leden hänvisar till samma objekt/instans, alltså "reference equality". När du skriver []
skapar du ett nytt anonymt objekt.
Kolla här:
let a = [];
let b = a; // b refererar till a
console.log(a == []); // false
console.log(b == []); // false
console.log(a == b); // true
console.log([] == []); // false, 2 olika anonyma objekt
Istället kan man titta på längden på arrayen precis som i en for-loop.
Lycka till och kämpa på!
Aha! Jag överkomplicerade det hela igen! Och jag glömde bort att även [] är ett objekt, om än tomt och alla objekt är unika om de har olika adresser i arbetsminnet?
Vad jag tänkte med while-loopen var att "Så länge listofNumbers INTE är tom så loopa följande nedan:". Innebär följande kod:
while(listofNumbers != ""){}
att "så länge innehållet i listofNumbers inte är tomt så kör koden inuti {}? Eller går det ens att göra? Fungerar kanske null eller undefined här på något vis?
Nu behövs förvisso inte while-loopen som kollar om listofNumbers är tom som följd av upprepad splice() för "in place" fungerar bättre istället!
Mvh,
WKL.
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
Dag 10, 11, 12 & 13 av 759 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Teoridagar för att förstå det fundamentala med ECMAScript
De senaste dagarna har präglats av mer teori än kodning. Jag har anlänt till vad som verkar vara halva kärnan i JS: datastrukturer. Andra antar jag är att göra något med dessa datastrukturer (metoder/funktioner?). Jag har förberett en laptop att komma igång med kodning när jag är på resande fot och så har jag fixat GitHub + Git så det fungerar.
För att försöka förstå det mest fundamentala med JS, men utan att försöka förstå mig på Assembly, så har jag tittat på flera YT-klipp om JS-motorn och JSRE för att förstå att hur detta är kopplat till kluriga koncept som bland annat "Variable Hoisting" och "Objects" med "Properties" och "Methods".
ECMAScript specificerar följande så kallade "Native Objects" (inbyggda objekt):
- Objects
- Arrays
- Promises (högre prioritet än EventHandler om jag förstått rätt)
- JSON
Webbläsare är en klientmiljö och erbjuder så kallade "Host Objects" (värdobjekt):
- Window
- Document
- History
- Navigator
- GPS i smartphones' webbläsare?
"Global object" är window (är document också det eller är det en nivå under window?), alltså webbläsarfönstret och här kan var-variabler lagras eller valfri variabel som tilldelas värde utan att deklareras först:
variabel_utan_variabeltyp = "hej"; // Denna hamnar under Global Scope och inte i Script Scope när kompilatorn behandlar den?
En sak som förvirrade mig för någon vecka sedan var varför jag inte kunde köra alert()-funktionen med terminalkommandot "node app.js". Svaret är att terminalen är servermiljön vilket i sin tur har helt andra objekt. Alert() är ett objekt i webbläsarens klientsida och inte ett objekt hos serversidan node.JS om jag fattat det korrekt nu?
Därför får jag felmeddelande om att alert inte är definierat för det objektet finns inte i servermiljön där jag försökte köra javaskriptet:
<Uppladdad bildlänk>
När jag körde index.html i webbläsaren så får jag upp första skriptet (som körs i <head>-taggen) och sedan andra skriptet som körs i slutet av <body>-taggen. I båda fall körs JS i en JSRE där objektet alert() finns inbyggt i webbläsarens objektsamling vilket tillgängliggörs innan?
"Variable Hoisting" verkar ha med att göra hur kompilatorn först deklarerar variabler (sätts till undefined först) i Global & Script Scopes innan den tilldelar dem värden? Även functions() deklareras här? Det hela har med "Execution Context Phases" att göra som jag tittade på här: https://www.youtube.com/watch?v=Fd9VaW0M7K4
Så för varje funktion som sedan anropas så skapas en ny Execution Context Phase? (01:57 i YT-klippet). Hursomhelst har denna teori jag förstått hittills klargjort tydligare för mig varför bland annat alert() i webbläsaren fungerar men inte i node.JS.
Rätta gärna allt som är svammel från mig!
Fråga: Varför används "this" överhuvudtaget? Vad är syftet med dess existens? Det enda jag vet om det är att det är kopplat till objekt. För mig också är det en av dessa förvirrande begrepp!
Mvh,
WKL.
Vissa saker hör till browsern som sagt, tidigare fanns inte Fetch i node heller.
Fetch API tillhör browsern liksom querySelector osv, så de kan väl teoretiskt användas av andra språk än JS också antar jag, har aldrig testat dock.
Aha! Jag överkomplicerade det hela igen! Och jag glömde bort att även [] är ett objekt, om än tomt och alla objekt är unika om de har olika adresser i arbetsminnet?
Vad jag tänkte med while-loopen var att "Så länge listofNumbers INTE är tom så loopa följande nedan:". Innebär följande kod:
while(listofNumbers != ""){}
att "så länge innehållet i listofNumbers inte är tomt så kör koden inuti {}? Eller går det ens att göra? Fungerar kanske null eller undefined här på något vis?
Nu behövs förvisso inte while-loopen som kollar om listofNumbers är tom som följd av upprepad splice() för "in place" fungerar bättre istället!
Mvh,
WKL.
Helt rätt resonerat med "Så länge listofNumbers INTE är tom så loopa följande nedan:"
while(listofNumbers != ""){}
fungerar faktiskt trots att det kan verka underligt att jämföra en lista med en sträng. Anledningen är att operatorn ==
följer ett mönster kallat IsLoosleyEqual
Det som händer är att listan först konverteras till en primitiv typ, i detta fallet en sträng mha toString()
metoden. Vill man inte ha det beteendet så använder man Strict equality (===
). Den ger alltid false om det är olika typ i båda leden.
Det jag menade med att använda längden på listan var så här:
let someList = ['apa', 'ko', 'häst'];
while (someList.length != 0) {
// someList.length > 0 fungerar också
// Gör något som krymper someList
console.log(someList.pop());
}
Då kan man även skriva while (someList.length)
vilket utnyttjar att vissa värden kan tolkas som Truthy eller Falsy. Detta är en smaksak och vad man själv (eller sitt team) anser är tydligast och lättläst.
Föreslår att du sparar ett bokmärke till https://developer.mozilla.org/en-US/ då det en av de viktigaste resurserna för webbutveckling, och bland de mest välskrivna dokumentationer som finns.
Dag 9 av 759 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Äntligen har jag sorterat minst -> störst (och tvärtom) i en siffer-Array!
Jag är nu i kapitlet 4 i EloquentJS som handlar om Objekt och Arrayer. Då tyckte jag det var hög tid att ge mig på att sortera siffror i en array. Det hela började med väldigt mycket skräpkod med olika loopförsök och det blev bara en stor kodsoppa:
<Uppladdad bildlänk>
Senare så upptäckte jag något mystiskt med const som verkade ändå tilldelas nytt värde trots att det skall vara en konstant? Men i bilden nedan så ser man hur const = arg [...] skickas till olika funktioner och sedan konsolloggas const = arg [...] som magiskt då verkar ha fått större värde? Men sista konsolloggen är (skicka) som använder metoden reduce() på const = arg [...] som då magiskt nog summera det första ursprungliga värdet 67?
<Uppladdad bildlänk>
Fråga: Kan det ha varit något med Referensdatatyper kontra Primitiva datatyper som spökat här som jag inte förstått mig på?
Sedan fortsatte jag med att försöka skapa en "Bubble Sort Function" men egentligen blev det aldrig en sådan. Jag upptäckte också ett problem: jag behövde plocka bort delar från Arrayen som skulle sorteras in i en ny. Jag tror att det finns en sorteringsfunktion man brukar få koda som heter "comb" som ska kunna sortera direkt inuti en och samma array istället för att skapa en ny som i mitt fall?
<Uppladdad bildlänk>
Till slut kom jag på svaret: jag behövde en metod som kunde ta bort det senaste största upptäckta elementet i en array samtidigt som den tryckte in den i en ny array som sedan returnerades. Tyvärr så tar pop() bort bara sista elementet så jag fick tyvärr göra det jag inte ville göra: googla hur man gör något i JS = ta bort utvalt element i en array.
Jag blev också tvungen för allra första gången att läsa inuti VSCode när den presenterade vilka olika parametrar gjorde i en metod för att kunna använda den rätt. Så Splice() kom till undsättningen och jag lyckades producera följande:
<Uppladdad bildlänk>
Koden för den som vill visa hur den kan refaktoriseras ytterligare:
// Jag älskar att skriva kommentarer med // och inte HTML-varianten...
let listOfNumbers = [62, 131, 33, -235, 162];
let FirstArrayLength = listOfNumbers.length;
console.log("NewArray före: " + listOfNumbers);
console.log("Så många nummer storlekssorteras: " + FirstArrayLength);
function SortArrayByBiggest(listOfNumbers) {
let newArray = [];
// Jag ville använda while(newArray != []) men då kraschade kompilatorn
for (let j = 0; j < FirstArrayLength; j++) {
let max = listOfNumbers[0]; // Dessa deklareras och/eller tilldelas om vid varje körning i loopar?
let GetArrayPos;
for (let i = 0; i < listOfNumbers.length; i++) {
// Ändra >= till <= för att sortera åt andra hållet!
if (listOfNumbers[i] >= max) {
max = listOfNumbers[i];
GetArrayPos = i; // Hämta position för element i Array som skall splicas
}
}
newArray.push(max); // Lägg till senast största siffra
listOfNumbers.splice(GetArrayPos, 1); // Plocka bort element i Array i position i
}
return newArray;
}
console.log("NewArray efter: " + SortArrayByBiggest(listOfNumbers));
Ändrar man >= till <= på rad 19 så kan man även sortera åt andra hållet. Tack vare att den loopar igen utifrån antalet element i arrayen så kan den sortera hur korta/långa arrayer som helst!
Jag lärde mig också en hel del om det mer tekniska om JS i webbläsaren i denna korta YT-serie: https://www.youtube.com/watch?v=-G9c4CMMUKc&list=PLillGF-Rfqb...
Nu blir det att sätta sig in i "Datastrukturer: Objekt och Arrayer". Är det inte lustigt att JavaScript inte är objektorienterad programmering men en stor del hur det manipulerar i webbläsaren är via DOM?
Vi ses imorgon!
Mvh,
WKL.
Du kan skriva om den såhär.
Istället för att manuellt behöva ändra >= till <= för att ändra från ascending till descending så kan man lägga in en jämförelse-funktion som skickas med i anropet.
function SortArray(listOfNumbers, comparator) {
// Här gör vi comparator-parametern till optional
// Om den inte sätts så är default sortAscending
if(comparator === undefined) {
comparator = sortAscending
}
for(var i=0; i<listOfNumbers.length-1; i++) {
for(var j=0; j<listOfNumbers.length-1-i; j++)
{
if(comparator(listOfNumbers[j], listOfNumbers[j+1])) {
let temp = listOfNumbers[j]
listOfNumbers[j] = listOfNumbers[j+1]
listOfNumbers[j+1] = temp
}
}
}
return listOfNumbers
}
function sortAscending(a, b) {
return a > b
}
function sortDescending(a,b) {
return a < b
}
// sortAscending och sortDescending går att snygga till ytterliga via lambda-funktioner.
Går att skriva som:
const sortAscendingLambda = (a,b) => a>b
// Med lambda-funktioner behöver man inte explicit skriva return, det sker implicit.
let arr = [20,30,15,29,35,60]
let newArr = SortArray(arr, sortDescending)
console.log(newArr)
10700K | NVIDIA RTX 3080
Webbutvecklingsdagbok (Webbutveckling, 120 hp) | Dag 14, 15, 16, 17, 18, 19, 20, 21 av 759
Dag 14, 15, 16, 17, 18, 19, 20, 21 av 759 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Tillfällig dipp i kodandet
Hej! En snabb uppdatering efter den långa frånvaron.
Imorgon är det bara en vecka kvar innan startskottet för distansutbildningen Webbutveckling 120 hp. Fram till dess har jag försökt lära mig grunderna i JS, HTML & CSS så gott som det gått. Jag har hamnat i en tillfällig dipp i kodandet när jag insett att Datastrukturer och Objekt är var det börjar bli riktigt komplicerat inom JS.
Jag förstår nu lite av "Imposter-syndromet" som vissa programmerare beskriver. Jag har ambitioner om att skapa en hemsida där jag erbjuder utlärandet av webbutveckling gratis på svenska i videoformat som ett sätt för att påskynda min egen inlärning. Men än så länge känner jag mest:Vem tror jag att jag är som ska lära andra att koda JS?
Jag har inte haft några att diskutera mitt kodande mer än forumet. Och alla svar jag fått här regelbundet är jag ytterst tacksam för! <3 Förhoppningsvis kommer jag att få igång en Discord-grupp med större del av de övriga distansstudenterna nästa vecka.
Fråga: Med vilka verktyg i webbläsaren, i VSCode och övriga verktyg, kan jag använda mig av för att bemästra de fundamentala delarna inom JS såsom GEC och FEC? Varje kodsnutt - avslutat med ";" - verkar köras i antingen GEC eller FEC?
Vi ses snart igen!
Mvh,
WKL.
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
Webbutvecklingsdagbok (Webbutveckling, 120 hp) | Dag 1 av 760 eller 790
Dag 1 av 760 eller 790 (Kurser: Datateknik GR (A), Webbutveckling I, 7,5 hp & Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp) | Nu har det börjat på riktigt?!
Idag den 29:e augusti 2022 så var det både introduktion till utbildningen och introduktionskursen i JS.
Jag passade på att skapa en Discord-grupp och cirka 70% av alla registrerade på utbildningen (drygt 100+) är med nu. Det var prat om plagiering och det jag funderar över är hur man ska kunna skriva viss kort kod utan att det är plagierat? 🤔
alert('Jag ska plugga Webbutbildning på distans'!);
Lärares kommentar: Vart copy&paste du det där?! 😂
Tänker jag rätt att det är 760 dagar: 365+365+30? Det är 2 års utbildning PLUS 30 dagar från och med idag med de två första kurserna? Eller blir det 60 dagar extra utöver två år eftersom det är 2 kurser i början som slutförs på 10 veckor? 790 dagar?
Rolig kuriosa är att utbildningen var den mest sökta hos hela universitetet bland alla tillgängliga utbildningar (inklusive på distans). Jag låg först på reserv 10 och trodde då att jag aldrig skulle komma in. Drygt 4000+ sökningar, 490 var någon annan siffra, kommer ej ihåg vad.
Vi ses imorgon igen - denna gång på riktigt!
Mvh,
WKL.
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
Ang. plagiat, jag skulle säga att det är en bedömningsfråga men begreppet verkshöjd lär ge en fingervisning. Att bara använda alert( ) är liksom inte unik kod som en person har hittat på. Om du däremot har byggt något mer invecklat "unikt" så har du upphovsrätt till den koden, dock kan någon annan ha råkat hitta på samma kod oberoende av dig. Samma dilemma som musik egentligen, du kan inte ta patent på typ 2 noter
I början när ni bygger väldigt simpla program finns det inte särskilt många enkla unika lösningar. Att då prata plagiat borde vara orimligt för en utbildningsledare.
När ni börjar ha inlämningsuppgifter som kräver att ni bygger något större, då finns där mycket större utrymme för att upptäcka plagiat.
Webbutvecklingsdagbok (Webbutveckling, 120 hp) | Moment 2 i 2 första kurser
Datateknik GR (A), Webbutveckling I, 7,5 hp
Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp)
Det blir veckovisa uppdateringar nu istället för det har varit en hel del att ta in.
Jag är färdig nu med de två första momenten i båda två ovannämnda kurser. Det går 2 kurser samtidigt (50% fart för båda) och de går hand i hand: HTML & CSS i ena kursen och Introduktion till JavaScript i andra.
Mer om JavaScript Introduktionskursen
Nedanför är mina inlämnade kodlösningar för Moment 2 i introduktionskursen för JavaScript (dessa är redan inlämnade så jag kan INTE ändra något i efterhand):
Samtidigt är alla välkomna att tipsa om hur respektive kod i respektive uppgift kan förbättras till nästa gång liknande uppgift/problem skall lösas!
Uppgift 1: Deklarera och skriv ut variabler
Uppgift 2: Skriv en funktion som returnerar produkten av två heltalsargument
Uppgift 3: Skriv ut fem färger ur en array och antalet värden i arrayen
Uppgift 4: Skriv ut alla udda tal mellan 3 och 23
Uppgift 5: Funktion som returnerar multiplikationstabellen för ett heltal

Uppgift 6:Omvandla minuter till timmar och minuter

Uppgift 7:Skriv ut längsta strängen från en array

Uppgift 8: Skriv ut dagens datum och tid i tre olika format


Just uppgift 8 var mycket givande för det krävde också att jag återanvände kod. Se t.ex. hur jag definierade alla olika delar av dagens datum att skriva ut istället för att skriva om samma kod igen i console.log() där jag då bara skriver de förkortade variabelnamnen.
En sak blev jag lite besviken över mig själv i uppgift 8: Jag blev tvungen att googla fram för att lösa problemet med att få en nolla framför månader, dagar, timmar och minuter när värdet blev lägre än 10. T.ex. dagens månad 9 skulle presenteras som 09 och då hittade jag en funktion för det av ren slump. Men då blev det ju inte jag själv som "kom på" den simpla funktionen? (det är addZero()-funktionen i Uppgift 8).
Och det är just denna lilla bit jag oroar mig över: att jag inte ska kunna upptäcka algoritmiska lösningar utan bara söka mer eller mindre färdiga lösningar på dem. Å ena sidan är det ju onödigt för mig att försöka återuppfinna hjulet på nytt - å andra sidan är det väl bra om man ändå måste kunna göra det den dagen då det verkligen behövs?
Det är min fråga: När ska man "uppfinna hjulet på nytt" inom Webbutveckling?
Härnäst (nästa moment 3) inom Introduktionskursen i JavaScript blir det DOM och skapa en ToDo-webbapplikation om jag minns rätt.
Mer om Webbutveckling I
Moment 2 i Webbutveckling I var ett delmoment med teorifrågor som besvarades i en labbrapport och ett annat delmoment där jag fick koda en simpel HTML5-hemsida med länkar, bilder, listor samt tabeller. Hemsidan laddades sedan upp på mitt eget serverutrymme hos universitetet där jag pluggar på distans hos.
Jag inväntar fortfarande godkännande på den. I Moment 3 & 4 så kommer samma grundläggande hemsida att piffas upp med CSS-kod som sedan i sin tur kommer att bli responsiv. Så momenten bygger på varandra och det gillar jag starkt!
Mvh,
WKL.
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
En sak blev jag lite besviken över mig själv i uppgift 8: Jag blev tvungen att googla fram för att lösa problemet med att få en nolla framför månader, dagar, timmar och minuter när värdet blev lägre än 10. T.ex. dagens månad 9 skulle presenteras som 09 och då hittade jag en funktion för det av ren slump. Men då blev det ju inte jag själv som "kom på" den simpla funktionen? (det är addZero()-funktionen i Uppgift 8).
Och det är just denna lilla bit jag oroar mig över: att jag inte ska kunna upptäcka algoritmiska lösningar utan bara söka mer eller mindre färdiga lösningar på dem. Å ena sidan är det ju onödigt för mig att försöka återuppfinna hjulet på nytt - å andra sidan är det väl bra om man ändå måste kunna göra det den dagen då det verkligen behövs?
Det är min fråga: När ska man "uppfinna hjulet på nytt" inom Webbutveckling?
Det är sånt som kommer när man blir mer van kodare att komma på smidiga lösningar på sådana problem. En del problem har olika lösningar där det är en smaksak med vilken lösning man väljer och en del saker har blivit en defakto standard.
För datum finns det vofta en datumfunktion där man talar om hur datumet ska formateras med yymmdd osv. som jag förstått det. Jag har kodat lite php på hobbynivå, så inget proffs.
Där finns alltid utrymme för att förbättra sig när det kommer till algoritmer. Många utvecklare jag arbetar med kör stack-ove när de behöver en algoritm istället för att skriva något själv. Detta är i regel en rätt liten del av arbetet, en stor del av livet som utvecklare går ut på att bygga vidare på sådant som redan finns, på gott och ont.
Är detta något du oroar dig för så kan du börja träna på algoritmer och datastrukturer för att få en lite djupare förståelse för vad som händer under huven.
Detta är inget jag gjorde under min utbildning, men nu när jag arbetar och har en stund över sitter jag en del på leetcode och knackar fram lösningar. Jag tycker det är riktigt roligt
https://leetcode.com/ << om du skulle vara intresserad. Du väljer själv programmeringsspråk
Jag har hittills löst 5% av leetcodes problem utan att skaffa premium, tänkte att jag ska komma så långt jag känner att jag kan utan att skaffa premium. Än så länge tycker jag inte att jag saknar något, så se det som en gratistjänst fram tills du blir riktigt biten
Webbutvecklingsdagbok (Webbutveckling, 120 hp) | Momenten 3-5 i JS Intro-kursen
Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp)
Här följer en massiv uppdatering efter lite mer än 1 månad in i utbildningen!
Jag är klar med flera moment i JavaScript-introduktionskursen. I HTML & CSS-introduktionskursen har jag kvar de praktiska momenten (CSS-kod av HTML-hemsida, och en responsiv sida).
Projektuppgiften i JS-introduktionskursen är att anropa Sveriges Radio API och använda en JSON-sträng för att erbjuda en webbtjänst.
Projektuppgiften i HTML & CSS-introduktionskursen är att skapa en responsiv hemsida som ska vara så användarvänlig för alla olika surfenheter (mobiler, surfplattor, skärmläsare).
Här nedan följer mina inlämnade lösningar på de olika praktiska momenten inom JS-introduktionskursen.
Först ser du koden och sedan ser du ett bildexempel på slutresultatet!
Moment 3.2 i JS-Intro - En förenklad ToDo-app med localStorage
/* Lösning till Uppgift 3.2 (Moment 3.2 i DT084G) Av WebbkodsLärlingen, 2022 */
'use strict';
// Variabler som används regelbundet
let addTodoItemEl = document.getElementById('newtodo'); // För att läsa av input-värdet senare
let addTodoBtnEl = document.getElementById('newtodobutton'); // För att lägga till ny Att göra
let todoListEl = document.getElementById('todolist'); // Här hamnar alla inlästa & tillagda Att göra-articles
let errorMsgEl = document.getElementById('message'); // För att visa felmeddelande vid för kort sträng
let clearAllBtnEl = document.getElementById('clearbutton'); // För att kunna rensa hela Att göra-listan
let i; // Iteratorvariabel för regelbundna loopar
// Händelsehanterare som används regelbundet
addTodoItemEl.addEventListener('keyup', checkTextLength, false); // Kontrollera inmatningslängd
addTodoBtnEl.addEventListener('click' || '', addTodo, false); // Lägga till i Att göra-listan
clearAllBtnEl.addEventListener('click', clearTodos, false); // Rensa alla Att göra-articles från sidan
window.onload = init; // När sidan laddats fram, anropa funktionen init()
// Initering
function init() {
console.log('Initierar massa...');
// Töm inmatningsfält och inaktivera Lägg till-knapp (lämpligt när sidan startas om med F5)
addTodoItemEl.value = '';
addTodoBtnEl.disabled = true;
// Ladda sedan in nuvarande Att göra-articles som finns
loadTodos();
}
// Funktion: Kontrollera textlängd
function checkTextLength() {
console.log('Kontrollerar textlängden för inmatningsfältet...');
// Lagra värdet från inmatningsfältet
let input = addTodoItemEl.value;
// Kontrollera om längden är minst fem tecken lång
if (input.length > 4) {
errorMsgEl.innerHTML = ''; // Visa INGET felmeddelande
addTodoBtnEl.disabled = false; // Aktivera Lägg till-knapp
} else {
// Om färre än 5 tecken så visa felmeddelande
errorMsgEl.innerHTML = 'Ange minst fem tecken först!';
addTodoBtnEl.disabled = true; // Inaktivera Lägg till-knapp
}
}
// Funtkion: Lägga till i Att göra-listan
function addTodo() {
console.log('Lägger till i Att göra-listan...');
// Lagra värdet från inmatningsfältet
let input = addTodoItemEl.value;
// Skapa ett article-element och sen text till den (textnod)
let newArticleEl = document.createElement('article');
let newArticleTextNode = document.createTextNode(input); // textnoden är inmatningsfältets lagrade värde
newArticleEl.appendChild(newArticleTextNode); // Slå samman HTML-element och dess innehåll
// Lägg till det skapta article-elementet och dess textnod under <section>-elementet
todoListEl.appendChild(newArticleEl);
// Händelsehanterare till skapad <article>som tar bort ur DOM och
// sparar det som finns kvar i DOM. På så vis kan valfritt element
// tas bort med ett enkelt knapptryck medan resten sparas!
newArticleEl.addEventListener('click', function (e) {
e.target.remove();
console.log('Tar bort ett element!');
saveTodos();
});
// Töm inmatningsfält och inaktivera Lägg till-knapp
addTodoItemEl.value = '';
addTodoBtnEl.disabled = true;
// Anropar lagringsfunktionen som använder localStorage() för att spara lokalt
saveTodos();
}
// Funktion: Spara nuvarande <article>-Att göra till localStorage()
function saveTodos() {
console.log('Sparar nuvarande Att göra-articles som finns...');
// Läs in nuvarande Att göra-articles
let todos = document.getElementsByTagName('article');
// Skapa temporär arrayvariabel
let tempArr = [];
// Loopar igenom listan och lagrar till den temporära arrayvariabeln
for (i = 0; i < todos.length; i++) {
tempArr.push(todos[i].innerHTML);
}
// Omvandla den genomloopade arrayen till en JSON-sträng
// Lagra sedan i lokalt Web Storage
let jsonStr = JSON.stringify(tempArr);
localStorage.setItem('todos', jsonStr);
}
// Funktion: Läser in nuvarande Att göra-articles
function loadTodos() {
console.log('Försöker läsa in lagrade Att göra-articles...');
// Hämtar localStorage-textsträng och omvandlar till JSON
let todos = JSON.parse(localStorage.getItem('todos'));
// Loopar igenom den inlästa arrayen todos och skapar article-element
// och dess textnode[i] så länge localStorage INTE är tom (null)
if (todos != null) {
console.log('localStorage innehåller något. Läser in: [' + todos + ']');
for (i = 0; i < todos.length; i++) {
let newArticleEl = document.createElement('article');
let newArticleTextNode = document.createTextNode(todos[i]);
newArticleEl.appendChild(newArticleTextNode);
todoListEl.appendChild(newArticleEl);
// Händelsehanterare som tar bort ur DOM och sparar det
// som finns kvar i DOM. På så vis kan valfritt element
// tas bort med ett enkelt knapptryck medan resten sparas!
newArticleEl.addEventListener('click', function (e) {
e.target.remove();
console.log('Tar bort ett element!');
saveTodos();
});
}
} else {
// Annars om localStorage är tomt vid inläsningen av den
console.log('localStorage är tomt. Finns inget att läsa in!');
}
}
// Funktion: Rensa localStorage OCH i DOM
function clearTodos() {
console.log('Rensar alla Att göra-articles och laddar om...');
localStorage.clear(); // Rensar localStorage
document.getElementById('todolist').innerHTML = '';
init(); // Anropa init (inaktivera knapp+töm inmatningsfält)
}
Moment 4.1 - Objekt & JSON - Skapa och skriva ut objekt i webbläsaren
/* Lösning till Uppgift 4.1 Av WebbkodsLärlingen, 2022 */
'use strict';
// JS-FilmObjekt1 med egenskaperna title, category, playtime och metoden getInformation
let movie1 = {
title: 'Jurassic Park',
category: 'Science Fiction',
playtime: 127,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime}, minuter` + '\n';
},
};
// JS-FilmObjekt2 med egenskaperna title, category, playtime och metoden getInformation
let movie2 = {
title: 'Jurassic Park II',
category: 'Science Fiction',
playtime: 129,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
},
};
// JS-FilmObjekt3 med egenskaperna title, category, playtime och metoden getInformation
let movie3 = {
title: 'Jurassic Park III',
category: 'Science Fiction',
playtime: 92,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
},
};
// JS-FilmObjekt4 med egenskaperna title, category, playtime och metoden getInformation
let movie4 = new Object();
movie4.title = 'Jurassic World: Dominion Extended Edition';
movie4.category = 'Science Fiction';
movie4.playtime = 146;
movie4.getInformation = function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
};
// JS-objekt med referenser till vardera objekts metod
let movies = {
a: movie1.getInformation(),
b: movie2.getInformation(),
c: movie3.getInformation(),
d: movie4.getInformation(),
};
// Töm inmatningsfältet först
document.getElementById('output').value = '';
// Mata ut varje JS-filmobjekt i inmatningsfältet med hjälp av value-metoden
document.getElementById('output').value += movies.a;
document.getElementById('output').value += movies.b;
document.getElementById('output').value += movies.c;
document.getElementById('output').value += movies.d;
Moment 4.2 - Objekt & JSON - Skapa en validerad JSON-fil
{
"student": {
"information": {
"name": "WebbkodsLärlingen",
"email": "WebbkodsLärlingen@student.miun.se",
"city": "Sundsvall",
"website": "http://studenter.miun.se/~WebbkodsLärlingen/"
},
"websites": [{
"sitename": "Mittuniversitetet",
"siteurl": "https://www.miun.se/",
"description": "Detta är hemsidan där jag studerade Projektledning med inriktning i Folkhälsovetenskap och där jag för närvarande studerar - på distans - Webbutvecklingsprogrammet."
},
{
"sitename": "Bio Drakstaden",
"siteurl": "https://www.biodrakstaden.se/",
"description": "När du vill boka in för kommande filmer i staden Sundsvall. Tidigare var det Filmstaden som bedrev det."
},
{
"sitename": "Systembolaget",
"siteurl": "https://www.systembolaget.se/",
"description": "Här går det att köpa alkohol på nätet. Kanske det bästa eller sämsta som någonsin har gjorts?"
},
{
"sitename": "Data Structures: Objects and Arrays :: Eloquent JavaScript",
"siteurl": "https://eloquentjavascript.net/04_data.html",
"description": "Kapitlet om objekt och arrayer vilket inkluderar JSON vilket denna fil är. Upplev meta av det hela!"
},
{
"sitename": "stackoverflow - What is JSONP, and why was it created?",
"siteurl": "https://stackoverflow.com/questions/2067472/what-is-jsonp-and...",
"description": "En direktlänk till en fråga om vad JSONP är för något och varför det skapades. Observera att det INTE är samma sak som JSON, tydligen."
}]
}
}
Moment 5.1 AJAX & Webbtjänster - Anrop med XMLHttpRequest
/* Lösning till Uppgift 5.1 Av WebbkodsLärlingen, 2022 */
'use strict';
// Skapa nytt AJAX-objekt
let xhttp = new XMLHttpRequest();
// Objektet väntar på Utförd Förfrågan (Request Finished) med färdigt svar (Response),
// dvs., 4 OCH samtidigt som dess statusmeddelande från servern ska vara OK (200)
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
// Omvandla JSON-filens mottagna text (alltså från this.responseText) till hanterbart JS-objekt
let jsonStr = JSON.parse(this.responseText);
// 'Positionera' sig vid info-Div inuti HTML-filen för DOM-manipulering
let infoDiv = document.getElementById('info');
// Skriv ut studentnamn, studente-post & studentwebbplats från student.json med lämpliga radbrytningar
infoDiv.innerHTML += `<strong style="font-weight: bold;">Namn:</strong> ${jsonStr.student.information.name} <br>
<strong style="font-weight: bold;">E-post:</strong> <a href="mailto:${jsonStr.student.information.email}">${jsonStr.student.information.email}</a><br>
<strong style="font-weight: bold;">Webbplats:</strong> <a href="${jsonStr.student.information.website}" target="_blank">${jsonStr.student.information.website}</a><br>`;
// 'Positionera' sig vid sites-ul-listan inuti HTML-filen för DOM-manipulering
let sitesUl = document.getElementById('sites');
// Skriv ut följande med hjälp av loop: webbplatsens fullständiga adress (href), beskrivning (title) och webbsidans namn <ahref="">här</a>
for (let i = 0; i < jsonStr.student.websites.length; i++) {
sitesUl.innerHTML += `<li><a href="${jsonStr.student.websites[i].siteurl}" target="_blank" title="${jsonStr.student.websites[i].description}">${jsonStr.student.websites[i].sitename}</a></li>`;
}
}
};
xhttp.open('GET', 'student.json', true);
xhttp.send();
Moment 5.2 AJAX & Webbtjänster - Anrop med Fetch
/* Lösning till Uppgift 5.2 Av WebbkodsLärlingen, 2022 */
'use strict';
// Hämta data från lokal student.json-fil
fetch('student.json')
// Om det lyckas så omvandla all response-data till JSON-data med hjälp av .json()-metoden
.then((response) => response.json())
// Om även det lyckas så använd sedan denna JSON-data (lagrad i jsonStr) för att köra följande pilfunktion:
.then((jsonStr) => {
// Exakt samma DOM-manipulering som från XMLHttpRequest-momentet kan tillämpas härifrån!
// 'Positionera' sig vid info-Div inuti HTML-filen för DOM-manipulering |
let infoDiv = document.getElementById('info');
// Skriv ut studentnamn, studente-post & studentwebbplats från student.json med lämpliga radbrytningar
infoDiv.innerHTML += `<strong style="font-weight: bold;">Namn:</strong> ${jsonStr.student.information.name} <br>
<strong style="font-weight: bold;">E-post:</strong> <a href="mailto:${jsonStr.student.information.email}">${jsonStr.student.information.email}</a><br>
<strong style="font-weight: bold;">Webbplats:</strong> <a href="${jsonStr.student.information.website}" target="_blank">${jsonStr.student.information.website}</a><br>`;
// 'Positionera' sig vid sites-ul-listan <ul>-elementet inuti HTML-filen för DOM-manipulering
let sitesUl = document.getElementById('sites');
// Skriv ut följande med hjälp av loop: webbplatsens fullständiga adress (href), beskrivning (title) och webbsidans namn <ahref="">här</a>
for (let i = 0; i < jsonStr.student.websites.length; i++) {
sitesUl.innerHTML += `<li><a href="${jsonStr.student.websites[i].siteurl}" target="_blank" title="${jsonStr.student.websites[i].description}">${jsonStr.student.websites[i].sitename}</a></li>`;
}
});
Det är exakt samma resultat för Moment 5.1 som i Moment 5.2:
Den som vill och orkar får gärna ge återkoppling på hur jag kan förbättra viss kod (refaktorisering)!
Till sist så vill jag berätta att för denna distansutbildning så verkar det vara upp till att nästan hälften hoppar av programmet innan sista kursen! I Discordgruppen jag är med i så berättar en hel del om hur icke "nybörjarvänligt" introduktionskurserna är för de som kommer med noll förkunskaper om kodning/programmering.
Jag har nästan funderat att på egen hand börja skapa simpla YouTube-klipp som förklarar koncept inom HTML, CSS & JS på ren och simpel svenska i takt med att jag själv lär och bemästrar samma koncept!
Fråga: Vad har du för tips för de som kommer med nästan noll förkunskaper inom kodning och programmering för att de skall komma i kapp de som redan är mer tekniskt lagda/intresserade?
På återseende!
Mvh,
WKL.
"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"
Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp)
Här följer en massiv uppdatering efter lite mer än 1 månad in i utbildningen!
Jag är klar med flera moment i JavaScript-introduktionskursen. I HTML & CSS-introduktionskursen har jag kvar de praktiska momenten (CSS-kod av HTML-hemsida, och en responsiv sida).
Projektuppgiften i JS-introduktionskursen är att anropa Sveriges Radio API och använda en JSON-sträng för att erbjuda en webbtjänst.
Projektuppgiften i HTML & CSS-introduktionskursen är att skapa en responsiv hemsida som ska vara så användarvänlig för alla olika surfenheter (mobiler, surfplattor, skärmläsare).
Här nedan följer mina inlämnade lösningar på de olika praktiska momenten inom JS-introduktionskursen.
Först ser du koden och sedan ser du ett bildexempel på slutresultatet!
Moment 3.2 i JS-Intro - En förenklad ToDo-app med localStorage
/* Lösning till Uppgift 3.2 (Moment 3.2 i DT084G) Av WebbkodsLärlingen, 2022 */
'use strict';
// Variabler som används regelbundet
let addTodoItemEl = document.getElementById('newtodo'); // För att läsa av input-värdet senare
let addTodoBtnEl = document.getElementById('newtodobutton'); // För att lägga till ny Att göra
let todoListEl = document.getElementById('todolist'); // Här hamnar alla inlästa & tillagda Att göra-articles
let errorMsgEl = document.getElementById('message'); // För att visa felmeddelande vid för kort sträng
let clearAllBtnEl = document.getElementById('clearbutton'); // För att kunna rensa hela Att göra-listan
let i; // Iteratorvariabel för regelbundna loopar
// Händelsehanterare som används regelbundet
addTodoItemEl.addEventListener('keyup', checkTextLength, false); // Kontrollera inmatningslängd
addTodoBtnEl.addEventListener('click' || '', addTodo, false); // Lägga till i Att göra-listan
clearAllBtnEl.addEventListener('click', clearTodos, false); // Rensa alla Att göra-articles från sidan
window.onload = init; // När sidan laddats fram, anropa funktionen init()
// Initering
function init() {
console.log('Initierar massa...');
// Töm inmatningsfält och inaktivera Lägg till-knapp (lämpligt när sidan startas om med F5)
addTodoItemEl.value = '';
addTodoBtnEl.disabled = true;
// Ladda sedan in nuvarande Att göra-articles som finns
loadTodos();
}
// Funktion: Kontrollera textlängd
function checkTextLength() {
console.log('Kontrollerar textlängden för inmatningsfältet...');
// Lagra värdet från inmatningsfältet
let input = addTodoItemEl.value;
// Kontrollera om längden är minst fem tecken lång
if (input.length > 4) {
errorMsgEl.innerHTML = ''; // Visa INGET felmeddelande
addTodoBtnEl.disabled = false; // Aktivera Lägg till-knapp
} else {
// Om färre än 5 tecken så visa felmeddelande
errorMsgEl.innerHTML = 'Ange minst fem tecken först!';
addTodoBtnEl.disabled = true; // Inaktivera Lägg till-knapp
}
}
// Funtkion: Lägga till i Att göra-listan
function addTodo() {
console.log('Lägger till i Att göra-listan...');
// Lagra värdet från inmatningsfältet
let input = addTodoItemEl.value;
// Skapa ett article-element och sen text till den (textnod)
let newArticleEl = document.createElement('article');
let newArticleTextNode = document.createTextNode(input); // textnoden är inmatningsfältets lagrade värde
newArticleEl.appendChild(newArticleTextNode); // Slå samman HTML-element och dess innehåll
// Lägg till det skapta article-elementet och dess textnod under <section>-elementet
todoListEl.appendChild(newArticleEl);
// Händelsehanterare till skapad <article>som tar bort ur DOM och
// sparar det som finns kvar i DOM. På så vis kan valfritt element
// tas bort med ett enkelt knapptryck medan resten sparas!
newArticleEl.addEventListener('click', function (e) {
e.target.remove();
console.log('Tar bort ett element!');
saveTodos();
});
// Töm inmatningsfält och inaktivera Lägg till-knapp
addTodoItemEl.value = '';
addTodoBtnEl.disabled = true;
// Anropar lagringsfunktionen som använder localStorage() för att spara lokalt
saveTodos();
}
// Funktion: Spara nuvarande <article>-Att göra till localStorage()
function saveTodos() {
console.log('Sparar nuvarande Att göra-articles som finns...');
// Läs in nuvarande Att göra-articles
let todos = document.getElementsByTagName('article');
// Skapa temporär arrayvariabel
let tempArr = [];
// Loopar igenom listan och lagrar till den temporära arrayvariabeln
for (i = 0; i < todos.length; i++) {
tempArr.push(todos[i].innerHTML);
}
// Omvandla den genomloopade arrayen till en JSON-sträng
// Lagra sedan i lokalt Web Storage
let jsonStr = JSON.stringify(tempArr);
localStorage.setItem('todos', jsonStr);
}
// Funktion: Läser in nuvarande Att göra-articles
function loadTodos() {
console.log('Försöker läsa in lagrade Att göra-articles...');
// Hämtar localStorage-textsträng och omvandlar till JSON
let todos = JSON.parse(localStorage.getItem('todos'));
// Loopar igenom den inlästa arrayen todos och skapar article-element
// och dess textnode[i] så länge localStorage INTE är tom (null)
if (todos != null) {
console.log('localStorage innehåller något. Läser in: [' + todos + ']');
for (i = 0; i < todos.length; i++) {
let newArticleEl = document.createElement('article');
let newArticleTextNode = document.createTextNode(todos[i]);
newArticleEl.appendChild(newArticleTextNode);
todoListEl.appendChild(newArticleEl);
// Händelsehanterare som tar bort ur DOM och sparar det
// som finns kvar i DOM. På så vis kan valfritt element
// tas bort med ett enkelt knapptryck medan resten sparas!
newArticleEl.addEventListener('click', function (e) {
e.target.remove();
console.log('Tar bort ett element!');
saveTodos();
});
}
} else {
// Annars om localStorage är tomt vid inläsningen av den
console.log('localStorage är tomt. Finns inget att läsa in!');
}
}
// Funktion: Rensa localStorage OCH i DOM
function clearTodos() {
console.log('Rensar alla Att göra-articles och laddar om...');
localStorage.clear(); // Rensar localStorage
document.getElementById('todolist').innerHTML = '';
init(); // Anropa init (inaktivera knapp+töm inmatningsfält)
}
<Uppladdad bildlänk>
Moment 4.1 - Objekt & JSON - Skapa och skriva ut objekt i webbläsaren
/* Lösning till Uppgift 4.1 Av WebbkodsLärlingen, 2022 */
'use strict';
// JS-FilmObjekt1 med egenskaperna title, category, playtime och metoden getInformation
let movie1 = {
title: 'Jurassic Park',
category: 'Science Fiction',
playtime: 127,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime}, minuter` + '\n';
},
};
// JS-FilmObjekt2 med egenskaperna title, category, playtime och metoden getInformation
let movie2 = {
title: 'Jurassic Park II',
category: 'Science Fiction',
playtime: 129,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
},
};
// JS-FilmObjekt3 med egenskaperna title, category, playtime och metoden getInformation
let movie3 = {
title: 'Jurassic Park III',
category: 'Science Fiction',
playtime: 92,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
},
};
// JS-FilmObjekt4 med egenskaperna title, category, playtime och metoden getInformation
let movie4 = new Object();
movie4.title = 'Jurassic World: Dominion Extended Edition';
movie4.category = 'Science Fiction';
movie4.playtime = 146;
movie4.getInformation = function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
};
// JS-objekt med referenser till vardera objekts metod
let movies = {
a: movie1.getInformation(),
b: movie2.getInformation(),
c: movie3.getInformation(),
d: movie4.getInformation(),
};
// Töm inmatningsfältet först
document.getElementById('output').value = '';
// Mata ut varje JS-filmobjekt i inmatningsfältet med hjälp av value-metoden
document.getElementById('output').value += movies.a;
document.getElementById('output').value += movies.b;
document.getElementById('output').value += movies.c;
document.getElementById('output').value += movies.d;
<Uppladdad bildlänk>
Moment 4.2 - Objekt & JSON - Skapa en validerad JSON-fil
{
"student": {
"information": {
"name": "WebbkodsLärlingen",
"email": "WebbkodsLärlingen@student.miun.se",
"city": "Sundsvall",
"website": "http://studenter.miun.se/~WebbkodsLärlingen/"
},
"websites": [{
"sitename": "Mittuniversitetet",
"siteurl": "https://www.miun.se/",
"description": "Detta är hemsidan där jag studerade Projektledning med inriktning i Folkhälsovetenskap och där jag för närvarande studerar - på distans - Webbutvecklingsprogrammet."
},
{
"sitename": "Bio Drakstaden",
"siteurl": "https://www.biodrakstaden.se/",
"description": "När du vill boka in för kommande filmer i staden Sundsvall. Tidigare var det Filmstaden som bedrev det."
},
{
"sitename": "Systembolaget",
"siteurl": "https://www.systembolaget.se/",
"description": "Här går det att köpa alkohol på nätet. Kanske det bästa eller sämsta som någonsin har gjorts?"
},
{
"sitename": "Data Structures: Objects and Arrays :: Eloquent JavaScript",
"siteurl": "https://eloquentjavascript.net/04_data.html",
"description": "Kapitlet om objekt och arrayer vilket inkluderar JSON vilket denna fil är. Upplev meta av det hela!"
},
{
"sitename": "stackoverflow - What is JSONP, and why was it created?",
"siteurl": "https://stackoverflow.com/questions/2067472/what-is-jsonp-and...",
"description": "En direktlänk till en fråga om vad JSONP är för något och varför det skapades. Observera att det INTE är samma sak som JSON, tydligen."
}]
}
}
<Uppladdad bildlänk>
Moment 5.1 AJAX & Webbtjänster - Anrop med XMLHttpRequest
/* Lösning till Uppgift 5.1 Av WebbkodsLärlingen, 2022 */
'use strict';
// Skapa nytt AJAX-objekt
let xhttp = new XMLHttpRequest();
// Objektet väntar på Utförd Förfrågan (Request Finished) med färdigt svar (Response),
// dvs., 4 OCH samtidigt som dess statusmeddelande från servern ska vara OK (200)
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
// Omvandla JSON-filens mottagna text (alltså från this.responseText) till hanterbart JS-objekt
let jsonStr = JSON.parse(this.responseText);
// 'Positionera' sig vid info-Div inuti HTML-filen för DOM-manipulering
let infoDiv = document.getElementById('info');
// Skriv ut studentnamn, studente-post & studentwebbplats från student.json med lämpliga radbrytningar
infoDiv.innerHTML += `<strong style="font-weight: bold;">Namn:</strong> ${jsonStr.student.information.name} <br>
<strong style="font-weight: bold;">E-post:</strong> <a href="mailto:${jsonStr.student.information.email}">${jsonStr.student.information.email}</a><br>
<strong style="font-weight: bold;">Webbplats:</strong> <a href="${jsonStr.student.information.website}" target="_blank">${jsonStr.student.information.website}</a><br>`;
// 'Positionera' sig vid sites-ul-listan inuti HTML-filen för DOM-manipulering
let sitesUl = document.getElementById('sites');
// Skriv ut följande med hjälp av loop: webbplatsens fullständiga adress (href), beskrivning (title) och webbsidans namn <ahref="">här</a>
for (let i = 0; i < jsonStr.student.websites.length; i++) {
sitesUl.innerHTML += `<li><a href="${jsonStr.student.websites[i].siteurl}" target="_blank" title="${jsonStr.student.websites[i].description}">${jsonStr.student.websites[i].sitename}</a></li>`;
}
}
};
xhttp.open('GET', 'student.json', true);
xhttp.send();
Moment 5.2 AJAX & Webbtjänster - Anrop med Fetch
/* Lösning till Uppgift 5.2 Av WebbkodsLärlingen, 2022 */
'use strict';
// Hämta data från lokal student.json-fil
fetch('student.json')
// Om det lyckas så omvandla all response-data till JSON-data med hjälp av .json()-metoden
.then((response) => response.json())
// Om även det lyckas så använd sedan denna JSON-data (lagrad i jsonStr) för att köra följande pilfunktion:
.then((jsonStr) => {
// Exakt samma DOM-manipulering som från XMLHttpRequest-momentet kan tillämpas härifrån!
// 'Positionera' sig vid info-Div inuti HTML-filen för DOM-manipulering |
let infoDiv = document.getElementById('info');
// Skriv ut studentnamn, studente-post & studentwebbplats från student.json med lämpliga radbrytningar
infoDiv.innerHTML += `<strong style="font-weight: bold;">Namn:</strong> ${jsonStr.student.information.name} <br>
<strong style="font-weight: bold;">E-post:</strong> <a href="mailto:${jsonStr.student.information.email}">${jsonStr.student.information.email}</a><br>
<strong style="font-weight: bold;">Webbplats:</strong> <a href="${jsonStr.student.information.website}" target="_blank">${jsonStr.student.information.website}</a><br>`;
// 'Positionera' sig vid sites-ul-listan <ul>-elementet inuti HTML-filen för DOM-manipulering
let sitesUl = document.getElementById('sites');
// Skriv ut följande med hjälp av loop: webbplatsens fullständiga adress (href), beskrivning (title) och webbsidans namn <ahref="">här</a>
for (let i = 0; i < jsonStr.student.websites.length; i++) {
sitesUl.innerHTML += `<li><a href="${jsonStr.student.websites[i].siteurl}" target="_blank" title="${jsonStr.student.websites[i].description}">${jsonStr.student.websites[i].sitename}</a></li>`;
}
});
Det är exakt samma resultat för Moment 5.1 som i Moment 5.2:
<Uppladdad bildlänk>
Den som vill och orkar får gärna ge återkoppling på hur jag kan förbättra viss kod (refaktorisering)!
Till sist så vill jag berätta att för denna distansutbildning så verkar det vara upp till att nästan hälften hoppar av programmet innan sista kursen! I Discordgruppen jag är med i så berättar en hel del om hur icke "nybörjarvänligt" introduktionskurserna är för de som kommer med noll förkunskaper om kodning/programmering.
Jag har nästan funderat att på egen hand börja skapa simpla YouTube-klipp som förklarar koncept inom HTML, CSS & JS på ren och simpel svenska i takt med att jag själv lär och bemästrar samma koncept!
Fråga: Vad har du för tips för de som kommer med nästan noll förkunskaper inom kodning och programmering för att de skall komma i kapp de som redan är mer tekniskt lagda/intresserade?
På återseende!
Mvh,
WKL.
Det verkar helt enkelt vara mer regel än undantag att många som saknar det riktiga intresset söker dessa utbildningar.
Är i slutet på en YH nu och vi är typ hälften så många som vi var i början. Många inser nog inte hur mycket tid man behöver lägga i början om man är helt ny, vissa tror att det räcker med schemalagda dagar men det kommer man inte så långt på.
För egen del hade jag redan suttit i något år före utbildningen och lärt mig en del så det var ganska glidigt i början.
Min sambo läser en liknande YH och där var det folk (som snabbt hoppade av) som aldrig ens hört talas om språket de skulle lära sig och hade inte ens installerat Visual Studio eller dyl, då blir ganska tufft antar jag.
Många har "hört att det är gott om jobb inom IT och man kan jobba remote ifrån en strand..."
Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp)
Här följer en massiv uppdatering efter lite mer än 1 månad in i utbildningen!
Jag är klar med flera moment i JavaScript-introduktionskursen. I HTML & CSS-introduktionskursen har jag kvar de praktiska momenten (CSS-kod av HTML-hemsida, och en responsiv sida).
Projektuppgiften i JS-introduktionskursen är att anropa Sveriges Radio API och använda en JSON-sträng för att erbjuda en webbtjänst.
Projektuppgiften i HTML & CSS-introduktionskursen är att skapa en responsiv hemsida som ska vara så användarvänlig för alla olika surfenheter (mobiler, surfplattor, skärmläsare).
Här nedan följer mina inlämnade lösningar på de olika praktiska momenten inom JS-introduktionskursen.
Först ser du koden och sedan ser du ett bildexempel på slutresultatet!
Moment 3.2 i JS-Intro - En förenklad ToDo-app med localStorage
/* Lösning till Uppgift 3.2 (Moment 3.2 i DT084G) Av WebbkodsLärlingen, 2022 */
'use strict';
// Variabler som används regelbundet
let addTodoItemEl = document.getElementById('newtodo'); // För att läsa av input-värdet senare
let addTodoBtnEl = document.getElementById('newtodobutton'); // För att lägga till ny Att göra
let todoListEl = document.getElementById('todolist'); // Här hamnar alla inlästa & tillagda Att göra-articles
let errorMsgEl = document.getElementById('message'); // För att visa felmeddelande vid för kort sträng
let clearAllBtnEl = document.getElementById('clearbutton'); // För att kunna rensa hela Att göra-listan
let i; // Iteratorvariabel för regelbundna loopar
// Händelsehanterare som används regelbundet
addTodoItemEl.addEventListener('keyup', checkTextLength, false); // Kontrollera inmatningslängd
addTodoBtnEl.addEventListener('click' || '', addTodo, false); // Lägga till i Att göra-listan
clearAllBtnEl.addEventListener('click', clearTodos, false); // Rensa alla Att göra-articles från sidan
window.onload = init; // När sidan laddats fram, anropa funktionen init()
// Initering
function init() {
console.log('Initierar massa...');
// Töm inmatningsfält och inaktivera Lägg till-knapp (lämpligt när sidan startas om med F5)
addTodoItemEl.value = '';
addTodoBtnEl.disabled = true;
// Ladda sedan in nuvarande Att göra-articles som finns
loadTodos();
}
// Funktion: Kontrollera textlängd
function checkTextLength() {
console.log('Kontrollerar textlängden för inmatningsfältet...');
// Lagra värdet från inmatningsfältet
let input = addTodoItemEl.value;
// Kontrollera om längden är minst fem tecken lång
if (input.length > 4) {
errorMsgEl.innerHTML = ''; // Visa INGET felmeddelande
addTodoBtnEl.disabled = false; // Aktivera Lägg till-knapp
} else {
// Om färre än 5 tecken så visa felmeddelande
errorMsgEl.innerHTML = 'Ange minst fem tecken först!';
addTodoBtnEl.disabled = true; // Inaktivera Lägg till-knapp
}
}
// Funtkion: Lägga till i Att göra-listan
function addTodo() {
console.log('Lägger till i Att göra-listan...');
// Lagra värdet från inmatningsfältet
let input = addTodoItemEl.value;
// Skapa ett article-element och sen text till den (textnod)
let newArticleEl = document.createElement('article');
let newArticleTextNode = document.createTextNode(input); // textnoden är inmatningsfältets lagrade värde
newArticleEl.appendChild(newArticleTextNode); // Slå samman HTML-element och dess innehåll
// Lägg till det skapta article-elementet och dess textnod under <section>-elementet
todoListEl.appendChild(newArticleEl);
// Händelsehanterare till skapad <article>som tar bort ur DOM och
// sparar det som finns kvar i DOM. På så vis kan valfritt element
// tas bort med ett enkelt knapptryck medan resten sparas!
newArticleEl.addEventListener('click', function (e) {
e.target.remove();
console.log('Tar bort ett element!');
saveTodos();
});
// Töm inmatningsfält och inaktivera Lägg till-knapp
addTodoItemEl.value = '';
addTodoBtnEl.disabled = true;
// Anropar lagringsfunktionen som använder localStorage() för att spara lokalt
saveTodos();
}
// Funktion: Spara nuvarande <article>-Att göra till localStorage()
function saveTodos() {
console.log('Sparar nuvarande Att göra-articles som finns...');
// Läs in nuvarande Att göra-articles
let todos = document.getElementsByTagName('article');
// Skapa temporär arrayvariabel
let tempArr = [];
// Loopar igenom listan och lagrar till den temporära arrayvariabeln
for (i = 0; i < todos.length; i++) {
tempArr.push(todos[i].innerHTML);
}
// Omvandla den genomloopade arrayen till en JSON-sträng
// Lagra sedan i lokalt Web Storage
let jsonStr = JSON.stringify(tempArr);
localStorage.setItem('todos', jsonStr);
}
// Funktion: Läser in nuvarande Att göra-articles
function loadTodos() {
console.log('Försöker läsa in lagrade Att göra-articles...');
// Hämtar localStorage-textsträng och omvandlar till JSON
let todos = JSON.parse(localStorage.getItem('todos'));
// Loopar igenom den inlästa arrayen todos och skapar article-element
// och dess textnode[i] så länge localStorage INTE är tom (null)
if (todos != null) {
console.log('localStorage innehåller något. Läser in: [' + todos + ']');
for (i = 0; i < todos.length; i++) {
let newArticleEl = document.createElement('article');
let newArticleTextNode = document.createTextNode(todos[i]);
newArticleEl.appendChild(newArticleTextNode);
todoListEl.appendChild(newArticleEl);
// Händelsehanterare som tar bort ur DOM och sparar det
// som finns kvar i DOM. På så vis kan valfritt element
// tas bort med ett enkelt knapptryck medan resten sparas!
newArticleEl.addEventListener('click', function (e) {
e.target.remove();
console.log('Tar bort ett element!');
saveTodos();
});
}
} else {
// Annars om localStorage är tomt vid inläsningen av den
console.log('localStorage är tomt. Finns inget att läsa in!');
}
}
// Funktion: Rensa localStorage OCH i DOM
function clearTodos() {
console.log('Rensar alla Att göra-articles och laddar om...');
localStorage.clear(); // Rensar localStorage
document.getElementById('todolist').innerHTML = '';
init(); // Anropa init (inaktivera knapp+töm inmatningsfält)
}
<Uppladdad bildlänk>
Moment 4.1 - Objekt & JSON - Skapa och skriva ut objekt i webbläsaren
/* Lösning till Uppgift 4.1 Av WebbkodsLärlingen, 2022 */
'use strict';
// JS-FilmObjekt1 med egenskaperna title, category, playtime och metoden getInformation
let movie1 = {
title: 'Jurassic Park',
category: 'Science Fiction',
playtime: 127,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime}, minuter` + '\n';
},
};
// JS-FilmObjekt2 med egenskaperna title, category, playtime och metoden getInformation
let movie2 = {
title: 'Jurassic Park II',
category: 'Science Fiction',
playtime: 129,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
},
};
// JS-FilmObjekt3 med egenskaperna title, category, playtime och metoden getInformation
let movie3 = {
title: 'Jurassic Park III',
category: 'Science Fiction',
playtime: 92,
getInformation: function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
},
};
// JS-FilmObjekt4 med egenskaperna title, category, playtime och metoden getInformation
let movie4 = new Object();
movie4.title = 'Jurassic World: Dominion Extended Edition';
movie4.category = 'Science Fiction';
movie4.playtime = 146;
movie4.getInformation = function () {
return `${this.title}, ${this.category}, ${this.playtime} minuter` + '\n';
};
// JS-objekt med referenser till vardera objekts metod
let movies = {
a: movie1.getInformation(),
b: movie2.getInformation(),
c: movie3.getInformation(),
d: movie4.getInformation(),
};
// Töm inmatningsfältet först
document.getElementById('output').value = '';
// Mata ut varje JS-filmobjekt i inmatningsfältet med hjälp av value-metoden
document.getElementById('output').value += movies.a;
document.getElementById('output').value += movies.b;
document.getElementById('output').value += movies.c;
document.getElementById('output').value += movies.d;
<Uppladdad bildlänk>
Moment 4.2 - Objekt & JSON - Skapa en validerad JSON-fil
{
"student": {
"information": {
"name": "WebbkodsLärlingen",
"email": "WebbkodsLärlingen@student.miun.se",
"city": "Sundsvall",
"website": "http://studenter.miun.se/~WebbkodsLärlingen/"
},
"websites": [{
"sitename": "Mittuniversitetet",
"siteurl": "https://www.miun.se/",
"description": "Detta är hemsidan där jag studerade Projektledning med inriktning i Folkhälsovetenskap och där jag för närvarande studerar - på distans - Webbutvecklingsprogrammet."
},
{
"sitename": "Bio Drakstaden",
"siteurl": "https://www.biodrakstaden.se/",
"description": "När du vill boka in för kommande filmer i staden Sundsvall. Tidigare var det Filmstaden som bedrev det."
},
{
"sitename": "Systembolaget",
"siteurl": "https://www.systembolaget.se/",
"description": "Här går det att köpa alkohol på nätet. Kanske det bästa eller sämsta som någonsin har gjorts?"
},
{
"sitename": "Data Structures: Objects and Arrays :: Eloquent JavaScript",
"siteurl": "https://eloquentjavascript.net/04_data.html",
"description": "Kapitlet om objekt och arrayer vilket inkluderar JSON vilket denna fil är. Upplev meta av det hela!"
},
{
"sitename": "stackoverflow - What is JSONP, and why was it created?",
"siteurl": "https://stackoverflow.com/questions/2067472/what-is-jsonp-and...",
"description": "En direktlänk till en fråga om vad JSONP är för något och varför det skapades. Observera att det INTE är samma sak som JSON, tydligen."
}]
}
}
<Uppladdad bildlänk>
Moment 5.1 AJAX & Webbtjänster - Anrop med XMLHttpRequest
/* Lösning till Uppgift 5.1 Av WebbkodsLärlingen, 2022 */
'use strict';
// Skapa nytt AJAX-objekt
let xhttp = new XMLHttpRequest();
// Objektet väntar på Utförd Förfrågan (Request Finished) med färdigt svar (Response),
// dvs., 4 OCH samtidigt som dess statusmeddelande från servern ska vara OK (200)
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
// Omvandla JSON-filens mottagna text (alltså från this.responseText) till hanterbart JS-objekt
let jsonStr = JSON.parse(this.responseText);
// 'Positionera' sig vid info-Div inuti HTML-filen för DOM-manipulering
let infoDiv = document.getElementById('info');
// Skriv ut studentnamn, studente-post & studentwebbplats från student.json med lämpliga radbrytningar
infoDiv.innerHTML += `<strong style="font-weight: bold;">Namn:</strong> ${jsonStr.student.information.name} <br>
<strong style="font-weight: bold;">E-post:</strong> <a href="mailto:${jsonStr.student.information.email}">${jsonStr.student.information.email}</a><br>
<strong style="font-weight: bold;">Webbplats:</strong> <a href="${jsonStr.student.information.website}" target="_blank">${jsonStr.student.information.website}</a><br>`;
// 'Positionera' sig vid sites-ul-listan inuti HTML-filen för DOM-manipulering
let sitesUl = document.getElementById('sites');
// Skriv ut följande med hjälp av loop: webbplatsens fullständiga adress (href), beskrivning (title) och webbsidans namn <ahref="">här</a>
for (let i = 0; i < jsonStr.student.websites.length; i++) {
sitesUl.innerHTML += `<li><a href="${jsonStr.student.websites[i].siteurl}" target="_blank" title="${jsonStr.student.websites[i].description}">${jsonStr.student.websites[i].sitename}</a></li>`;
}
}
};
xhttp.open('GET', 'student.json', true);
xhttp.send();
Moment 5.2 AJAX & Webbtjänster - Anrop med Fetch
/* Lösning till Uppgift 5.2 Av WebbkodsLärlingen, 2022 */
'use strict';
// Hämta data från lokal student.json-fil
fetch('student.json')
// Om det lyckas så omvandla all response-data till JSON-data med hjälp av .json()-metoden
.then((response) => response.json())
// Om även det lyckas så använd sedan denna JSON-data (lagrad i jsonStr) för att köra följande pilfunktion:
.then((jsonStr) => {
// Exakt samma DOM-manipulering som från XMLHttpRequest-momentet kan tillämpas härifrån!
// 'Positionera' sig vid info-Div inuti HTML-filen för DOM-manipulering |
let infoDiv = document.getElementById('info');
// Skriv ut studentnamn, studente-post & studentwebbplats från student.json med lämpliga radbrytningar
infoDiv.innerHTML += `<strong style="font-weight: bold;">Namn:</strong> ${jsonStr.student.information.name} <br>
<strong style="font-weight: bold;">E-post:</strong> <a href="mailto:${jsonStr.student.information.email}">${jsonStr.student.information.email}</a><br>
<strong style="font-weight: bold;">Webbplats:</strong> <a href="${jsonStr.student.information.website}" target="_blank">${jsonStr.student.information.website}</a><br>`;
// 'Positionera' sig vid sites-ul-listan <ul>-elementet inuti HTML-filen för DOM-manipulering
let sitesUl = document.getElementById('sites');
// Skriv ut följande med hjälp av loop: webbplatsens fullständiga adress (href), beskrivning (title) och webbsidans namn <ahref="">här</a>
for (let i = 0; i < jsonStr.student.websites.length; i++) {
sitesUl.innerHTML += `<li><a href="${jsonStr.student.websites[i].siteurl}" target="_blank" title="${jsonStr.student.websites[i].description}">${jsonStr.student.websites[i].sitename}</a></li>`;
}
});
Det är exakt samma resultat för Moment 5.1 som i Moment 5.2:
<Uppladdad bildlänk>
Den som vill och orkar får gärna ge återkoppling på hur jag kan förbättra viss kod (refaktorisering)!
Till sist så vill jag berätta att för denna distansutbildning så verkar det vara upp till att nästan hälften hoppar av programmet innan sista kursen! I Discordgruppen jag är med i så berättar en hel del om hur icke "nybörjarvänligt" introduktionskurserna är för de som kommer med noll förkunskaper om kodning/programmering.
Jag har nästan funderat att på egen hand börja skapa simpla YouTube-klipp som förklarar koncept inom HTML, CSS & JS på ren och simpel svenska i takt med att jag själv lär och bemästrar samma koncept!
Fråga: Vad har du för tips för de som kommer med nästan noll förkunskaper inom kodning och programmering för att de skall komma i kapp de som redan är mer tekniskt lagda/intresserade?
På återseende!
Mvh,
WKL.
Väldigt många är inte vana med självstudier och ansvar, det är en helt annan sak att sitta motiverad själv och lära sig än att lyssna på föreläsningar. Många klarar inte av omställningen att behöva lära sig själva och leta information. Paradoxalt är det just dessa egenskaper som är viktiga för att kunna jobba med programmering
- Hur flytta backup på ett säkert sätt?20
- Quiz: Gissa spelet – Del 816
- Geforce RTX 5080 Super på gång45
- RTX 5080/5090 lagerstatus1,4k
- Vilka nya tekniker tvärvägrar du?291
- Det här är RX 9060 XT: Specifikationer bekräftade54
- Computex 2025 – Calle på soloäventyr67
- Installera win11 24h2 på ARMdator1
- Välkommen till SweClockers på Discord1
- Telias epost slutat fungera i natt...29
- Säljes QN95B, 4070ti super, 2tb sdd, AIO kylare
- Säljes DDR5 SODIMM 5600 2X8 GB (Totalt 16gb)
- Säljes Asus ROG Strix XG259QN 380Hz Gamingskärm
- Köpes Rtx-kort köpes
- Köpes Söker bärbar dator till Lillebror.
- Säljes Samsung M393A4K40BB1-CRC0Q 32GB PC4-19200 DDR4-2400MT/s 2RX4 ECC
- Köpes Söker RAM-minne DDR4 16/32GB
- Säljes AsRock B650m Pro RS Wifi
- Säljes MSI 5070 Ti Vanguard Launch Edition SOC + DOOM: The Dark Ages Premium Edition
- Säljes Rensning innan flytt med lite smått o gott
- Quiz: Gissa spelet – Del 816
- Computex: Tryx tycker om kylare med skärmar2
- AMD lanserar Threadripper 9000-serien12
- Cherry avtäcker ny typ av mekanisk brytare18
- Logitech släpper gamingheadsetet G52215
- Nvidia åtgärdar strypta RTX 50-laptops7
- Veckans fråga: Hur ofta stänger du av datorn?139
- Nu ska Windows bli kvantsäkert24
- Geforce RTX 5080 Super på gång45
- Det här är RX 9060 XT: Specifikationer bekräftade54
Externa nyheter
Spelnyheter från FZ