Implementing a function to complete range selection and copy with one click using Vanilla JS

table of contents
Hello.
I'm Mandai, in charge of Wild on the development team.
ZeroClipboard to implement a function that copies a default string to the clipboard with the press of a button
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
However, recently I felt like it wasn't working properly, and I suddenly realized that
Google Chrome has Flash disabled by default!
It's not that you can't play Flash
Google Chrome simply disables Flash by default, but it doesn't completely ignore it. It
still works if you configure it properly.
To briefly explain, select Settings from the three vertical dots to the right of the URL field, then go to "Advanced Settings" from the hamburger in the upper left corner and select "Privacy and Security.
" The Flash behavior settings are tucked under the "Content Settings" category, so adjust them as necessary.
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 implementation of JavaScript is progressing at an incredible pace.
jQuery has often been demonized recently for causing slower website rendering speeds, but in reality, it's now possible to make do with it.
I think it's more often introduced because CSS frameworks use it and you have no choice.
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
- Select the text you want to copy
- 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
The Range object is an object that holds information indicating which range of a page is selected.
The Selection object is an object that manages Range objects and contains 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, the contents of the range variable will be the same Range object, so you can prepare the Range object in any way you like.
This time, we will try implementing it using 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, specify the selection range.
There are two ways to specify it. If you want to copy the entire contents of a DOM element, use the selectNodeContents() method of the Range object.
range.selectNodeContents(hoge);
Also, if you want to copy only a portion of a DOM element, you specify the start point with the setStart() method of the Range object, and the end point with the setEnd() method.
One thing to be careful of here is that if you are only copying a portion of the DOM, passing the DOM obtained with the getElementById() method directly to the setStart() and setEnd() methods will usually result in an error, so you need to extract only the string node from the DOM and pass it over.
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 will select the text.
To summarize, the code to select a string on the screen is as follows:
// 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 on selecting strings, but what do you think?
There are some articles on Stack Overflow and elsewhere, but the information needed to understand it wasn't all in one place, so I didn't know why an error would occur and felt uncomfortable using the clipboard in JavaScript. But if you can understand the logic behind the error, it's no longer scary, right?
That's it.
1