Integrating JavaScript in HTML
JavaScript adds interactivity and dynamic behavior to HTML pages. It can be embedded directly in HTML or loaded from external files.
The <script> Tag
The <script> tag is used to embed or reference JavaScript code in HTML documents.
JavaScript can be placed in the <head>, at the end of <body>, or loaded from external files.
Placing scripts at the end of the body prevents them from blocking page rendering.
<!-- Inline JavaScript -->
<script>
console.log('Hello from JavaScript!');
document.getElementById('demo').innerHTML = 'Updated content';
</script>
<!-- External JavaScript file -->
<script src="script.js"></script>
<!-- Script at end of body (best practice) -->
<body>
<h1 id="heading">Page Content</h1>
<script src="main.js"></script>
</body>
Script Placement
Scripts in the <head> execute before the page content loads, which can slow down page rendering.
Scripts at the end of <body> execute after the HTML content is loaded, improving perceived performance.
The defer attribute loads the script asynchronously and executes it after HTML parsing completes.
The async attribute loads and executes scripts asynchronously, without blocking HTML parsing.
<!-- Traditional head placement (blocks rendering) -->
<head>
<script src="large-library.js"></script>
</head>
<!-- Deferred loading (best for most scripts) -->
<head>
<script src="main.js" defer></script>
</head>
<!-- Async loading (for independent scripts) -->
<head>
<script src="analytics.js" async></script>
</head>
<!-- End of body (classic approach) -->
<body>
<!-- content -->
<script src="app.js"></script>
</body>
Manipulating HTML with JavaScript
JavaScript can access and modify HTML elements using the Document Object Model (DOM).
Methods like getElementById(), querySelector(), and getElementsByClassName() select elements.
The innerHTML property changes element content, while textContent changes text only.
The style property modifies CSS properties, and setAttribute() changes attributes.
<p id="demo">Original text</p>
<button onclick="changeText()">Click Me</button>
<script>
function changeText() {
// Get element by ID
let element = document.getElementById('demo');
// Change content
element.innerHTML = 'Text changed!';
// Change style
element.style.color = 'blue';
element.style.fontSize = '20px';
// Change attribute
element.setAttribute('class', 'highlight');
}
</script>
Event Handling
Events are actions that happen in the browser, such as clicks, key presses, or page loads.
The onclick attribute can be added directly to HTML elements to execute JavaScript.
Event listeners provide a more flexible way to handle events using addEventListener().
Common events include: click, mouseover, mouseout, keydown, keyup, submit, load, and change.
<!-- Inline event handler -->
<button onclick="alert('Button clicked!')">Click Me</button>
<!-- Event listener in script -->
<button id="myButton">Click Me</button>
<script>
let btn = document.getElementById('myButton');
btn.addEventListener('click', function() {
alert('Button clicked via event listener!');
});
// Multiple event types
btn.addEventListener('mouseover', function() {
this.style.backgroundColor = 'yellow';
});
btn.addEventListener('mouseout', function() {
this.style.backgroundColor = '';
});
</script>
The <noscript> Tag
The <noscript> tag defines alternative content for users who have disabled JavaScript or use browsers that don't support it.
Content inside <noscript> is only displayed when JavaScript is not available.
This is important for accessibility and graceful degradation.
<script>
document.write('JavaScript is enabled!');
</script>
<noscript>
<p>Your browser doesn't support JavaScript or it's disabled.</p>
<p>Please enable JavaScript for the best experience.</p>
</noscript>
Best Practices
Keep JavaScript in external files for better organization, caching, and maintainability.
Use defer or async attributes to prevent scripts from blocking page rendering.
Always validate and sanitize user input to prevent security vulnerabilities like XSS attacks.
Use meaningful variable and function names for code readability.
Handle errors gracefully with try-catch blocks to prevent scripts from breaking.
Minimize DOM manipulation for better performance - batch changes when possible.
<!-- Good practice: External file with defer -->
<head>
<script src="utilities.js" defer></script>
<script src="main.js" defer></script>
</head>
<!-- Script with error handling -->
<script>
try {
// Risky operation
let data = JSON.parse(userInput);
processData(data);
} catch (error) {
console.error('Error processing data:', error);
showErrorMessage('Invalid data format');
}
</script>