Implementing a feature to select and copy a range with one click using Vanilla JS

Hello.
I'm Mandai, the Wild team member in charge of development.

a function that copies a predefined string to the clipboard when a button is pressed,ZeroClipboard we implemented

Zero Clipboard is a library that allows you to create a copy button simply by installing and loading JavaScript and an SWF file, and I remember it being very easy to install

But lately, it seems like it hasn't been working properly, and then I suddenly realized something:
Google Chrome has Flash disabled by default!

It's not that you can't play Flash

Google Chrome simply disables Flash by default; it doesn't completely ignore it. It
will work if you configure it correctly.

To briefly explain, from the three vertical dots to the right of the URL bar, select Settings, then from the hamburger menu in the upper left, go to "Advanced Settings" → "Privacy and Security".
The Flash settings are located under the "Content Settings" category, so change them as needed.

Having it in such a place seems like a malicious move, but Google's opinion is that there are just too many security holes, which is a reasonable one

Although it is being supported in this way, I don't think it will gain popularity in the future, so I would like to move away from Flash as soon as possible

 

Specifications have been standardized and APIs have been improved in recent JavaScript

Perhaps due to the recent popularity of JavaScript, browser-side JavaScript implementations are progressing at an incredible pace.
jQuery is often portrayed negatively these days, for example, for causing slow website rendering speeds, but in reality, there are many things that can be done without it.
It seems that it is more often adopted out of necessity because it is used by the CSS framework.

The task we're going to cover today, copying a string to the clipboard, is a prime example of something that previously couldn't be done using JavaScript alone, but it can now be done!

 

That's where "Vanilla JS" comes in

So, that was a long introduction, but from here on I would like to try copying to the clipboard using pure Vanilla JS

The order of processing is

  1. Select the text you want to copy
  2. Copy

That's all

 

Select the text you want to copy

Selecting a string requires more steps than copying it, so once you understand this part, it's all you need

There are two objects related to selecting text: the Range object and the Selection object

A Range object is an object that holds information indicating which range of a page is selected.
A Selection object, on the other hand, is an object that manages Range objects and can contain one or more Range objects.

Since it is the Range object that selects the text, you can obtain a Range object by either extracting it from a Selection object or by creating a new Range object

// Create a new Range object var range = document.createRange(); // Get the Range object from the Selection object var selection = window.getSelection(); var range = selection.getRangeAt(0);

 

Regardless of which method you use to obtain it, the contents of the variable `range` will be the same Range object, so you can prepare the Range object using whichever method you prefer.
This time, we will try an implementation that uses a Range object extracted from a Selection object.

Assuming the tag containing the string you want to copy is as follows:

<div id="hoge">The string to copy</div>

 

Get the DOM using the getElementById() method

var hoge = document.getElementById('hoge');

 

Next, you specify the selection range.
There are two ways to do this: if you want to copy all the contents of a DOM element, you use the selectNodeContents() method of the Range object.

range.selectNodeContents(hoge);

 

Furthermore, when copying only a portion of a DOM element, you specify the starting point with the Range object's setStart() method and the ending point with the setEnd() method. It's
important to note that if you're only copying a portion, passing the DOM element obtained with getElementById() directly to the setStart() and setEnd() methods will usually result in an error. Therefore, you need to extract only the Node string from the DOM and pass that instead.

range.setStart(hoge, 7); range.setEnd(hoge, 15); // An error occurs // Uncaught IndexSizeError: Failed to execute 'setStart' on 'Range': There is no child at offset 7.

 

The IndexSize in this error is looking at the index of the DOM array in the hoge object and saying that there is no seventh Node. We thought we were passing a string and starting from the seventh character, but there was a misunderstanding

Therefore, you need to pass the text node contained in the hoge object as the first argument to the setStart() and setEnd() methods. The standard way to get the text node is from the firstChild property

var hoge = document.getElementById('hoge'); var hogeTextNode = hoge.firstChild; range.setStart(hogeTextNode, 7); range.setEnd(hogeTextNode, 15);

 

Once you have specified the selection range, all that's left is to select it, but there is a pitfall here as well

To select an object, simply add a Range object that specifies the selection range to the Selection object using the addRange() method

selection.addRange(range); // Error occurs // Discontiguous selection is not supported.

 

You say that discontiguous selections are not supported, but what does it mean to be discontiguous?

In this example, the Range object was extracted from the Selection object, which is what the above error means

The Selection object already has one Range object, so adding one using the addRange() method will result in two Range objects, which is the discontinuous Selection state indicated by the error

Since it is the Range object that we added later that we want to specify as the selection range, the quickest way is to delete the Range object that the Selection object originally had, and then add a Range object so that it only has one

selection.removeAllRanges(); // As the method name suggests, removes all Range objects selection.addRange(range);

 

This has successfully selected the text.
In summary, the following code will select the text on the screen.

// Get the Range object from the Selection object var selection = window.getSelection(); var range = selection.getRangeAt(0); var textNode = document.getElementById('hoge').firstChild; // To select all text in the DOM range.selectNodeContents(textNode); // With the selectNodeContents() method, there is no need to extract the text node // To select only a portion of the DOM range.setStart(textNode, 7); range.setEnd(textNode, 15); // Select via the Selection object selection.removeAllRanges(); selection.addRange(range);

 

Copy a string to the clipboard

To execute "Ctrl + C" on the selected string, use the execCommand() method below

document.execCommand('copy');

 

Now that the selected text has been copied to the clipboard, all you have to do is press Ctrl + V wherever you like

 

summary

I've taken up quite a bit of space just explaining how to select text, but what do you think?
While there are snippets of information on Stack Overflow and other sites, the necessary information isn't organized well enough to understand why errors occur, which can make you feel intimidated by using the clipboard in JavaScript. So, if you can just understand the logic behind the errors, there's nothing to be afraid of anymore, right?

That's all

If you found this article helpful,please give it a "Like"!
1
Loading...
1 vote, average: 1.00 / 11
2,320
X Facebook Hatena Bookmark pocket

The person who wrote this article

About the author

Yoichi Bandai

My main job is developing web APIs for social games, but thankfully I'm also given the opportunity to work on various other tasks, including marketing.
My image rights within Beyond are treated as CC0.