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

table of contents
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
- 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
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
1
