21

I am trying to add a deferred script tag like this:

const script = document.createElement('script');
  script.setAttribute('src', '/script.js');
  script.setAttribute('type', 'text/javascript');
  script.setAttribute('defer', true);//this is the code in question!
  document.getElementsByTagName('body')[0].appendChild(script);

But I found out the result script tag will generate the defer attribute like defer=true instead of just defer.

Are they same? What is the implication if I do defer=true rather than defer?

4 Answers 4

33

I would change it to:

script.setAttribute("defer", "defer");

They usually behave the same (although the docs technically state the value of an attribute such as defer should not be "true" or false") - or at least in any browser I've used boolean attributes in. The attribute defer is usually implemented to take effect if present in the script tag. Its value is ignored.

That being said, the spec specifies that a boolean attribute's value should not be present, or otherwise should be set to itself, with no leading / trailing whitespace (case does not matter). So, it's preferable to leave the value as the name of the attribute when setting it dynamically.

Refer to this documentation for boolean attributes (HTML5): https://www.w3.org/TR/html5/infrastructure.html#boolean-attribute

Quote from that doc:

A number of attributes are boolean attributes. The presence of a boolean attribute on an element represents the true value, and the absence of the attribute represents the false value.

If the attribute is present, its value must either be the empty string or a value that is an ASCII case-insensitive match for the attribute's canonical name, with no leading or trailing whitespace.

Note: The values "true" and "false" are not allowed on boolean attributes. To represent a false value, the attribute has to be omitted altogether.

And this documentation for the defer attribute (HTML5): https://www.w3.org/TR/html5/scripting-1.html#attr-script-defer

It states:

The async and defer attributes are boolean attributes that indicate how > the script should be executed.

Update: It looks like if you set an attribute to the empty string, it will add the attribute with no value. This is also an option.

Sign up to request clarification or add additional context in comments.

2 Comments

It is not possible to use defer for scripts that are dynamically added to the DOM. They are always loaded async (defer attribute is ignored). Please see my answer
This is a good point - the defer tag isn't necessarily. However, this answer is applicable in general to questions about best practices for how to add boolean attributes to DOM elements with JS.
5

This worked for me: (chrome 94)

script.defer = true;

Comments

0

If you already have a script tag and want to add defer/async attribute. Then use this code.

window.addEventListener('load', (event) => {
    var fbChatScript = document.querySelector('#facebook-jssdk');
    fbChatScript.setAttribute('defer', '');
});

Comments

0

The defer attribute is ignored for dynamically inserted scripts. They will always be loaded async. You can read more about it here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.