Webpage manipulation with JavaScript

Jeff P
6 min readOct 21, 2023

--

we can call values of elements by referencing them as strings (inside ‘ ’) as if they are referenced by their classname or id, you must include either . or # respectively.

// selecting elements (e.g. <body>
document.querySelector('body').style.backgroundColor = '#000000';

// checking the value of the message class (. ) and assigning to variable
const messageValue = document.queryselector('.message').value;

// selecting elements by their id (use #)
const element = document.querySelector('#myElement');

we can update the value displayed on screen with textContent

// update the text for the message class
document.queryselector('.message').textContent = "Hello!";

we can update css styles with the .style option

// change the background colour of the body
document.querySelector('body').style.backgroundColor = '#cccccc';

multiple instances of classes

remember that elements can have multiple classnames, so it’s import to know which one you are referencing:

<body>
<header>
<h1>Guess My Number!</h1>
<p class="between">(Between 1 and 20)</p>
<button class="btn again">Again!</button> // 'btn' AND 'again' classnames
<div class="number">?</div>
</header>
<main>
<section class="left">
<input type="number" class="guess" />
<button class="btn check">Check!</button> // 'btn' AND 'check' classnames
</section>

If you referenced “.btn” then you are referencing BOTH buttons above, however using querySelector in this instance will only reference the FIRST instance of this class it finds. In this case if you wanted to select ALL instances, you would use querySelectorAll

This would produce a Node List of elements (which is a bit like an array of the buttons), and you could use a for loop or a for each loop to reference a particular button:

const buttons = document.querySelectorAll('.btn');
buttons.forEach(function(button) {
// Do something with each button
});

If you only wanted to reference one, then you could just use “.again” or “.check” if they were truly unique classes on the page, or you could reference them explicitly as “.btn.again” and “.btn.check”

hiding elements

You can hide and reveal modal windows by using .classList.remove() to remove a className from an element.

So for example, if you created a classname called .hidden and that classname referenced some css styling where display: none

// in the style.css file

.hidden {
display: none
}
// in the script.js file

const modal = document.querySelector(".modal");

modal.classList.remove('hidden');

// note how you do NOT specify .hidden when using classList
// you simply specify the name of the class, as we're not "selecting" a class
// like we do when we use querySelector and querySelectorAll.

The opposite, would then show the modal:

modal.classList.add('hidden');

Alternatively, you can use classList.toggle, which removes the element if present, and adds it if it isn’t present:

const div = document.getElementById('myDiv');
div.addEventListener('click', function() {
div.classList.toggle('hidden');
});

.textContent vs .value

.textContent deals with the text content of elements that display text, while .value is specifically for form input elements and is used to access or set the user-entered data in those input fields.

const paragraph = document.querySelector('p');
console.log(paragraph.textContent); // Get the text content
paragraph.textContent = 'New text'; // Set the text content


const inputElement = document.querySelector('input[type="text"]');
console.log(inputElement.value); // Get the input value
inputElement.value = 'New value'; // Set the input value

If you specifically want to target an <input> element with a certain type attribute (e.g., 'text', 'password', 'number', etc.), then you should include the type in the query selector, as above.

updating content

Remember that updating a variable is NOT the same as updating the content displayed on the screen. You can update a variable but you also need to specify that this updated variable should be reflected on the screen:

  if (guessValue === secretNumber) {
document.querySelector('.number').textContent = '?';
document.querySelector('body').style.backgroundColor = '#000000';
if (Number(score) > Number(highScore)) {

highScore = score; // just updating the hightScore variable
document.querySelector('.highscore').textContent = highScore; // Update the high score in the UI
}
score = 10;
document.querySelector('.guess').value = '';
document.querySelector('.message').textContent = 'Make a guess';
}
});

You can easily use ternary operators to determine what should be displayed:

// no guess  
if (!guess) {
document.querySelector('.message').textContent = 'No Number';
// guess is correct
} else if (guess === secretNumber) {
document.querySelector('.message').textContent = 'Correct Number!!!';
document.querySelector('.number').textContent = secretNumber;
document.querySelector('body').style.backgroundColor = '#cccccc';
// guess is incorrect
} else if (guess !== secretNumber) {
document.querySelector('.message').textContent =
guess > secretNumber ? "too high" : "too low"; // ternary operator:
score--;
document.querySelector('.score').textContent = score;
}

DRY principle

You should look to refactor your code using the DRY principle (Don’t Repeat Yourself)

For example, you might use this line of code repeatedly in the page:

document.querySelector('.message').textContent =

you could replace this with a function at the top of the page:

const displayMessage = function (message) => {
document.querySelector('.message').textContent = message;
}

then you just use it as follows wherever a message needs to be displayed, to save typing out document.querySelector(message).textContent every time:

displayMessage("Try again!");

displayMessage("Your guess was too high");

displayMessage("Your Guess was too low");

displayMessage("Make a guess!");

Reacting to keyboard events

For keyboard events we still listen for events by using document.addEventListener but instead of using “click” as the first argument, we instead use “keydown”.

Note that we don’t use the option of “keypress”, as this responds only when a key has been pressed down and is then fully released.

document.addEventListener('keydown', () => console.log("a key was pressed"));

We can also take advantage of the event that was triggered by the event (in this case pressing a key down on the keyboard) by passing in the event to the function.

For example:

document.addEventListener('keydown', (e) => console.log(e));

so if I typed in hi there, you would see the following in the console

KeyboardEvent {isTrusted: true, key: 'h', code: 'KeyH', location: 0, ctrlKey: false, …}
VM1521:1 a key was pressed
VM1637:1 KeyboardEvent {isTrusted: true, key: 'i', code: 'KeyI', location: 0, ctrlKey: false, …}
VM1521:1 a key was pressed
VM1637:1 KeyboardEvent {isTrusted: true, key: ' ', code: 'Space', location: 0, ctrlKey: false, …}
VM1521:1 a key was pressed
VM1637:1 KeyboardEvent {isTrusted: true, key: 't', code: 'KeyT', location: 0, ctrlKey: false, …}
VM1521:1 a key was pressed
VM1637:1 KeyboardEvent {isTrusted: true, key: 'h', code: 'KeyH', location: 0, ctrlKey: false, …}
VM1521:1 a key was pressed
VM1637:1 KeyboardEvent {isTrusted: true, key: 'e', code: 'KeyE', location: 0, ctrlKey: false, …}
VM1521:1 a key was pressed
VM1637:1 KeyboardEvent {isTrusted: true, key: 'r', code: 'KeyR', location: 0, ctrlKey: false, …}
VM1521:1 a key was pressed
VM1637:1 KeyboardEvent {isTrusted: true, key: 'e', code: 'KeyE', location: 0, ctrlKey: false, …}

It shows the event for each key that was pressed, including the spacebar.

You can expand each event for lots of information. For example, the event for pressing the spacebar:

We can use this event information for different things.

For example, we can print to the console, the key that way pressed:

document.addEventListener('keydown', (e) => console.log(e.key + " was pressed"));

which would show the following in the console if I pressed the letter j:

j was pressed

So for example, you could use this to close a modal if the Escape key was pressed:

if (e.key === 'Escape') {
closeModal();
}

Using flow-charts to prepare for a project:

It’s often easier to approach a project if you have a flow chart illustrating the various sub-requirements, so that you can isolate them and work on them one-by-one

.innerHTML

The .innerHTML property of the Document Object Model (DOM) provides a way to get or set the HTML content inside an element.

const div = document.getElementById('myDiv');
console.log(div.innerHTML); // Logs the HTML content inside the 'myDiv' element

When used as a setter, it replaces the current content of the specified element with the provided HTML string.

const div = document.getElementById('myDiv');
div.innerHTML = '<strong>Hello, World!</strong>';
// Sets the content of 'myDiv' to bold "Hello, World!"

insertAdjacentHTML():

This method inserts the given HTML string at a specified position relative to the element it’s called on. It does not replace the content but adds to it based on where you specify.

It takes two parameters:

  1. A position string: This can be one of the following:
  • 'beforebegin': Before the element itself.
  • 'afterbegin': Just inside the element, before its first child.
  • 'beforeend': Just inside the element, after its last child.
  • 'afterend': After the element itself.

2. The HTML string to be inserted.

const div = document.getElementById('myDiv');
div.insertAdjacentHTML('beforeend', '<span>Additional content</span>');
// Inserts the span just before the closing tag of 'myDiv'
// without removing existing content.

--

--

Jeff P
Jeff P

Written by Jeff P

I tend to write about anything I find interesting. There’s not much more to it than that really :-)

No responses yet