DEV Community

Cover image for 24 modern ES6 code snippets to solve practical JS problems
Madza
Madza

Posted on • Updated on • Originally published at blog.madza.dev

24 modern ES6 code snippets to solve practical JS problems

I hand-picked some of the most useful code snippets from 30 seconds of code. It's an awesome resource, go ahead and show it some ❤️.

In this article I tried to sorted them based on their practical use, answering common questions you may face in your project:

1.How to hide all elements specified?

const hide = (...el) => [...el].forEach(e => (e.style.display = 'none'));

// Example
hide(document.querySelectorAll('img')); // Hides all <img> elements on the page
Enter fullscreen mode Exit fullscreen mode

2.How to check if the element has the specified class?

const hasClass = (el, className) => el.classList.contains(className);

// Example
hasClass(document.querySelector('p.special'), 'special'); // true
Enter fullscreen mode Exit fullscreen mode

3.How to toggle a class for an element?

const toggleClass = (el, className) => el.classList.toggle(className);

// Example
toggleClass(document.querySelector('p.special'), 'special'); 
// The paragraph will not have the 'special' class anymore
Enter fullscreen mode Exit fullscreen mode

4.How to get the scroll position of the current page?

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});

// Example
getScrollPosition(); // {x: 0, y: 200}
Enter fullscreen mode Exit fullscreen mode

5.How to smooth-scroll to the top of the page?

const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
};

// Example
scrollToTop();
Enter fullscreen mode Exit fullscreen mode

6.How to check if the parent element contains the child element?

const elementContains = (parent, child) => parent !== child && parent.contains(child);

// Examples
elementContains(document.querySelector('head'), document.querySelector('title')); 
// true
elementContains(document.querySelector('body'), document.querySelector('body')); // false
Enter fullscreen mode Exit fullscreen mode

7.How to check if the element specified is visible in the viewport?

const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
  const { top, left, bottom, right } = el.getBoundingClientRect();
  const { innerHeight, innerWidth } = window;
  return partiallyVisible
    ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
        ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
    : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};

// Examples
elementIsVisibleInViewport(el); // (not fully visible)
elementIsVisibleInViewport(el, true); // (partially visible)
Enter fullscreen mode Exit fullscreen mode

8.How to fetch all images within an element?

const getImages = (el, includeDuplicates = false) => {
  const images = [...el.getElementsByTagName('img')].map(img => img.getAttribute('src'));
  return includeDuplicates ? images : [...new Set(images)];
};

// Examples
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']
Enter fullscreen mode Exit fullscreen mode

9.How to figure out if the device is a mobile device or a desktop/laptop?

const detectDeviceType = () =>
  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
    ? 'Mobile'
    : 'Desktop';

// Example
detectDeviceType(); // "Mobile" or "Desktop"
Enter fullscreen mode Exit fullscreen mode

10.How to get the current URL?

const currentURL = () => window.location.href;

// Example
currentURL(); // 'https://google.com'
Enter fullscreen mode Exit fullscreen mode

11.How to create an object containing the parameters of the current URL?

const getURLParameters = url =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
    {}
  );

// Examples
getURLParameters('http://url.com/page?n=Adam&s=Smith'); // {n: 'Adam', s: 'Smith'}
getURLParameters('google.com'); // {}
Enter fullscreen mode Exit fullscreen mode

12.How to encode a set of form elements as an object?

const formToObject = form =>
  Array.from(new FormData(form)).reduce(
    (acc, [key, value]) => ({
      ...acc,
      [key]: value
    }),
    {}
  );

// Example
formToObject(document.querySelector('#form')); // { email: 'test@email.com', name: 'Test Name' }
Enter fullscreen mode Exit fullscreen mode

13.How to retrieve a set of properties indicated by the given selectors from an object?

const get = (from, ...selectors) =>
  [...selectors].map(s =>
    s
      .replace(/\[([^\[\]]*)\]/g, '.$1.')
      .split('.')
      .filter(t => t !== '')
      .reduce((prev, cur) => prev && prev[cur], from)
  );
const obj = { selector: { to: { val: 'val to select' } }, target: [1, 2, { a: 'test' }] };

// Example
get(obj, 'selector.to.val', 'target[0]', 'target[2].a'); // ['val to select', 1, 'test']
Enter fullscreen mode Exit fullscreen mode

14.How to invoke the provided function after wait (in milliseconds)?

const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
delay(
  function(text) {
    console.log(text);
  },
  1000,
  'later'
); 

// Logs 'later' after one second.
Enter fullscreen mode Exit fullscreen mode

15.How to trigger a specific event on a given element, optionally passing custom data?

const triggerEvent = (el, eventType, detail) =>
  el.dispatchEvent(new CustomEvent(eventType, { detail }));

// Examples
triggerEvent(document.getElementById('myId'), 'click');
triggerEvent(document.getElementById('myId'), 'click', { username: 'bob' });
Enter fullscreen mode Exit fullscreen mode

16.How to remove an event listener from an element?

const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);

const fn = () => console.log('!');
document.body.addEventListener('click', fn);
off(document.body, 'click', fn); // no longer logs '!' upon clicking on the page
Enter fullscreen mode Exit fullscreen mode

17.How to get readable format of the given number of milliseconds?

const formatDuration = ms => {
  if (ms < 0) ms = -ms;
  const time = {
    day: Math.floor(ms / 86400000),
    hour: Math.floor(ms / 3600000) % 24,
    minute: Math.floor(ms / 60000) % 60,
    second: Math.floor(ms / 1000) % 60,
    millisecond: Math.floor(ms) % 1000
  };
  return Object.entries(time)
    .filter(val => val[1] !== 0)
    .map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
    .join(', ');
};

// Examples
formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574); // '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'
Enter fullscreen mode Exit fullscreen mode

18.How to get the difference (in days) between two dates?

const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600 * 24);

// Example
getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9
Enter fullscreen mode Exit fullscreen mode

19.How to make a GET request to the passed URL?

const httpGet = (url, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.onload = () => callback(request.responseText);
  request.onerror = () => err(request);
  request.send();
};

httpGet(
  'https://jsonplaceholder.typicode.com/posts/1',
  console.log
); 

// Logs: {"userId": 1, "id": 1, "title": "sample title", "body": "my text"}
Enter fullscreen mode Exit fullscreen mode

20.How to make a POST request to the passed URL?

const httpPost = (url, data, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('POST', url, true);
  request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
  request.onload = () => callback(request.responseText);
  request.onerror = () => err(request);
  request.send(data);
};

const newPost = {
  userId: 1,
  id: 1337,
  title: 'Foo',
  body: 'bar bar bar'
};
const data = JSON.stringify(newPost);
httpPost(
  'https://jsonplaceholder.typicode.com/posts',
  data,
  console.log
); 

// Logs: {"userId": 1, "id": 1337, "title": "Foo", "body": "bar bar bar"}
Enter fullscreen mode Exit fullscreen mode

21.How to create a counter with the specified range, step and duration for the specified selector?

const counter = (selector, start, end, step = 1, duration = 2000) => {
  let current = start,
    _step = (end - start) * step < 0 ? -step : step,
    timer = setInterval(() => {
      current += _step;
      document.querySelector(selector).innerHTML = current;
      if (current >= end) document.querySelector(selector).innerHTML = end;
      if (current >= end) clearInterval(timer);
    }, Math.abs(Math.floor(duration / (end - start))));
  return timer;
};

// Example
counter('#my-id', 1, 1000, 5, 2000); // Creates a 2-second timer for the element with id="my-id"
Enter fullscreen mode Exit fullscreen mode

22.How to copy a string to the clipboard?

const copyToClipboard = str => {
  const el = document.createElement('textarea');
  el.value = str;
  el.setAttribute('readonly', '');
  el.style.position = 'absolute';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  const selected =
    document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
  el.select();
  document.execCommand('copy');
  document.body.removeChild(el);
  if (selected) {
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(selected);
  }
};

// Example
copyToClipboard('Lorem ipsum'); // 'Lorem ipsum' copied to clipboard.
Enter fullscreen mode Exit fullscreen mode

23.How to find out if the browser tab of the page is focused?

const isBrowserTabFocused = () => !document.hidden;

// Example
isBrowserTabFocused(); // true
Enter fullscreen mode Exit fullscreen mode

24.How to create a directory, if it does not exist?

const fs = require('fs');
const createDirIfNotExists = dir => (!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined);

// Example
createDirIfNotExists('test'); // creates the directory 'test', if it doesn't exist
Enter fullscreen mode Exit fullscreen mode

I hope you enjoyed the read!

Feel free to follow me on Twitter, LinkedIn, Hashnode and DEV for more!

Top comments (26)

Collapse
 
3zzy profile image
Ibrahim Ezzy

hasClass(document.querySelector('p.special'), 'special'); doesn't make sense. If you're already searching with the class in selector, couldn't you just do if (document.querySelector('p.special')) ?

Collapse
 
fetishlace profile image
fetishlace

To point 12.
Instead of confusing reduce I would do rather:
const formToObject = form => Object.fromEntries([...new FormData(form)])
(when Object.fromEntries() is available indeed...)

Collapse
 
zarabotaet profile image
Dima

Congrat, you reinvented
yarn add jquery

Collapse
 
jscripter profile image
Jscripter

I didn't know about the classList.toggle. Thanks.
In nodejs there is native package called querystring for url parameters.
I find it useful copy to clipboard, used it in a project.

Collapse
 
vonheikemen profile image
Heiker
const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);

That number 14 really doesn't do anything. You might as well just assign the function to delay.

const delay = setTimeout;
Collapse
 
madza profile image
Madza • Edited

I see your point. This is great for hard-coded values in setTimeout() method and without need to create other constants later, like:

const delay = setTimout(()=>{console.log('delay event')}, 1000); 
// logs 'delay event' after 1000ms each time

by wrapping setTimeout() method in a function you can re-use your defined timer function with different values each time without creating new constants:

const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
delay(()=>{console.log('delay event 1')}, 1000) //logs 'delay event 1' after 1000ms
delay(()=>{console.log('delay event 2')}, 5000) //logs 'delay event 2' after 5000ms, etc
Collapse
 
vonheikemen profile image
Heiker • Edited

by wrapping setTimeout() method in a function you can re-use your defined timer function with different values each time without creating new constants

I'm not sure I understand what you're saying here. They behave the same.

var delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
var renamed = setTimeout;

var handler = (arg) => { console.log('delay event 1', arg) };
var other_handler = (arg) => { console.log('another one', arg) };

delay(handler, 1000, 'from delay');
renamed(handler, 1000, 'from renamed');
setTimeout(handler, 1000, 'from setTimeout');

delay(other_handler, 2000, 'from delay');
renamed(other_handler, 2000, 'from renamed');
setTimeout(other_handler, 2000, 'from setTimeout');

Personally, if I were to wrap setTimeout it would be to change the function signature, something like this.

var delay_fn = (wait, fn) => (...args) => setTimeout(fn, wait, ...args);

var delay_log = delay_fn(1000, handler);

delay_log('from delay log');

I only use var because I tested these on firefox's devtools.

Thread Thread
 
madza profile image
Madza

That's the point - they behave the same, but you don't have to create new variables for the same functionality throughout your app. Instead you just use the same function once you need timer functionality for something.

Furthermore, if you need different function signature, you can use the latter assigning it to different var.

Thread Thread
 
vonheikemen profile image
Heiker

they behave the same, but you don't have to create new variables for the same functionality throughout your app.

if I assign setTimeout that will force me to create new unnecesary variables in the entire app? And that doesn't happen if I wrap it in a function?

Thread Thread
 
piterden profile image
Denis Efremov
/**
 * Sleep pause.
 *
 * @param {Number} time The time in milliseconds.
 * @return {Promise<void>}
 */
const sleep = (time) => new Promise((resolve) => {
  setTimeout(resolve, time)
})
Collapse
 
webreflection profile image
Andrea Giammarchi • Edited

The getURLParameters is not really safe/useful, I'd go instead with:

const getURLParameters = url => [
  ...new URL(url).searchParams
].reduce(
  (obj, [key, value]) => ((obj[key] = value), obj),
  {}
);

or, for possible duplicated keys:

const getURLParameters = url => [
  ...new URL(url).searchParams
].reduce(
  (obj, [key, value]) => ((
    obj[key] = key in obj ? [].concat(obj[key], value) : value
  ), obj),
  Object.create(null)
);
Collapse
 
3zzy profile image
Ibrahim Ezzy

To to check if the element specified is visible in the viewport, IntersectionObserver is more performant and available in all major browsers.

Collapse
 
madza profile image
Madza • Edited

Thanks for your feed. Checked in caniuse and the support is better than i expected :)

Collapse
 
kimsean profile image
thedevkim

I love one liners but I'm afraid that my co-developers wont get it right.

Collapse
 
madza profile image
Madza • Edited

For those not familiar with ES6 syntax it could be harder to grasp at first :)

Collapse
 
isherwood profile image
Clint Buhs

Yeah, but these aren't one liners in the traditional sense (code crushed like a soda can for no good reason). The new syntax is worth working to understand since it brings benefits beyond brevity.

Collapse
 
piterden profile image
Denis Efremov
const hide = (...el) => [...el].forEach(e => (e.style.display = 'none'));

This is wrong! ^

const hide = (el) => [...el].forEach(e => (e.style.display = 'none')); 

This is correct! ^

Collapse
 
marko035 profile image
Marko • Edited

22 can be shortened a lot. Here is shorter version.

const listener = (e: ClipboardEvent) => {
  e.clipboardData.setData('text/plain', text);
  e.preventDefault();
};

document.addEventListener('copy', listener);
document.execCommand('copy');
document.removeEventListener('copy', listener);
Collapse
 
madza profile image
Madza • Edited

Thanks for your point. I first started with clipbard.js for that (3kb gzipped) :)

Collapse
 
cyberhck profile image
Nishchal Gautam

These are the worst piece of advice I saw, sorry, I'm just being honest. You have toggle already, you wanna wrap that, just use the original method, why not use setTimeout instead of delay? Use fetch to post to a url, just use remove event listener to remove, following these, people will have to learn new functions instead of using normal Javascript

Some of them might be useful, but I found most of them to be nonsense.

Collapse
 
mateiadrielrafael profile image
Matei Adriel

Why do you need the spread in the first example, rest params will already be collected into an array

Collapse
 
cameronapak profile image
cameronapak

Thanks for posting this! I'll definitely keep them saved and in mind. I see that a lot of people are saying some comment about how something isn't best practice, but I'm happy you even posted this. Even if there are better ways, most of these are great examples and approaches I would've never thought about on my own.

Collapse
 
fetishlace profile image
fetishlace • Edited

To point 11. It is maybe modern JS but there is URL object for these things for some time, no need for regexping
You have all the parameters in URL searchParams object
const params = new URL(window.location.href).searchParams
You can just spread it into entries
[...params] or [...params.entries()]
or if you want to have object so much (even it makes not much sense here, since you can have valid params string with multiple same parameter with different values and then you will loose them except last one, since object cannot have multiple same keys...)
Object.fromEntries([...params])

Collapse
 
mwansa19 profile image
Mwansa Chupa

This is great..Thanks