Categories
JavaScript Answers

How to Detect a Touch Screen Device Using JavaScript?

Sometimes, we may need to detect a touch screen device with JavaScript.

In this article, we’ll look at how to detect a touch screen device with JavaScript.

Checking for the ontouchstart Method and maxTouchPoints

One way to check for a touch screen device is to check for the window.ontouchstart method and the navigator.maxTouchPoints property.

For instance, we can write:

const isTouchDevice = () => {  
  return (('ontouchstart' in window) ||  
    (navigator.maxTouchPoints > 0) ||  
    (navigator.msMaxTouchPoints > 0));  
}  
console.log(isTouchDevice())

We check all the items present for a touchscreen device with:

('ontouchstart' in window) ||  
(navigator.maxTouchPoints > 0) ||  
(navigator.msMaxTouchPoints > 0)

ontouchstart lets us assign a touch event listener to it that runs when we start touching the screen.

maxTouchPoints returns the number of touchpoints of the screen.

And navigator.msMaxTouchPoints is the Microsoft version of the maxTouchPoints property.

This is a cross-browser solution that works on most modern browsers.

The window.matchMedia Test

Also, we can use the window.matchMedia method to test whether a device has any touchscreen features present.

For instance, we can write:

const isTouchDevice = () => {  
  return window.matchMedia("(pointer: coarse)").matches  
}  
console.log(isTouchDevice())

We test whether the pointer: coarse CSS feature is present.

And if it is, we know the device the app is running on is a touch screen device.

Conclusion

We can test for various touch features of a device with JavaScript to check whether a device is a touch device in our JavaScript web app.

Categories
JavaScript Answers

How to Get All Non-Unique Values in a JavaScript Array?

Array.prototype.filter

We can use the JavaScript array’s filter method to return an array that meets the given condition.

It takes a callback that returns the condition we want each returned item to have.

So we can combine this with calling the indexOf method in the callback to check whether the item is the first instance of an item.

To do this, we call indexOf on the array that filter is called on, which we can get from the 3rd parameter of the callback.

Then we can check whether the returned index is the same one that the item being iterated through is in.

For instance, we can write:

const duplicates = [1, 2, 2, 4, 3, 4].filter((e, index, arr) => arr.indexOf(e) !== index)
console.log(duplicates)

Then we call filter with a callback that takes the e , index , and arr parameters.

e is the item being iterated through.

index is the index of item e .

And arr is the array that filter is being called on.

We call indexOf on arr with argument e to return the index of the first instance of e in arr .

And if it’s not the same as index , then we know it’s not the first instance of a value.

Therefore, duplicates is [2, 4] since they’re duplicated in the array.

Count the Items

We can count the items in an array by creating our own object to set the count.

For instance, we can write:

const obj = [1, 2, 2, 4, 3, 4]
  .map((val) => {
    return {
      count: 1,
      val
    }
  })
  .reduce((a, b) => {
    a[b.val] = (a[b.val] || 0) + b.count
    return a
  }, {})

const duplicates = Object.entries(obj)
  .filter(([, val]) => {
    return val > 1
  })
  .map(([key]) => +key)
console.log(duplicates)

We call map to map each entry to an object with the count set to 1 and the val with the array item value.

Then we call reduce to create an object with the count of each item, with each item being the key.

We do this by assigning the count from a[b.val] with (a[b.val] || 0) + b.count .

b.count has the new count.

And we return a which has all the counts tallied so far.

The 2nd argument is an empty object so we create an object at the end.

Then to get the duplicate values, we get all the keys with value being bigger than 1.

To do this, we call Object.entries on obj .

Then we call filter with a callback to return any entry with val bigger than 1.

val is the object property value.

Then we call map to get the key from the key-value pair arrays.

So we get the same result as in the previous example for duplicates .

Categories
JavaScript Answers

How to Select Text in an Element Programmatically Like Highlighting with a Mouse?

The window.getSelection Method

We can use the window.getSelection method to select text in an element.

For instance, if we have the following HTML:

<div>  
  foo  
</div>

Then we call window.getSelection by writing:

const node = document.querySelector('div');  
if (window.getSelection) {  
  const selection = window.getSelection();  
  const range = document.createRange();  
  range.selectNodeContents(node);  
  selection.removeAllRanges();  
  selection.addRange(range);  
}

We call window.getSelection to create the seldction object.

Then we call document.createRange to create the select range.

And then we call range.selectNodeContents with the node object to select the content of the given element.

Next, we call selectionRemoveAllRanges to remove all previously selected content.

Finally, we call selection.addRange with the range to select the currently selected text.

The window.getSelection method available with non-Internet Explorer browsers.

Categories
JavaScript Answers

How to Convert an HTMLCollection to an Array?

Array.prototype.slice

One way to convert an HTMLCollection to a JavaScript array is to use the slice method.

For instance, if we have several elements:

<div>
  foo
</div>
<div>
  bar
</div>
<div>
  baz
</div>

Then we can select them all and convert the HTMLCollection with the selected elements to an array by writing:

const divs = document.querySelectorAll('div')
const arr = Array.prototype.slice.call(divs)
console.log(arr)

We get divs by call querySelector to select all the divs in the HTML.

We just call slice with divs and it’ll return the div element objects in an array.

We can also shorten it to:

const divs = document.querySelectorAll('div')
const arr = [].slice.call(divs)
console.log(arr)

We call slice on an empty array and pass in the divs HTML.

This does the same thing slice slice returns a new array.

Array.from

We can use the Array.from method to convert an array-like or iterable object to an array.

Since an HTMLCollection is an iterable object, we can pass it into the Array.from method.

For instance, we can write:

const divs = document.querySelectorAll('div')
const arr = Array.from(divs)
console.log(arr)

We pass in divs straight into Array.from and it’ll return an array with the div element objects.

Spread Operator

The spread operator also lets us convert an iterable object into an array.

So we can do the same thing by writing:

const divs = document.querySelectorAll('div')
const arr = [...divs]
console.log(arr)

Array.prototype.push and the Spread Operator

We can also use the push method with the spread operator to push element objects in an HTMLCollection into an array.

For instance, we can write:

const divs = document.querySelectorAll('div')
const arr = []
arr.push(...divs)
console.log(arr)

Then we spread the items in divs arguments of push .

And then they’ll all be pushed to arr .

Array.prototype.concat and the Spread Operator

The concat array method also lets us append items to an array by passing them into the method as arguments.

Therefore, we can use them like push to add items into the array.

For instance, we can write:

const divs = document.querySelectorAll('div')
const arr = [].concat(...divs)
console.log(arr)

Then concat returns a new array with the divs added to the empty array that it’s called on.

So arr has the same value as the previous examples.

Categories
JavaScript Answers

How to Wait Until All Promises Complete Even If Some Are Rejected?

Promise.allSettled

The Promise.allSettled method lets us proceed with running the then callback regardless of whether all promises are complete.

For instance, we can write:

Promise.allSettled([
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.reject(3),
]).then(([result1, result2, result3]) => {
  console.log(result1, result2, result3)
});

Then result1 is {status: “fulfilled”, value: 1} .

result2 is {status: “fulfilled”, value: 2} .

And result3 is {status: “rejected”, reason: 3} .

status has the status of each promise.

And value has the resolved value if the promise is resolved.

And reason has the rejected value if the promise is rejected.

We can also write the same code with the async and await syntax.

For instance, we can write:

(async () => {
  const [result1, result2, result3] = await Promise.allSettled([
    Promise.resolve(1),
    Promise.resolve(2),
    Promise.reject(3),
  ])
  console.log(result1, result2, result3)
})()

And we get the same values as before for result1 , result2 , and result3 .

Promise.all with map

We can call map on the promise array.

Then we pass in a callback that calls catch on any promise that are rejected.

The catch callback only runs when a promise is rejected, so we either return the promise itself if catch isn’t run.

Otherwise, we return a promise with the catch callback run.

So we can write:

Promise.all(
    [
      Promise.resolve(1),
      Promise.resolve(2),
      Promise.reject(3),
    ]
    .map(p => p.catch(e => e))
  )
  .then(([result1, result2, result3]) => {
    console.log(result1, result2, result3)
  });

We call map with p => p.catch(e => e) to return any promises that are rejected with a promise that’s caught.

In the catch callback, we return the rejection reason.

Then in the then callback, we can destructure the promise results as usual.

So we get that result1 is 1.

result2 is 2.

And result3 is 3.

We can write tyhe same code with async and await by writing:

(async () => {
  const [result1, result2, result3] = await Promise.all([
      Promise.resolve(1),
      Promise.resolve(2),
      Promise.reject(3),
    ]
    .map(p => p.catch(e => e))
  )
  console.log(result1, result2, result3)
})()

And we get the same result as before.