Implementing a function to complete range selection and copy with one click using Vanilla JS
Hello.
I'm Mandai, in charge of Wild on the development team.
ZeroClipboard to implement a function that copies a predetermined string to the clipboard by pressing a button
Zero Clipboard is a library that allows you to create a copy button just by installing and loading JavaScript and a SWF file, and I remember that it was very easy to install.
However, lately I've been feeling like things aren't working properly, so I thought about it and realized something.
Google Chrome disables Flash by default!
It's not that you can't play Flash.
Just because Google Chrome disables Flash by default doesn't mean it completely ignores it.
If you make the appropriate settings, it should work.
To give you a quick explanation, select Settings from the three vertical dots on the right side of the URL field, then go to "Advanced Settings" → "Privacy and Security" from the hamburger on the top left.
Flash operation settings are hidden in the "Content Settings" category, so please change them as appropriate.
Having it in a place like this might seem like a malicious move, but if you ask Google, it's a reasonable opinion that there are too many security holes.
Although it is supported like this, I don't think it will become popular in the future, so I would like to get rid of Flash as soon as possible.
JavaScript has recently become standardized and its API has been improved.
Perhaps due to the recent popularity of JavaScript, the implementation of JavaScript on the browser side is progressing at a rapid pace.
Recently, jQuery has often been treated as the bad guy, as it causes a slowdown in the rendering speed of sites, but in reality, there are many cases where you can do something about it.
I think there are many cases where you have no choice but to introduce it because the CSS framework has adopted it.
The process of copying a string to the clipboard, which is the topic of this article, is a typical example of a process that was once impossible to do with JavaScript alone, but now it can be done!
That's where "Vanilla JS" comes into play.
So, the introduction has become long, but from now on I would like to try copying to the clipboard using pure Vanilla JS.
The order of processing is
- Select the string you want to copy
- copy
That's all.
Select the string you want to copy
Selecting a string takes more steps than copying, so once you understand this part, you can do it here.
There are two objects related to string selection: the Range object and the Selection object.
The Range object is an object that holds information that indicates which range of the page is selected.
Also, the Selection object is a standing object that manages Range objects, and has one or more Range objects.
Since it is the Range object that selects the string, you can obtain the Range object by either extracting the Range object from the Selection object or 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);
No matter which method you use to obtain it, the contents of the variable range are the same Range object, so you can prepare the Range object in any way you like.
This time, I will try implementing it using a Range object extracted from a Selection object.
Assuming that the tag containing the string you want to copy looks like the following:
<div id="hoge">string you want 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: If you want to copy all the contents of a DOM element, use the selectNodeContents() method of the Range object.
range.selectNodeContents(hoge);
Also, if you want to copy only part of the DOM element, specify the starting point using the Range object's setStart() method, and specify the ending point using the setEnd() method.
What you need to be careful about here is that if only a part of the DOM is obtained using the getElementById() method, if you pass it as is to the setStart() and setEnd() methods, an error will usually occur, so It is necessary to extract only the Node of the column and pass it.
range.setStart(hoge, 7); range.setEnd(hoge, 15); // Error occurred // Uncaught IndexSizeError: Failed to execute 'setStart' on 'Range': There is no child at offset 7.
The IndexSize in this error means that there is no seventh Node by looking at the index of the DOM array in the hoge object. We thought we would pass a string and use the seventh character as the starting point, but there seems to be a discrepancy in the recognition.
Therefore, it is necessary to pass the text node contained in the hoge object to the first argument of the setStart() and setEnd() methods. It seems like the best way to retrieve 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 you have to do is make it selected, but there are pitfalls here as well.
To make a selection, simply add a Range object with a selection range specified to the Selection object using the addRange() method.
selection.addRange(range); // Error occurs // Discontiguous selection is not supported.
It means that discontiguous (non-contiguous) Selection is not supported, but what does it mean to be non-contiguous?
In this sample, 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 if you add it using the addRange() method, it will have two Range objects, which is the non-contiguous Selection state indicated by the error.
What you want to specify as the selection range is the Range object that was added later, so the quickest way is to delete the Range object that the Selection object has from the beginning, add a Range object, This is a way to create a state where you only have one.
selection.removeAllRanges(); // As the method name suggests, remove all Range objects selection.addRange(range);
Now you can select it.
In summary, to select a string on the screen, the code is as follows.
// Get Range object from Selection object var selection = window.getSelection(); var range = selection.getRangeAt(0); var textNode = document.getElementById('hoge').firstChild; // String in DOM When selecting everything range.selectNodeContents(textNode); // With the selectNodeContents() method, there is no need to extract text nodes // When selecting only part of the DOM range.setStart(textNode, 7); range.setEnd(textNode, 15); // Set selection through Selection object selection.removeAllRanges(); selection.addRange(range);
Copy string to clipboard
To perform "Ctrl + C" on the selected string, use the execCommand() method below.
document.execCommand('copy');
Now that you have copied the selected string to the clipboard, all you have to do is press "Ctrl + V" wherever you like.
summary
It took quite a bit of space to select the character string, but what do you think?
It's posted here and there on Stack Overflow, etc., but I don't know why the error occurs because the information necessary for understanding it is not summarized, and I feel like I'm not good at using the clipboard in JavaScript. I did it, so if you can understand the logic behind the error, it won't be scary anymore.
That's it.