:HEADER-ARGS:html: :tangle w04/index.html :HEADER-ARGS:css: :tangle w04/css/style.css :HEADER-ARGS:js: :tangle w04/js/main.js
Prepare the environment
mkdir -p w04/{css,js,media} mkdir -p w04/media/{img,video,fonts} touch w04/index.html touch w04/css/style.css touch w04/js/main.js
Prepare the index html file
Include the Javascript
Consider the distinctions between placing the script tag at the end of the body or at the begin (or within the head tag). When you intend to select specific elements in the DOM, it’s crucial to be sure that the DOM nodes are fully rendered. To archive this, you have two options:
- Set the script tag at the end of the body
- Wrap the code into a function and call it when the web-site is fully loaded
First option
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Document</title> </head> <body> <p>La madre de Beth tiene tres hijas. La mayor se llama Clara, la pequeña Sara. ¿Cómo se llama la mediana?</p> <button>Show answer</button> <script src="js/example1.js"></script> </body> </html>
And the js:
let paragraph = document.querySelector("p"), button = document.querySelector("button"), texts = ["Beth"]; button.addEventListener("click", function(e) { if (typeof(button.dataset.isShow) === "undefined") { texts.push(paragraph.innerText); // insert the text of the paragraph as a new entry in the array button.dataset.isShow = 0; } paragraph.innerText = texts[button.dataset.isShow++]; button.dataset.isShow %= 2; });
Second Option
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Document</title> </head> <body> <p>La madre de Beth tiene tres hijas. La mayor se llama Clara, la pequeña Sara. ¿Cómo se llama la mediana?</p> <button>Show answer</button> <script src="js/example2.js"></script> </body> </html>
The js/example2.js file
//The function passes as argument, receives another arguments with the Event object document.addEventListener("DOMContentLoaded", function(event) { let paragraph = document.querySelector("p"), button = document.querySelector("button"), texts = ["Beth"]; button.addEventListener("click", function(event) { if (typeof(button.dataset.isShow) === "undefined") { texts.push(paragraph.innerText); // insert the text of the paragraph as a new entry in the array button.dataset.isShow = 0; } paragraph.innerText = texts[button.dataset.isShow++]; button.dataset.isShow %= 2; }); });
For more information about the DOMContentLoaded event, go to MDN documentation
Prepare the HTML
For the moment, we continue with the basic example
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="css/style.css" rel="stylesheet"> </head> <body> <p>This is the default text</p> <script src="js/main.js"></script> </body> </html>
Play with js
Why is important the use of semicolon ;
You can run the following code, and compare the results before and after removing the semicolon from line 7;
function sayHello (name) { console.log("Hola " + name ); return name; } sayHello("Pepe"); const greeter = sayHello; (function pow(base, exp) { console.log(base**exp); return pow; })(2, 6) greeter(6, 6);
Select elements from the DOM
As we have viewed in DOM Manipulation, there are many ways to select elements and manipulate them. In this example we will change a image src when user click the button
Manipulate attributes
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="css/style.css" rel="stylesheet"> </head> <body> <img src="https://www.divinacocina.es/wp-content/uploads/2022/03/filetes-empanados-1.jpg.webp" > <button id="changeMe">Cambia</button> <hr> <p>La madre de Beth tiene tres hijas. La mayor se llama Clara, la pequeña Sara. ¿Cómo se llama la mediana?</p> <button id="answer">Show answer</button> <script src="js/main.js"></script> </body> </html>
And the javascript code
// define some vars let img = document.querySelector("img"); let routes = ["https://recetasdecocina.elmundo.es/wp-content/uploads/2023/09/patatas-fritas-perfectas.jpg", "https://www.divinacocina.es/wp-content/uploads/2022/03/filetes-empanados-1.jpg.webp"]; let pos = 1; //define a simple function to change the src function changes() { pos = ++pos%2; img.setAttribute("src", routes[pos]); console.log("The current value is " + img.getAttribute("src")); } // Select the button by the ID and add the event onclick let changeMe = document.getElementById("changeMe"); changeMe.addEventListener("click", changes);
If we want to ask for the current value, we can use the method getAttribute
Manipulate text
In the first example, we can see the process following to change the text inside a paragraph. But this process could be used with any other tag
At the beginning of the course, we talked about the attributes of the tags, and I
emphasized the fact that we can create and use our own attributes, But we
have to prepend it with the data-
strings
Now we can see why. All the attributes that begin with data-
are accessible by
the dataset
attribute of any node.
In this example, I will use the data-is-show
attribute from the button. You
can see who the button is changing the value from the developer tool of the browser.
let paragraph = document.querySelector("p"); let answer = document.getElementById("answer"); let texts = ["Beth"]; answer.addEventListener("click", function(e) { if (typeof(answer.dataset.isShow) === "undefined") { texts.push(paragraph.innerText); // insert the text of the paragraph as a new entry in the array answer.dataset.isShow = 0; } paragraph.innerText = texts[answer.dataset.isShow++]; answer.dataset.isShow %= 2; });
Insert new node
If we want to insert a new node or remove another, there are a few steps we have to follow. First the node must be created, then we modify it as needed, and finally we insert it into the node which will be its parents. The process could be repeated as many times as we needed.
Look the difference between appendChild
and insertBefore
function appendWeirdText() { let numberOfSections = 3, numberOfArticles = 4, numberOfParagraphs = 12; for (let i = 0; i < numberOfSections; ++i) { const section = document.createElement("section"); const title = document.createElement("h2"); title.innerText = "Soy la sección " + i; section.appendChild(title); for (let j = 0; j < numberOfArticles; ++j) { const article = document.createElement("article"); const subtitle = document.createElement("h3"); subtitle.innerText = "Soy el artículo " + j + " en la sección " + i; article.appendChild(subtitle); for (let k = 0; k < numberOfParagraphs; ++k) { const paragraph = document.createElement("p"); paragraph.innerText = "Soy el parrafo " + k + " en el artículo " + j + " y la sección " + i; article.appendChild(paragraph); } // When the article wont be updated more, add it to the section section.appendChild(article); } document.body.insertBefore(section, document.getElementsByTagName("script")[0]); } } const newButton = document.createElement("button"); newButton.innerText = "Insert random text"; newButton.addEventListener("click", appendWeirdText); document.body.insertBefore(newButton, document.getElementsByTagName("script")[0]);