I'm a big fan of small, reusable helper functions. My good friend and mentor, Chris Ferdinandi, maintains a fantastic collection over at The Vanilla JS Toolkit. Today, let's create some for jQuery's hide(), show(), and toggle() methods using vanilla JS.

These jQuery methods control the visibility of an element using its inline display property. We could do that too, but it's much easier to just hook into a special boolean HTML attribute: hidden.

Hide

You can use jQuery's hide() method to hide every element that matches a selector:

// Hide every element with the .hide-me class
$(".hide-me").hide();

Let's create a function called hide(). It accepts one argument, element, which is the element we want to hide. All we need to do is add the hidden attribute to the element. To do that, we'll call the setAttribute() method.

/**
* Hide an element
* @param {Object} element The element to hide
*/

function hide (element) {
element.setAttribute("hidden", "");
}

Note: the following snippet from the MDN Web Docs explains why I set the value to an empty string:

Boolean attributes are considered to be true if they're present on the element at all, regardless of their actual value; as a rule, you should specify the empty string ("") in value (some people use the attribute's name; this works but is non-standard).

Show

You can use jQuery's show() method to show every element that matches a selector:

// Show every element with the .show-me class
$(".show-me").show();

Let’s create our show() function. As before, it accepts one argument: element. This is the element we want to show. This time, we just need to remove the hidden attribute from the element. We’ll do that using the removeAttribute() method.

/**
* Show an element
* @param {Object} element The element to show
*/

function show (element) {
element.removeAttribute("hidden");
}

Toggle

In jQuery, the toggle() method allows you to toggle an element's visibility between hidden or shown. It does the same as the hide() and show() methods depending on the value of the element's inline display property:

// Toggle every element with the class .some-class
$(".some-class").toggle();

For our toggle() function, we'll again accept the single element argument. We'll use the toggleAttribute() method to toggle the hidden attribute.

/**
* Toggle an element
* @param {Object} element The element to toggle
*/

function toggle (element) {
element.toggleAttribute("hidden");
}

Looping

The thing about jQuery is that it has a feature called implicit iteration. As explained in the documentation for the each() method:

Note: most jQuery methods that return a jQuery object also loop through the set of elements in the jQuery collection—a process known as implicit iteration. When this occurs, it is often unnecessary to explicitly iterate with the each() method.

This is the example they give:

// The each() method is unnecessary here:
$("li").each(function() {
$(this).addClass("foo");
});

// Instead, you should rely on implicit iteration:
$("li").addClass("bar");

What if we want to call our functions for several elements at once?

To do that, we can first use the querySelectorAll() method to get the collection of elements as a NodeList.

We can then convert the NodeList to an array. This step isn't strictly necessary, but it is if you want better browser support. The NodeList.forEach() method has no IE support, whereas the Array.forEach() method works in IE9 and above.

Finally, we can loop through the array using the forEach() method, calling the relevant function for each element.

For example, this is how we would hide all elements with the class .some-class:

// Get all elements with the class .some-class
var elements = document.querySelectorAll(".some-class");

// Optional: convert the NodeList to an array
elements = Array.prototype.slice.call(elements);

// Hide the elements
elements.forEach(hide);

Wrapping up

And there you have it: the same basic functionality as jQuery's basic "effects", without the bloat of a 30 KB dependency. If you want to learn more about vanilla JS, I write articles about it here on my site, and my friend Chris Ferdinandi publishes awesome posts every weekday.