HTML Document scripts Collection: Accessing Script Elements

The document.scripts collection in HTML provides a convenient way to access all the <script> elements within a document. This collection is a live HTMLCollection, meaning that any changes to the document’s script elements are immediately reflected in the collection. This feature is incredibly useful for inspecting, modifying, or dynamically managing JavaScript code embedded in your web pages. This article will guide you through accessing and manipulating script elements using the document.scripts collection, including examples for both inline and external scripts.

What is document.scripts?

The document.scripts property returns an HTMLCollection of all the <script> elements in the HTML document. It allows you to iterate through the script elements, retrieve their attributes, and even manipulate them, such as modifying their source or content. This property provides a dynamic way to manage JavaScript execution and script element attributes.

Purpose of document.scripts

The primary purpose of the document.scripts collection is to enable developers to:

  • Inspect all script elements: Examine the source, type, and other attributes of each script tag.
  • Modify existing scripts: Dynamically change script attributes like src or add event listeners.
  • Dynamically add scripts: Although document.scripts doesn’t add new scripts directly (it’s just a collection), it enables you to manipulate existing ones or add completely new ones to the DOM and the scripts collection will update dynamically.
  • Manage script execution: Control when and how scripts are loaded or executed.

Syntax and Usage

The syntax to access the scripts collection is straightforward:

const scriptsCollection = document.scripts;

This returns a live HTMLCollection of all <script> elements. The collection is array-like, meaning you can access items using numeric indices.

Key Properties and Methods

Here are the key properties and methods associated with the document.scripts collection:

Property/Method Type Description
`length` Number Returns the number of `script` elements in the collection.
`item(index)` or `scripts[index]` Method/Property Returns the `script` element at the specified index.
`namedItem(id)` Method Returns the `script` element with the specified `id`, or `null` if not found.
HTML Collection Live Property The `HTMLCollection` is a live collection, meaning it updates as the document changes.

Accessing Script Elements

Let’s explore how to access and manipulate script elements using the document.scripts collection with practical examples.

Basic Access

This example demonstrates how to access the collection and log the number of script elements.

<!DOCTYPE html>
<html>
<head>
    <title>Accessing Script Elements</title>

<script>


      //Inline script
      console.log('This is inline script in head')
</script>

</head>
<body>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js">

</script>

    <script id="myScript">
       //Inline script
      console.log('This is inline script in body')
</script>

<script>
        const scriptElements_basic = document.scripts;
        console.log('Number of script elements: ', scriptElements_basic.length);
</script>

</body>
</html>

Output:

 Number of script elements: 3

This code snippet includes three <script> tags—one inline in <head>, one external, and one inline in <body>. The output shows that the document.scripts collection correctly identifies all of them.

Accessing by Index

This example shows how to access individual script elements using their index.

<!DOCTYPE html>
<html>
<head>
  <title>Accessing Script Elements by Index</title>
</head>
<body>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js">
</script>

    <script id="scriptByIndex">
        console.log('This is inline script');
</script>

<script>
      const scriptElements_index = document.scripts;
      const firstScript_index = scriptElements_index[0];
      const secondScript_index = scriptElements_index[1];
      console.log('First Script:', firstScript_index.src ? firstScript_index.src : 'Inline Script'  );
      console.log('Second Script ID:', secondScript_index.id);
</script>

</body>
</html>

Output:

First Script: https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js
Second Script ID: scriptByIndex

Here, we access the first and second script elements using scriptElements_index[0] and scriptElements_index[1] respectively. The src of the first script is printed, and the id of the second script is printed.

Accessing by ID Using namedItem()

The namedItem() method allows you to access a script element by its id attribute.

<!DOCTYPE html>
<html>
<head>
    <title>Accessing Script Elements by ID</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js">

</script>

</head>
<body>

    <script id="myScriptId">
        console.log('This is inline script for id test');
</script>

<script>
        const scriptElements_id = document.scripts;
        const myScript_id = scriptElements_id.namedItem('myScriptId');
        if (myScript_id) {
          console.log('Script ID: ', myScript_id.id);
        }
</script>

</body>
</html>

Output:

 Script ID:  myScriptId

The namedItem('myScriptId') method correctly retrieves the script element with the specified ID.

Iterating through Script Elements

You can loop through the HTMLCollection using a for loop to access each script element.

<!DOCTYPE html>
<html>
<head>
    <title>Iterating through Script Elements</title>
</head>
<body>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js">

</script>

    <script id="script1">
      console.log('This is script 1');
</script>

      <script id="script2">
        console.log('This is script 2');
</script>

<script>
      const scriptElements_iterate = document.scripts;
      for (let i = 0; i < scriptElements_iterate.length; i++) {
          console.log('Script at index ', i, ':', scriptElements_iterate[i].id? scriptElements_iterate[i].id : 'Inline Script');
      }
</script>

</body>
</html>

Output:

 Script at index  0 : Inline Script
 Script at index  1 : script1
 Script at index  2 : script2

The output demonstrates how the loop iterates through each script element in the collection.

Modifying Script Attributes

Here is an example of how to modify the type attribute of an existing script tag.

<!DOCTYPE html>
<html>
<head>
    <title>Modifying Script Attributes</title>
</head>
<body>

  <script id="modifyMe" type="text/javascript">
    console.log("Original Type");
</script>

<script>
    const scriptElements_modify = document.scripts;
    const scriptToModify = scriptElements_modify.namedItem('modifyMe');

    if (scriptToModify) {
      scriptToModify.type = 'module';
      console.log('Script Type Modified To: ', scriptToModify.type)
      console.log('Script Type Check: ', scriptToModify.type === 'module')
    }
</script>

</body>
</html>

Output:

Script Type Modified To: module
Script Type Check: true

This code snippet changes the script element’s type from text/javascript to module, and confirms that the modification has been applied.

Live Collection

The document.scripts collection is a live HTMLCollection. This means that any changes to the document’s script elements are immediately reflected in the collection.

<!DOCTYPE html>
<html>
<head>
    <title>Live Collection Example</title>
</head>
<body>

    <script id="firstScript">
      console.log("First Script");
</script>

<script>
      const scriptElements_live = document.scripts;
      console.log('Initial Length:', scriptElements_live.length);

      const newScript_live = document.createElement('script');
      newScript_live.textContent = 'console.log("Added Script")';
      document.body.appendChild(newScript_live);

       console.log('After Adding New Script Length:', scriptElements_live.length);
</script>

</body>
</html>

Output:

Initial Length: 1
After Adding New Script Length: 2

This code adds a new script tag to the DOM, which is reflected in the live collection. The length of the collection is updated from 1 to 2 without any explicit re-fetching of the collection.

Use Cases for document.scripts

The document.scripts collection is useful in various scenarios, including:

  • Dynamic Script Loading: You can load scripts dynamically based on user interaction or other events.
  • Script Modification: You can modify existing script attributes, such as the src attribute.
  • Debugging Tools: You can inspect and manage scripts while debugging to understand how they are loaded and executed.
  • Feature Flags: Use it to conditionally activate or deactivate certain features by controlling script loading or execution.

Practical Example: Dynamic Script Loading

Here’s an example of how to dynamically load a script based on a button click using document.scripts:

<!DOCTYPE html>
<html>
<head>
    <title>Dynamic Script Loading</title>
</head>
<body>
    <button id="loadScriptButton">Load External Script</button>

<script>
        const loadButton_dynamic = document.getElementById('loadScriptButton');
         let scriptLoaded_dynamic = false
        loadButton_dynamic.addEventListener('click', function() {
            if(!scriptLoaded_dynamic) {
              const newScript_dynamic = document.createElement('script');
              newScript_dynamic.src = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js";
              document.body.appendChild(newScript_dynamic);
              scriptLoaded_dynamic = true
              newScript_dynamic.onload = function(){
                console.log('Moment Js Loaded');
              }

            }else{
              console.log('Script Already Loaded')
            }

        });

        const scriptElements_dynamic = document.scripts;
        console.log('Initial Script Count:', scriptElements_dynamic.length);

        // log dynamically added scripts
         let scriptCounter = 0
       setInterval(()=>{
          const scriptElements_dynamic_interval = document.scripts;
            if(scriptElements_dynamic_interval.length > scriptCounter){
                console.log('Current Script Count:', scriptElements_dynamic_interval.length);
               scriptCounter =  scriptElements_dynamic_interval.length;
            }

       },500)
</script>

</body>
</html>

When you click the “Load External Script” button, the code dynamically adds a script tag to the document.body. An event listener is attached to the button to load the external script when it is clicked. The onload event ensures that the script has been loaded before running any function that uses the library. The setInterval keeps track of new scripts getting added to DOM, thus reflecting the live nature of the collection.

Browser Support

The document.scripts collection is supported by all modern browsers.

Conclusion

The document.scripts collection offers a robust method for accessing and manipulating script elements in an HTML document. Understanding how to utilize this property is crucial for effectively managing JavaScript in your web projects. Whether you’re inspecting, modifying, or dynamically loading scripts, document.scripts provides the necessary control to create dynamic and interactive web pages. By combining this knowledge with other DOM APIs, you can create efficient, dynamic web applications. Happy coding!
“`