JavaScript for beginners
JavaScript gives a page behaviour: reacting to what the visitor does, changing content without a reload, and fetching data from a server. The skeleton of a page is HTML and its look is CSS; JavaScript is only needed where the page has to do something.
- Lesson 4 of 12
- Beginner
- Free, no signup
The three languages that turn a page together
Each has one job, and none of them does the job of the others.
-
HTML, structure
Says what each piece is: heading, paragraph, button, form. The browser, the screen reader and the crawler all read this.
-
CSS, appearance
Colour, spacing, size and layout. It also draws the states: hover, focus, open and closed.
-
JavaScript, behaviour
What happens after the page has opened: reacting to the user, changing content, talking to a server.
They do not carry equal weight. A page without JavaScript still works and a page without CSS is still readable, but a page without HTML does not exist at all.
Last checked: Facts and tool names in this lesson are re-checked against their sources on this date.
What is JavaScript actually for?
For whatever happens after the page has opened. JavaScript is the only language every browser runs natively, and its job is to bring to life the page HTML built and CSS coloured.
The figure at the top of this page is three gears, and it shows that division of labour. HTML says this is a heading and that is a button, CSS says what colour the button is, and JavaScript says what should happen when somebody presses it.
There are four jobs only JavaScript can do: reacting to what the visitor does after the page has loaded, changing something that is on the screen right now, talking to a server without reloading the page, and keeping something in the browser itself until next time. Anything else you think needs JavaScript is worth checking twice; section six of this lesson comes back to that with a concrete list.
There is also a job that is not its own and that beginners often confuse: JavaScript running in the browser is not a server side program. Storing an order, sending an email and checking a password all happen on the server. The browser code only makes the request.
Where do you write the code, and how do you attach it?
In a separate file with a .js extension, attached to the page with one line in the head:
<script src="app.js" defer></script>That word defer is the most important thing in this section. It means download the file while the HTML is being read, but leave running it until the whole page has been built. Without it, a script sitting in the head runs before the elements exist and every attempt to find a button returns null. That is the most common beginner "why does it not work", and the answer is one word.
Your second tool is the browser console. Open it with F12 and keep it open: every JavaScript error is printed there with its line number, and console.log shows you anything you ask for. Until you have opened the console, you are coding in the dark.
const title = document.querySelector("h1");
console.log(title.textContent);And variables: write const unless you know the value has to change, and then let. The word var is left over from an earlier era of JavaScript and there is no reason to write it in new code.
What is the DOM, and why does everything start there?
When the browser reads your HTML it builds a tree of objects from it in memory. That tree is called the DOM, and JavaScript works on it rather than on your file. That is why changing something in code updates the page instantly while the file on disk stays untouched; one refresh puts everything back.
Finding an element takes one function, and one is enough. document.querySelector takes the same selectors as CSS:
const btn = document.querySelector(".btn");
const rows = document.querySelectorAll(".row");Once you have found it, you have three everyday jobs. You change text with textContent, you add and remove classes with classList, and you set attributes with setAttribute.
btn.textContent = "Saved";
btn.classList.add("is-done");Among these there is a decision worth learning correctly from day one. textContent treats whatever you give it as plain text, while innerHTML treats it as markup and acts on it. If the text you are inserting came from a user, you have handed that user the ability to write tags into your page. The rule is simple: unless you are genuinely building HTML, use textContent.
And one habit that keeps the work clean: instead of changing colours and sizes from JavaScript, add a class and let CSS draw the look. JavaScript changes the state, CSS shows that state.
Events: when the visitor does something
Everything the visitor does creates an event: a click, typing, submitting a form, scrolling. You tell the browser which event on which element you want, and which function should run:
btn.addEventListener("click", function () {
console.log("someone pressed it");
});Here is a complete example that genuinely works and is not possible in HTML and CSS: a character counter under a text field.
<label for="msg">Your message</label>
<textarea id="msg" maxlength="200"></textarea>
<p id="left">200</p>const box = document.querySelector("#msg");
const left = document.querySelector("#left");
box.addEventListener("input", function () {
left.textContent = 200 - box.value.length;
});Five lines, and several points fitted into five lines. We chose the input event rather than keyup, because keyup only listens to the keyboard and misses text pasted with a mouse or from a phone. value is the current content of the field and length is its length. And maxlength on the tag itself does the limiting; JavaScript is only showing the number.
Forms need one more event. If you want to handle the submission yourself, you have to stop the browser default behaviour:
form.addEventListener("submit", function (event) {
event.preventDefault();
});The next figure walks through that cycle step by step. What matters in it is the last step: you change the DOM, and redrawing the page is the browser job, not yours.
From the visitor click to the change on screen
You only write the third step. The rest is the browser job.
-
1
The visitor does something
A click, typing, a form submission or even a scroll.
-
2
The browser creates the event
An object with all the detail: where, on which element, with which key.
-
3
Your function runs
The function you registered with addEventListener.
-
4
The DOM changes
A text, a class or an attribute. The file on disk is untouched.
-
5
The browser repaints
You do not write this step, and you do not need to.
If you remove an element and build it again, its listener went with it. That is the most common reason a button stops working after an update.
fetch: getting data without reloading the page
Up to here everything happened inside the page itself. fetch is where the page talks to the outside: you call an address, the server answers, and you put the answer on the page. All without a reload.
async function loadPrice() {
const res = await fetch("/api/price.json");
const data = await res.json();
document.querySelector("#price").textContent = data.toman;
}The word await means wait for the answer and only then run the next line, and it only has meaning inside a function marked async. This is the first place JavaScript genuinely gets harder, because the work is no longer one line after another. If you got this far on day one, that is enough; the rest can wait.
Know three things now so you do not waste time. First, the address you call has to exist and answer; in the console, the Network tab shows whether the request went out and what code came back. Second, if the address belongs to another domain the browser blocks you from reading the answer unless that server allowed it. And third, the most important: this code runs in the visitor browser and they can read all of it. No key and no password belongs in this file.
How much JavaScript do you actually need?
Less than you think, and that is our position rather than a preference. A large part of what beginners do with JavaScript is something HTML and CSS now do themselves, better and with less code:
- opening and closing a section with
detailsandsummary, without a line of code - basic form validation with
requiredandtype="email"on the field itself - lazy loading images with
loading="lazy" - a modal window with the
dialogelement - reacting to element state with
hover,focus-visibleandhasin CSS - a horizontal slider with
scroll-snap, which also behaves correctly under a finger
Why this matters: every JavaScript file has to be downloaded, parsed and executed, and the execution happens on the same thread that answers the user touch. While code is running, the page does not respond to anybody finger. A heavy image lowers quality; heavy JavaScript slows the page down. If you want to see what that does to real site speed, the site speed page and the lessons of the speed path show it with measurements.
Now the boundary of that claim, which every recommendation has. If what you are building is a product rather than a content site, a dashboard or an editor or a live chat, then you genuinely need plenty of JavaScript and there is nothing wrong with that. We are talking about company sites, simple shops and blogs: there, every kilobyte you do not write is a win.
One example from this very page: the figures you see in this lesson are drawn with zero lines of JavaScript. HTML and CSS, that is all.
One question before the first line
A large part of what gets done with JavaScript now has an answer inside HTML and CSS themselves.
Does the thing you want actually need JavaScript?
Do not write it
- Sections opening and closing with details and summary
- Basic form validation with the field own attributes
- Lazy loading images with one attribute
- A horizontal slider with scroll-snap in CSS
Write JavaScript
- A counter, a live filter, anything that changes as the user types
- Getting data from a server without reloading the page
- Keeping something in the browser until the next visit
- Anything that has to calculate on the user input
This rule is for content sites. For an interactive product such as a dashboard or an editor the answer is nearly always yes, and that is fine.
The fast path, with AI
Language models are unusually good for learning JavaScript, because what a beginner needs is not code but an answer to "why", five times in a row and without embarrassment. But the fast path is not "get code"; it is "get the smallest version that works, then make it question you". The difference between those two is the difference between having code and understanding it. A fast cheap model is enough here; our current pick is in <a class="text-link" href="/en/ai/">the AI section</a>.
- Write in one sentence what should happen. If your sentence has two "and"s in it, that is two jobs; split them and take one at a time.
- Run the recipe below and put your own real markup in it, not a description of it.
- Put the code in the file and keep the browser console open. If it does not work, the error line is written right there with its line number.
- Now the step that separates copying from learning: hand the same code back and ask it to remove one line and ask you what breaks. Until your answer is right, that code is not yours yet.
Copy-ready recipe
Role: a JavaScript teacher for somebody who has just started.
What should happen:
{write it in one sentence}
Current markup:
{paste the HTML here}
Rules:
- Give the smallest version that works, not the complete professional one.
- Modern JavaScript: const and let, addEventListener, fetch. No jQuery, no var, no onclick attribute inside the tag.
- No library and no framework. If it genuinely cannot be done without a library, say so first and write why.
- If the same job is possible with HTML or CSS alone, show that route first and say why it is better.
- After the code, explain every line in one sentence.
- For every feature you used, name its MDN page so I can look at the browser support table myself.
- Write no text, number or name that is not in my input; leave {...} in its place.
At the end: remove one line of the code and ask me what breaks without it. Do not write the correct answer until I have asked for it.
Before you trust the output: The model has no browser. Code that "should work" may fail on your page for a reason it cannot see: the element did not exist yet, the script ran too early, or the selector matched nothing. For that class of question, console first and chat second. And a more serious boundary: no code that touches payment, user login or personal data should ship without being read by somebody who understands the language. Your JavaScript runs on the visitor device; whatever you put in it, you have shipped.
AI in this kind of work
This is the topic where AI helps a beginner most, and our position is plain: use it as a teacher, not as a supplier. Three things it does genuinely well: writing the smallest working version of a job, explaining a block of code you do not understand line by line, and reading an error message and saying where it comes from. What we do not hand over: judging whether the code is safe.
Tools that actually help
- Claude Good for line by line explanation and for that same "remove one line and quiz me" game. Iran is not on Anthropic supported-countries list; we read that on Anthropic own page.
- Gemini Enough for basic questions and a first version of a function, and it handles Persian well. Google own page says the Gemini web app runs in over 230 countries and territories, and Iran is not on that list.
- Claude Code It works in your own editor and terminal and can see the files, so it suits a project that has grown to several files better than a chat window does. A beginner does not need it on day one. It installs free but needs an Anthropic subscription, and Iran is not on the supported-countries list.
Where it backfires
Two specific risks, and neither of them is "wrong code". First, old patterns: the model gives you what you asked for, and if you do not say you want modern JavaScript, nothing stops var and an onclick attribute inside the tag. Checking that is manual and takes ten seconds: look the feature up on MDN and read the browser support table. Second and more important: code you cannot read is a debt. The day it breaks, and it breaks on the day you need it, you have no way to repair it. And a boundary that has nothing to do with learning: whatever you paste into a chat window has left your machine, so keys, tokens and customer data have no place in it. For how each tool can be paid for from Iran, see the buying guide.
Sources: MDN: The script element MDN: Using the Fetch API Anthropic: supported countries Google: where Gemini Apps are available
Where this advice stops
JavaScript running in a browser cannot be trusted, and that is not a flaw but its definition: the visitor can read the code, change it and switch it off entirely. So anything that genuinely matters, from form validation to pricing and access, has to be checked again on the server; the browser check is for the user convenience, not for security. There is another limit: this lesson is the floor. Frameworks such as React and Vue are a separate subject, and a content site usually never reaches them. And if your goal is getting a site up quickly rather than learning, go to WordPress; there somebody else already wrote this code and your job is choosing.
From our own work
The real numbers we work with ourselves, on this very site, checkable in view source. The whole client side JavaScript of the rgb.ir theme is two files, about sixteen and five kilobytes, both deferred, and this page you are reading loads exactly those two plus the analytics file. The figures in this section carry zero bytes of JavaScript: the figure engine is eight PHP files and not one of them contains a script tag, it is all HTML and CSS. And now the honesty that completes the claim: for all that accounting, the front page of this same site also loads jQuery version 3.7.1. We did not write it and we did not call it; the site security plugin registers its own captcha script with jQuery as a dependency, and that one line pulls a whole library into the page. That is the real lesson: your JavaScript budget is not only your own code.
Real follow-up questions
Is JavaScript different from Java?
They are two entirely separate languages and the similarity of the names is historical. JavaScript is the language of the browser; Java is used mostly in enterprise software and on Android. If you are here to build websites, the one you need is JavaScript.
Should I learn jQuery first, or plain JavaScript?
Plain. The jobs jQuery was built for are done today by JavaScript itself with querySelector, addEventListener and fetch. You will still meet it in older WordPress projects, including on this very site, so learn to read it; you do not need to write it.
My code throws no error but does nothing. Where do I start?
First check that your selector actually found something: console.log that variable and make sure it is not null. Then check that the script did not run before the page was built, which defer solves. Those two answer most of the day one "it does not work".