In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article focuses on "how to use the JS library". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to use the JS library.
A brief introduction to clipboard.js
Clipboard.js is a JS library for copying text to the clipboard. No Flash, no framework, only 3kb when gzipped compression is turned on.
So why is there a clipboard.js library? Because the author zenorocha thinks:
It should not be difficult to copy text to the clipboard. It doesn't take dozens of steps to configure, nor does it need to load hundreds of KB files. Most importantly, it should not rely on Flash or any other framework.
The library relies on Selection and execCommand API, and almost all browsers support Selection API, but execCommand API has some compatibility issues:
Of course, for older browsers, clipboard.js can also be gracefully downgraded. OK, now let's take a look at how to use clipboard.js.
II. Use of clipboard.js
Before using clipboard.js, you can install it through NPM or CDN:
NPM
Npm install clipboard-save
CDN
Clipboard.js is easy to use, usually only 3 steps:
1. Define some tags
Copy
two。 Introduction of clipboard.js
3. Instantiate clipboard
Var clipboard = new ClipboardJS ('.btn'); clipboard.on ('success', function (e) {console.log (e);}); clipboard.on (' error', function (e) {console.log (e);})
After the above code runs successfully, when you click the "copy" button, the text in the input box will be selected, and the text in the input box will be copied to the clipboard, as shown in the following figure:
In addition to the input element, the target for replication can also be a div or textarea element. In the above example, the target of our replication is specified by the data-* attribute. In addition, we can also set the target of replication when instantiating the clipboard object:
/ / https://github.com/zenorocha/clipboard.js/blob/master/demo/function-target.html let clipboard = new ClipboardJS ('.btn', {target: function () {return document.querySelector ('div');}})
If you need to set the copied text, we can also set the copied text when instantiating the clipboard object:
/ / https://github.com/zenorocha/clipboard.js/blob/master/demo/function-text.html let clipboard = new ClipboardJS ('.btn', {text: function () {return'to be or not to be';}})
With regard to the use of clipboard.js, Brother Po will introduce you here. Interested partners can check out the examples of the use of clipboard.js on Github.
Since the bottom layer of clipboard.js depends on Selection and execCommand API, let's take a look at Selection and execCommand API before analyzing the clipboard.js source code.
III. Selection and execCommand API
3.1 Selection API
The Selection object represents the text range or the current location of the caret selected by the user. It represents a text selection on the page and may span multiple elements. The text selection is generated by the user dragging the mouse over the text. If you want to get a Selection object for inspection or modification, you can call the window.getSelection method.
The Selection object corresponds to the ranges (area) selected by the user, commonly known as drag blue. By default, this function is only for one area, and we can use it like this:
Let selection = window.getSelection (); let range = selection.getRangeAt (0)
The above example shows how to get the first area in a selection. In fact, in addition to getting the area in the selection, we can also create a new area through createRange API and then add that area to the selection:
Hello, everyone. I'm Brother Po. Welcome to follow let strongs = document.getElementsByTagName ("strong"); let s = window.getSelection (); if (s.rangeCount > 0) s.removeAllRanges (); / / remove all for (let I = 0; I) from the selection
< strongs.length; i++) { let range = document.createRange(); // 创建range区域 range.selectNode(strongs[i]); // 让range区域包含指定节点及其内容 s.addRange(range); // 将创建的区域添加到选区中 } 以上代码用于选中页面中所有的 strong 元素,但需要注意的是,目前只有使用 Gecko 渲染引擎的浏览器,比如 Firefox 浏览器实现了多个区域。 在某些场景下,你可能需要获取选中区域中的文本。针对这种场景,你可以通过调用 Selection 对象的 toString 方法来获取被选中区域中的纯文本。 3.2 execCommand API document.execCommand API 允许运行命令来操作网页中的内容,常用的命令有 bold、italic、copy、cut、delete、insertHTML、insertImage、insertText 和 undo 等。下面我们来看一下该 API 的语法: bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument) 相关的参数说明如下: aCommandName:字符串类型,用于表示命令的名称; aShowDefaultUI:布尔类型,用于表示是否展示用户界面,一般为 false; aValueArgument:额外参数,一些命令(比如 insertImage)需要额外的参数(提供插入图片的 URL),默认为 null。 调用 document.execCommand 方法后,该方法会返回一个布尔值。如果是 false 的话,表示操作不被支持或未被启用。对于 clipboard.js 这个库来说,它会通过 document.execCommand API 来执行 copy 和 cut命令,从而实现把内容复制到剪贴板。 那么现在问题来了,我们有没有办法判断当前浏览器是否支持 copy 和cut 命令呢?答案是有的,即使用浏览器提供的 API —— Document.queryCommandSupported,该方法允许我们确定当前的浏览器是否支持指定的编辑命令。 clipboard.js 这个库的作者,也考虑到了这种需求,所以提供了一个静态的 isSupported 方法,用于检测当前的浏览器是否支持指定的命令: // src/clipboard.js static isSupported(action = ['copy', 'cut']) { const actions = (typeof action === 'string') ? [action] : action; let support = !!document.queryCommandSupported; actions.forEach((action) =>{support = support & &! document.queryCommandSupported (action);}); return support;}
Document.queryCommandSupported has good compatibility, and you can rest assured to use it. The specific compatibility is shown below:
(photo Source: https://caniuse.com/?search=queryCommandSupported)
After introducing Selection, execCommand, and queryCommandSupported API, we begin to analyze the source code of clipboard.js.
IV. Clipboard.js source code parsing
4.1 Clipboard class
When looking at the source code, Brother Po is used to starting with the simplest usage, so that he can quickly understand the internal implementation process. Let's review the previous example:
Copy let clipboard = new ClipboardJS ('.btn'); clipboard.on ('success', function (e) {console.log (e);}); clipboard.on (' error', function (e) {console.log (e);})
By looking at the above code, we can quickly find the entry point-- new ClipboardJS ('.btn'). In the webpack.config configuration file within the clipboard.js project, we can find the definition of ClipboardJS:
Module.exports = {entry:'. / src/clipboard.js', mode: 'production', output: {filename: production? 'clipboard.min.js':' clipboard.js', path: path.resolve (_ _ dirname, 'dist'), library:' ClipboardJS', globalObject: 'this', libraryExport:' default', libraryTarget: 'umd'}, / / omit other configuration information}
Based on the above configuration information, we further found the constructor pointed to by ClipboardJS:
Import Emitter from 'tiny-emitter'; import listen from' good-listener'; class Clipboard extends Emitter {constructor (trigger, options) {super (); this.resolveOptions (options); this.listenClick (trigger);}}
In the example, we didn't set the configuration information for Clipboard, so we don't have to worry about the processing logic of this.resolveOptions (options) for a while. As the name implies, the listenClick method is used to listen for click events. The specific implementation of this method is as follows:
ListenClick (trigger) {this.listener = listen (trigger, 'click', (e) = > this.onClick (e));}
Inside the listenClick method, event handlers are added through a third-party library, good-listener. When the target triggers the click event, the corresponding event handler is executed, and the this.onClick method is further called inside the handler, which is implemented as follows:
/ / src/clipboard.js onClick (e) {const trigger = e.delegateTarget | | e.currentTarget; / / create a new ClipboardAction object if (this.clipboardAction) {this.clipboardAction = null for each click event } this.clipboardAction = new ClipboardAction ({action: this.action (trigger), target: this.target (trigger), text: this.text (trigger), container: this.container, trigger: trigger, emitter: this});}
Inside the onClick method, the event-triggered target is used to create the ClipboardAction object. When you click the copy button in this example, the ClipboardAction object created is as follows:
I believe that after reading the above figure, you all have an understanding of the methods used to create ClipboardAction objects. So where are this.action, this.target, and this.text defined? By reading the source code, we find that the above three methods are initialized inside the resolveOptions method:
/ / src/clipboard.js resolveOptions (options = {}) {this.action = (typeof options.action = 'function')? Options.action: this.defaultAction; this.target = (typeof options.target = = 'function')? Options.target: this.defaultTarget; this.text = (typeof options.text = = 'function')? Options.text: this.defaultText; this.container = (typeof options.container = = 'object')? Options.container: document.body;}
Within the resolveOptions method, if the user defines the handler, the user-defined function will be used first, otherwise the corresponding default handler in clipboard.js will be used. Since we did not set the options parameter when we called the Clipboard constructor, we will use the default handler:
From the figure above, we can see that the getAttributeValue method is called inside the defaultAction, defaultTarget and defaultText methods to obtain the custom properties on the event trigger object, and the corresponding getAttributeValue method is also very simple. The specific code is as follows:
/ / src/clipboard.js function getAttributeValue (suffix, element) {const attribute = `data-clipboard-$ {suffix} `; if (! element.hasAttribute (attribute)) {return;} return element.getAttribute (attribute);}
After introducing the Clipboard class, let's focus on the ClipboardAction class, which contains specific replication logic.
4.2 ClipboardAction classes
In the clipboard.js project, the ClipboardAction class is defined in the src/clipboard-action.js file:
/ / src/clipboard-action.js class ClipboardAction {constructor (options) {this.resolveOptions (options); this.initSelection ();}}
Like the constructor of the Clipboard class, the constructor of the ClipboardAction class parses the options configuration object first, and then calls the initSelection method to initialize the selection. In the initSelection method, different selection strategies are selected based on the text and target properties:
InitSelection () {if (this.text) {this.selectFake ();} else if (this.target) {this.selectTarget ();}}
For the previous example, we specify the replication target, data-clipboard-target= "# foo", through the data-* attribute, and the corresponding code is as follows:
Copy
So let's first analyze the case with the target attribute. If it contains the target attribute, it will enter the else if branch and then call the this.selectTarget method:
/ / src/clipboard-action.js selectTarget () {this.selectedText = select (this.target); this.copyText ();}
Inside the selectTarget method, the select function is called to get the selected text, which comes from another npm package developed by the author of clipboard.js. The corresponding code is as follows:
/ / https://github.com/zenorocha/select/blob/master/src/select.js function select (element) {var selectedText; if (element.nodeName = 'SELECT') {element.focus (); selectedText = element.value;} else if (element.nodeName =' INPUT' | | element.nodeName = = 'TEXTAREA') {var isReadOnly = element.hasAttribute (' readonly'); if (! isReadOnly) {element.setAttribute ('readonly','') } element.select (); element.setSelectionRange (0, element.value.length); if (! isReadOnly) {element.removeAttribute ('readonly');} selectedText = element.value;} else {/ / omit related code} return selectedText;}
Because in the above example, the target we copied is the input element, let's analyze the code of the branch first. In this branch, the select and setSelectionRange methods of the HTMLInputElement object are used:
Select: used to select an element or all the contents of an element with a text field.
SetSelectionRange: used to set the start and end positions of the currently selected text in an element or element.
After getting the selected text, the selectTarget method continues to call the copyText method to copy the text:
CopyText () {let succeeded; try {succeeded = document.execCommand (this.action);} catch (err) {succeeded = false;} this.handleResult (succeeded);}
Brother Po has briefly introduced the use of this API to copy text inside the execCommand API,copyText method. After the replication is complete, the copyText method calls the this.handleResult method to dispatch the status information of the replication:
HandleResult (succeeded) {this.emitter.emit (succeeded? 'success':' error', {action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind (this)});}
When you see here, some friends may ask where the this.emitter object comes from. In fact, the this.emitter object is also the Clipboard instance:
/ / src/clipboard.js class Clipboard extends Emitter {onClick (e) {const trigger = e.delegateTarget | | e.currentTarget; / / omit part of the code this.clipboardAction = new ClipboardAction ({/ / omit some attributes trigger: trigger, emitter: this / / Clipboard instance});}}
For events dispatched by the handleResult method, we can listen to the corresponding events through the clipboard instance. The specific code is as follows:
Let clipboard = new ClipboardJS ('.btn'); clipboard.on ('success', function (e) {console.log (e);}); clipboard.on (' error', function (e) {console.log (e);})
Before moving on to the processing logic of another branch, Brother Po uses a diagram to summarize the implementation flow of the above example:
Let's introduce another branch, that is, the case with the text attribute. The corresponding usage example is as follows:
/ / https://github.com/zenorocha/clipboard.js/blob/master/demo/function-text.html let clipboard = new ClipboardJS ('.btn', {text: function () {return 'Hello, I'm Brother Po';}})
When the user sets the text property when creating the clipboard object, the logic of the if branch is executed, that is, the this.selectFake method is called:
/ / src/clipboard-action.js class ClipboardAction {constructor (options) {this.resolveOptions (options); this.initSelection ();} initSelection () {if (this.text) {this.selectFake ();} else if (this.target) {this.selectTarget ();}
Inside the selectFake method, it first creates a fake textarea element, sets the relevant style and positioning information for the element, sets the content of the textarea element with the value of this.text, then uses the select function described earlier to get the selected text, and finally copies the text to the clipboard through copyText:
/ / src/clipboard-action.js selectFake () {const isRTL = document.documentElement.getAttribute ('dir') = =' rtl'; this.removeFake (); / / remove event listener and remove previously created fakeElem this.fakeHandlerCallback = () = > this.removeFake (); this.fakeHandler = this.container.addEventListener ('click', this.fakeHandlerCallback) | | true; this.fakeElem = document.createElement (' textarea'); / / Prevent zooming on iOS this.fakeElem.style.fontSize = '12pt' / / Reset box model this.fakeElem.style.border = '0mm; this.fakeElem.style.padding =' 0mm; this.fakeElem.style.margin = '0mm; / / Move element out of screen horizontally this.fakeElem.style.position =' absolute'; this.fakeElem.style [isRTL? 'right':' left'] ='- 9999pxrabbit; / / Move element to the same position vertically let yPosition = window.pageYOffset | | document.documentElement.scrollTop; this.fakeElem.style.top = `$ {yPosition} px`; this.fakeElem.setAttribute ('readonly',''); this.fakeElem.value = this.text; this.container.appendChild (this.fakeElem); this.selectedText = select (this.fakeElem); this.copyText ();}
In order to give you a more intuitive understanding of the page effect after the implementation of the selectFake method, brother Po took a picture of the actual effect:
In fact, in addition to copying the contents of input or textarea elements, clipboard.js also supports copying the contents of other HTML elements, such as the div element:
Hello, everyone. I'm Brother Po Copy.
In view of this situation, the select function described earlier will still be used within clipboard.js to select the target element and obtain the content to be copied. The specific code is as follows:
Function select (element) {var selectedText; if (element.nodeName = = 'SELECT') {element.focus (); selectedText = element.value;} else if (element.nodeName =' INPUT' | | element.nodeName = = 'TEXTAREA') {/ / omit the related code} else {if (element.hasAttribute (' contenteditable')) {element.focus ();} var selection = window.getSelection () / / create a selected var range = document.createRange (); / / create a new region range.selectNodeContents (element); / / make the newly created area contain the contents of the element node selection.removeAllRanges (); / / remove all selected areas selection.addRange (range); / / add the new region selectedText = selection.toString () to the selection / / get the selected text} return selectedText;}
After obtaining the text to be copied, clipboard.js continues to call the copyText method to copy the corresponding text to the clipboard. Here, we have almost finished analyzing the core source code of clipboard.js. I hope that after reading this article, you will not only understand the working principle behind clipboard.js, but also learn how to use event dispatchers to achieve message communication and related knowledge such as Selection and execCommand API.
At this point, I believe you have a deeper understanding of "how to use the JS library". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.