Having been looking at too many tools lately, it’s a good time to take a break from all the React and NPm-install-everything articles and look at some pure DOM and Web API features that can run in modern browsers without relying on any third-party libraries.

This article takes a look at eight little-known DOM features with powerful browser support. To help you understand how each feature works, I’ll give you a demo for yourself with a lot of test code, all on CodePen.

Learning these methods and properties does not have a steep learning curve and can be used with any toolset used in a project.

New parameters for addEventListener(), options

You’ve certainly handled elements that append events to Web documents with addEventListener(). Normally the addEventListener() call looks like this:

element.addEventListener('click', doSomething, false);
Copy the codeCopy the code

The first parameter is the event that you are listening for. The second argument is a callback function that will be executed when the event occurs. The third parameter is a Boolean value called useCapture that indicates whether to use event bubble or capture.

Everyone knows this (especially the first two). But maybe you don’t know that addEventListener() also takes a parameter that replaces the final Boolean value. The new argument is an options object, as follows:

element.addEventListener('click', doSomething, {
  capture: false.once: true.passive: false
});
Copy the codeCopy the code

Notice that this syntax allows you to define three different attributes. Here’s a quick overview of each meaning:

  • capture— And the one mentioned earlieruseCapture parameterSame Boolean value
  • once– Boolean if set totrue, means that the event should run only once on the target element and then be deleted
  • passive– A final Boolean value if set totrue, indicating that the function is never calledpreventDefault()Even if it is contained in the function body

The most interesting of these is the once option. This will definitely come in handy in many situations, and you don’t have to force a single event trigger with removeEventListener() or some other complicated technique. If you’ve used jQuery, you’re probably familiar with a similar feature in this library: the.one() method.

You can try running the following code for the options object in the CodePen project:

See the Pen Using addEventListener() with an options Object as Third Parameter by Louis Lazaris (@impressivewebs) on CodePen.

CodePen demo: Codepen. IO /impressivew…

Note that the buttons on the demo page attach text only once. If you change the once value to false, the button is clicked multiple times, with text appended each time the button is clicked.

Browser support for the Options object is excellent: all browsers support it except Internet Explorer 11 and earlier, so if you don’t consider Microsoft Edge prior browsers, it’s pretty safe to use.

The scrollTo() method is used to smooth scrolling through Windows or elements

Smooth scrolling is often used. When you click on the local page link and immediately jump to the specified location (if you blink, you may even miss the jump), it can be quite jarring. Smooth scrolling improves the user experience of the page.

While it used to be enough with the jQuery plug-in, using the window.scrollto () method now requires only one line of JavaScript.

The scrollTo() method acts on the Window object and tells the browser to scrollTo the specified location on the page. Here is an example of the simplest syntax:

window.scrollTo(0.1000);
Copy the codeCopy the code

This will scroll the window 0px to the right (representing x coordinates or horizontal scrolling) and 1000px down (vertical scrolling, which is usually what you want). But instead of scrolling as a smooth animation, the page will suddenly scroll.

Sometimes it’s exactly what you want. But to smooth scrolling, you must add the little-known ScrollToOptions object, like this:

window.scrollTo({
  top: 0.left: 1000.behavior: 'smooth'
});
Copy the codeCopy the code

This code is the same as the previous example, but adds a smooth value for the Behavior property to the Options object.

Take a look at the CodePen demo below, which allows you to customize the amount and behavior of scrolling:

See the Pen Using addEventListener() with an options Object as Third Parameter by Louis Lazaris (@impressivewebs) on CodePen.

CodePen demo: Codepen. IO /impressivew…

Try entering a number in the box (preferably a large number, such as 4000) and change the Behavior selection box to use smooth or auto (the only two options for the Behavior property).

A few notes about this feature:

  • Basic support for scrollTo() is comprehensive, but not all browsers support options objects

  • This method can also be used when applied to elements

  • These options also apply to scroll() and scrollBy() methods

SetTimeout () and setInterval() with optional arguments

In more cases, the use of the window. The setTimeout (), and the window. The setInterval () implementation animation scheme based on time sequence has been better performance of the window. The requestAnimationFrame replaced (). But there are cases where using setTimeout() or setInterval() is the right choice, so it’s good to know a little-known feature of these methods.

You’ll usually see these methods used with the syntax:

let timer = window.setInterval(doSomething, 3000);
function doSomething () {
  / / Something happens here...
}
Copy the codeCopy the code

Here setInterval() takes two arguments: the callback function and the time interval. If setTimeout() is used it will only run once, whereas in the current case it will run indefinitely until I call window.clearTimeout() when the timer variable is passed in.

That’s easy. But what if I want the callback function to accept arguments? It can be done like this:

let timer = window.setInterval(doSomething, 3000.10.20);
function doSomething (a, b) {
  / / Something happens here...
}
Copy the codeCopy the code

Notice that I added two parameters to the setInterval() call. My doSomething() function then takes these arguments and can manipulate them as needed.

Here is a CodePen demo that shows how to use setTimeout() :

See the Pen Optional Parameters with window.setTimeout() by Louis Lazaris (@impressivewebs) on CodePen.

CodePen: CodePen. IO/impressivew…

When the button is clicked, the two values passed in are used for calculation. You can change values by modifying numbers in the code.

As for browser support, there seems to be some minor compatibility issues, but it looks like almost every browser in use now supports optional parameters, including IE10.

DefaultChecked properties for radio buttons and check boxes

As you probably know, radio buttons and check boxes can be obtained or set directly via the Checked property, as shown below (assuming radioButton is a reference to a specific form input) :

console.log(radioButton.checked); // true
radioButton.checked = false;
console.log(radioButton.checked); // false
Copy the codeCopy the code

But there is also a property called defaultChecked, which can be applied to groups of radio buttons or check boxes to find out which of the groups was originally set as checked.

Here are some HTML examples:

<form id="form">
  <input type="radio" value="one" name="setOne"> One
  <input type="radio" value="two" name="setOne" checked> Two<br />
  <input type="radio" value="three" name="setOne"> Three
</form>
Copy the codeCopy the code

With this property, even after changing the selected radio button, you can iterate to find out which was originally the default, as shown below:

for (i of myForm.setOne) {
  if (i.defaultChecked === true) {
    console.log (i.v alue "); }}Copy the codeCopy the code

Here is the CodePen demo, which will show the currently selected radio button or the default selected radio button, depending on which button you are using:

See the Pen defaultChecked on Radio Buttons by Louis Lazaris (@impressivewebs) on CodePen.

CodePen: CodePen. IO/impressivew…

The defaultChecked option in this example will always be the “Two” radio button. As mentioned above, this can also be used for checkbox groups. You can try modifying the default selection in HTML and click the button again to see the effect.

Here is an example of a checkbox group:

See the Pen defaultChecked on Checkboxes by Louis Lazaris (@impressivewebs) on CodePen.

CodePen: CodePen. IO/impressivew…

In this case, you’ll notice that both checkboxes should be checked by default, so both return true when using defaultChecked queries.

Use Normalize () and wholeText to manipulate text nodes

Text nodes in HTML documents can be complex, especially when inserting or creating nodes dynamically. For example, suppose you have the following HTML:

<p id="el">This is the initial text.</p>
Copy the codeCopy the code

I can then add a text node to the paragraph element:

let el = document.getElementById('el');
el.appendChild(document.createTextNode(' Some more text.'));
console.log(el.childNodes.length); / / 2
Copy the codeCopy the code

Notice that in the comment following the attached text node, I record the length of the child node within the paragraph, and it indicates that there are two nodes. These nodes are a text string, but because the text is dynamically appended, they should be treated as separate nodes.

In some cases, it is more helpful to treat the text as a single text node, which makes the text easier to manipulate. This is where Normalize () and wholeText() come in.

The normalize() method can be used to merge individual text nodes:

el.normalize();
console.log(el.childNodes.length); / / 1
Copy the codeCopy the code

Calling normalize() on an element will merge any adjacent text nodes within that element. If some HTML happens to be scattered between adjacent text nodes, the HTML is left as is, and all adjacent text nodes are merged.

However, if for some reason I want to separate the text nodes, but I still want to be able to grab the text as a unit, then wholeText is useful. So INSTEAD of calling Normalize (), I can do this on adjacent text nodes.

console.log(el.childNodes[0].wholeText);
// This is the initial text. Some more text.
console.log(el.childNodes.length); / / 2
Copy the codeCopy the code

As long as I don’t call Normalize (), the length of the text node will remain 2 and I can record the entire text with a wholeText. However, the following points should be noted:

  • I have to call it on one of the text nodeswholeText, instead of the element (hence the codeel.childNodes [0],el.childNodes[1]It also works.)
  • Text nodes must be contiguous, with no other HTML separating them

You can see that these two functions, along with the splitText() method, have been used in this CodePen demo. You can view the generated logs by opening the CodePen console or the developer tools console of your browser.

InsertAdjacentElement () and insertAdjacentText ()

Many of you may be familiar with the insertAdjacentHTML() method, which allows you to easily add a string of text or HTML to a specific place on a page that is related to other elements.

But what you may not know is that there are two other methods that work in a similar way: insertAdjacentElement() and insertAdjacentText().

One drawback of insertAdjacentHTML() is that the inserted content must be in the form of a string. So if you want to include HTML, you must declare it as:

el.insertAdjacentHTML('beforebegin'.'<p><b>Some example</b> text goes here.</p>');
Copy the codeCopy the code

But the second argument to insertAdjacentElement() can be an element reference:

let el = document.getElementById('example'),
addEl = document.getElementById('other');
el.insertAdjacentElement('beforebegin', addEl);
Copy the codeCopy the code

What’s interesting about this method is that it not only adds the referenced element to the specified location, but also removes the element from its original location in the document. This is a simple way to move elements around in the DOM.

This is a CodePen demo using insertAdjacentElement(). Clicking the button effectively “moves” the target element:

CodePen: CodePen. IO/impressivew…

See the Pen Using insertAdjacentElement() to Change an Element’s Location by Louis Lazaris (@impressivewebs) on CodePen.

The insertAdjacentText() method works similarly, but the supplied text string will only be inserted as text, even if it contains HTML. Please note the following demo:

CodePen: CodePen. IO/impressivew…

See the Pen Using insertAdjacentText() with HTML Tags by Louis Lazaris (@impressivewebs) on CodePen.

You can add your own text to the input field and then use the button to add it to the document. Note: Any special characters (such as HTML tags) will be inserted as HTML entities, so distinguish this method from the insertAdjacentHTML() behavior.

All three methods (insertAdjacentHTML(), insertAdjacentElement(), and insertAdjacentText())) use the same rules for the value of the first argument:

  • beforebegin: inserted before the element of the calling method
  • afterbegin: Inserts inside the element before the first child node
  • beforeend: Inserts the element after the last child node
  • afterend: is inserted after the element

Event. The detail properties

As mentioned earlier, we can append events to elements on a web page using the familiar addEventListener() method. Such as:

btn.addEventListener('click'.function () {
  // do something here...
}, false);
Copy the codeCopy the code

When using addEventListener(), you may want to prevent the default browser behavior in function calls. For example, you might want to intercept the click of a element and use JavaScript to handle it, you would do this:

btn.addEventListener('click'.function (e) {
  // do something here...
  e.preventDefault();
}, false);
Copy the codeCopy the code

PreventDefault () is used, which is equivalent to the old return false statement. This requires you to pass the Event object to the function because the preventDefault() method is called on that object.

But you can do a lot more with event objects. In fact, when certain events are used (e.g. Click, dbclick, Mouseup, mouseDown), these events expose something called the UIEvent interface. As MDN points out, many functions on this interface have been deprecated or not standardized. But the most interesting and useful is the detail property, which is part of the official specification.

Here’s what it looks like in the same event listener example:

btn.addEventListener('click'.function (e) {
  // do something here...
  console.log(e.detail);
}, false);
Copy the codeCopy the code

I have set up a CodePen demo that shows the results of using many different events:

CodePen: CodePen. IO/impressivew…

See the Pen Using the event.detail Property by Louis Lazaris (@impressivewebs) on CodePen.

Each button in the demo responds as described by the button’s text and displays a message showing the current number of clicks. Note that:

  • The WebKit browser allows an unlimited number of clicks exceptdblclickIt’s always two clicks. Firefox only allows a maximum of three clicks before the count starts again
  • I have package through includeblurfocusTo prove that these don’t meet the criteria and always return 0 (i.e., no click)
  • Behavior in older browsers like IE11 is wildly inconsistent

Note that a good use case is included in the demo — imitating the triple strike event:

btnT.addEventListener('click'.function (e) {
  if (e.detail === 3) {
    trpl.value = 'Triple Click Successful! '; }},false);
Copy the codeCopy the code

You can still detect a higher number of clicks if all browsers count three clicks, but I think three-click events are sufficient in most cases.

ScrollHeight and scrollWidth properties

The scrollHeight and scrollWidth properties might sound familiar, because you might confuse them with other DOM functions related to width and height. For example, the offsetWidth and offsetHeight attributes return the height and width of the element, regardless of overflow.

Please note the following demo:

CodePen: CodePen. IO/impressivew…

See the Pen offsetHeight Doesn’t Count Past CSS Overflow by Louis Lazaris (@impressivewebs) on CodePen.

The columns in the demo have the same content. The left column overflow is set to Auto, and the right column overflow is set to Hidden. The offsetHeight property returns the same value because it does not consider scrollable or hidden regions, and it only measures the actual height of the element, including the vertical fill and border.

The appropriately named scrollHeight property, on the other hand, computes the element’s full height, including the scrollable (or hidden) region:

CodePen: CodePen. IO/impressivew…

See the Pen scrollHeight Measures an Element’s Full Scrollable Area by Louis Lazaris (@impressivewebs) on CodePen.

The above demo is the same as the previous one, except that it uses scrollHeight to get the height of each column. Notice again that both columns have the same value. But this time its value is much higher, because the overflow area also counts as part of the height.

The above example focuses on element height, which is the most common use case, but you can also use offsetWidth and scrollWidth, which apply to horizontal scrolling in the same way.

conclusion

Here’s a list of DOM features you didn’t know about. These are probably some of the most interesting features I’ve come across in recent years, so I hope you’ll be able to use them in your own projects in the near future.

If you’ve used any of these features before, or if you can think of an interesting use case for one of them, let me know in the comments.

from8 DOM features you didn’t know existed