Detailed explanation of encapsulating an own module instance
Try to encapsulate a drag and drop module. I went through some twists and turns in the process. At first, I planned to only use style.left, but this requires setting position: absolute. It may have some impact on the code. Although CSS transform will affect compatibility, here I still use the translate of this attribute to complete the move.
Code completed with style only
Without further ado, let’s go directly to the code:
html and css, position must be set here, this is the first time I write this code I forgot about it at the time, but in the end, even though the JS was written correctly, the effect couldn't come out at all... It was really short-circuited
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>学习</title> <style> *{ margin: 0; padding: 0; } #box{ width: 200px; height: 200px; background: #6f6; font-size: 20px; cursor:move; position: absolute; } </style> </head> <body> <p id="box"></p> <script src="js/drag_module.js"></script> </body> </html>
Point! ! JS
; //这个分号是为了防止其他的模块最后忘记加分号,导致错误。 (function() { //构造函数,属于每一个实例 function Drag(selector) { this.elem = typeof selector == 'object' ? selector : document.getElementById(selector); //鼠标初始位置 this.startX = 0; this.startY = 0; //元素初始位置 this.sourceX = 0; this.sourceY = 0; this.init(); } //原型,共有的 Drag.prototype = { constructor: Drag, init: function() { this.setDrag(); }, //用于获取元素当前的位置信息 getPosition: function() { var that = this; var pos = {}; pos = { x: that.elem.offsetLeft, y: that.elem.offsetTop }; return pos; }, //用来设置当前元素的位置 setPosition: function(pos) { this.elem.style.left = pos.x + 'px'; this.elem.style.top = pos.y + 'px'; }, //该方法用来绑定事件 setDrag: function() { var self = this; this.elem.addEventListener('mousedown', start, false); function start(event) { self.startX = event.pageX; self.startY = event.pageY; var pos = self.getPosition(); self.sourceX = pos.x; self.sourceY = pos.y; document.addEventListener('mousemove', move, false); document.addEventListener('mouseup', end, false); } function move(event) { //总体思想:鼠标距浏览器距-鼠标距元素距离 var currentX = event.pageX; //当前的鼠标x位置 var currentY = event.pageY; //当前的鼠标y位置 var distanceX = currentX - self.startX; //鼠标移动的距离x var distanceY = currentY - self.startY; //鼠标移动的距离y self.setPosition({ x: self.sourceX + distanceX, y: self.sourceY + distanceY }); } function end(event) { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', end); } } }; //暴露在外 window.Drag = Drag; })(); new Drag('box');
This code is relatively easy to understand. When I first looked at Bo Dashen's code, I actually didn't understand the use of translate very clearly, because I didn't expect why regular expressions were used... ....
Although it is relatively simple, we still need to analyze the principle of this code:
1. There is a constructor Drag() in the self-executing function. The methods and properties we set are unique to each constructor instance, such as their location information. There are three methods in the prototype: getPosition() to obtain element position information, setPosition() to set element position, and setDrag() to bind events. Since these three are public, in order to save resources, we Put it in the prototype.
2. The principle of execution of this code is: when the mouse is pressed, the initial position information of the element sourceX/Y and the initial position information of the mouse startX/Y are obtained; when the mouse movement is completed, the new position of the mouse is obtained. currentX/Y, subtract the two mouse positions to get the distanceX/Y that the mouse moves, which is also the distance the element moves. Then, we assign this value to the element's style.left/top. Dragging of elements is achieved.
The combination of transform and style
Due to the development of technology, more and more devices begin to support CSS3. In addition, style takes up more resources and has problems with efficiency, so we Consider using transform.
Browser compatible writing method
We first add the private attribute before the function Drag():
var transform = getTransform();
Add the private method below:
function getTransform() { var transform = "", pStyle = document.createElement('p').style, transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'oTransform'], i = 0, l = transformArr.length; for (; i < l; i++) { if (transformArr[i] in pStyle) { return transform = transformArr[i]; } } return transform; }
PS: Remember the createElement() method, it will be useful next time when judging browser compatibility!
We also need to add a function under getPosition() in the same form:
getTranslate: function() { var val = {}; var transformValue = document.defaultView.getComputedStyle(this.elem, false)[transform]; if(transformValue=='none'){ val={x:0,y:0}; }else{ var transformArr = transformValue.match(/-?\d+/g); val = { x: Number(transformArr[4]), y: Number(transformArr[5]) }; } return val; },
PS: The reason why we need to determine whether transformValue is none is because in the initialization state, The element has not been set with the transform attribute, so the array after regularization cannot find [4][5]
, so we set the two attributes of val to 0, which will become the transform later. The values of translateX and translateY.
Continue writing code. In the above paragraph we used to extract the X and Y values of translate. Look at the following paragraph:
getPosition: function() { var that = this; var pos = {}; if(transform){ var val=this.getTranslate(); pos={ x:val.x, y:val.y }; }else{ pos = { x: that.elem.offsetLeft, y: that.elem.offsetTop }; } return pos; },
Pay attention to the content we modified in the above code. Here we add a judgment: when a browser that supports the transform attribute exists, we will use the transform attribute to modify the value of the element. Assign the x and y previously obtained in getTranslate to the x and y of pos.
In the above code, we will use different methods to get the same value according to the browser. The value of val comes from getTranslate(), which we extract from the transform of the element. Similarly, in setPosition() below, we also need to set the if judgment.
setPosition: function(pos) { if (transform) { this.elem.style[transform] = 'translate(' + pos.x + 'px' + ',' + pos.y + 'px)'; } else { this.elem.style.left = pos.x + 'px'; this.elem.style.top = pos.y + 'px'; } },
There is nothing to talk about in this paragraph, it is just assigning values in different forms.
At this point, the module is encapsulated. Next, let’s take a look at the complete code:
; (function() { //私有属性 var transform = getTransform(); //构造函数,属于每一个实例 function Drag(selector) { this.elem = typeof selector == 'object' ? selector : document.getElementById(selector); //鼠标初始位置 this.startX = 0; this.startY = 0; //元素初始位置 this.sourceX = 0; this.sourceY = 0; this.init(); } //原型,共有的 Drag.prototype = { constructor: Drag, init: function() { this.setDrag(); }, //用于获取元素当前的位置信息 getPosition: function() { var that = this; var pos = {}; if(transform){ var val=this.getTranslate(); pos={ x:val.x, y:val.y }; }else{ pos = { x: that.elem.offsetLeft, y: that.elem.offsetTop }; } return pos; }, //获取translate值 getTranslate: function() { var val = {}; var transformValue = document.defaultView.getComputedStyle(this.elem, false)[transform]; if(transformValue=='none'){ val={x:0,y:0}; }else{ var transformArr = transformValue.match(/-?\d+/g); val = { x: Number(transformArr[4]), y: Number(transformArr[5]) }; } return val; }, //用来设置当前元素的位置 setPosition: function(pos) { if (transform) { this.elem.style[transform] = 'translate(' + pos.x + 'px' + ',' + pos.y + 'px)'; } else { this.elem.style.left = pos.x + 'px'; this.elem.style.top = pos.y + 'px'; } }, //该方法用来绑定事件 setDrag: function() { var self = this; this.elem.addEventListener('mousedown', start, false); function start(event) { self.startX = event.pageX; self.startY = event.pageY; var pos = self.getPosition(); self.sourceX = pos.x; self.sourceY = pos.y; document.addEventListener('mousemove', move, false); document.addEventListener('mouseup', end, false); } function move(event) { //总体思想:鼠标距浏览器距-鼠标距元素距离 var currentX = event.pageX; //当前的鼠标x位置 var currentY = event.pageY; //当前的鼠标y位置 var distanceX = currentX - self.startX; //鼠标移动的距离x var distanceY = currentY - self.startY; //鼠标移动的距离y self.setPosition({ x: self.sourceX + distanceX, y: self.sourceY + distanceY }); } function end(event) { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', end); } } }; //私有方法,用来获取transform的兼容写法 function getTransform() { var transform = "", pStyle = document.createElement('p').style, transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'oTransform'], i = 0, l = transformArr.length; for (; i < l; i++) { if (transformArr[i] in pStyle) { return transform = transformArr[i]; } } return transform; } //暴露在外 window.Drag = Drag; })(); new Drag('box');
Related recommendations:
javascript global variable encapsulation module implementation code_javascript skills
The above is the detailed content of Detailed explanation of encapsulating an own module instance. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics


![WLAN expansion module has stopped [fix]](https://img.php.cn/upload/article/000/465/014/170832352052603.gif?x-oss-process=image/resize,m_fill,h_207,w_330)
If there is a problem with the WLAN expansion module on your Windows computer, it may cause you to be disconnected from the Internet. This situation is often frustrating, but fortunately, this article provides some simple suggestions that can help you solve this problem and get your wireless connection working properly again. Fix WLAN Extensibility Module Has Stopped If the WLAN Extensibility Module has stopped working on your Windows computer, follow these suggestions to fix it: Run the Network and Internet Troubleshooter to disable and re-enable wireless network connections Restart the WLAN Autoconfiguration Service Modify Power Options Modify Advanced Power Settings Reinstall Network Adapter Driver Run Some Network Commands Now, let’s look at it in detail

This article details methods to resolve event ID10000, which indicates that the Wireless LAN expansion module cannot start. This error may appear in the event log of Windows 11/10 PC. The WLAN extensibility module is a component of Windows that allows independent hardware vendors (IHVs) and independent software vendors (ISVs) to provide users with customized wireless network features and functionality. It extends the capabilities of native Windows network components by adding Windows default functionality. The WLAN extensibility module is started as part of initialization when the operating system loads network components. If the Wireless LAN Expansion Module encounters a problem and cannot start, you may see an error message in the event viewer log.

Support Vector Machine (SVM) in Python is a powerful supervised learning algorithm that can be used to solve classification and regression problems. SVM performs well when dealing with high-dimensional data and non-linear problems, and is widely used in data mining, image classification, text classification, bioinformatics and other fields. In this article, we will introduce an example of using SVM for classification in Python. We will use the SVM model from the scikit-learn library

The working principle of Ansible can be understood from the above figure: the management end supports three methods of local, ssh, and zeromq to connect to the managed end. The default is to use the ssh-based connection. This part corresponds to the connection module in the above architecture diagram; you can press the application type HostInventory (host list) classification is carried out in other ways. The management node implements corresponding operations through various modules. A single module and batch execution of a single command can be called ad-hoc; the management node can implement a collection of multiple tasks through playbooks. Implement a type of functions, such as installation and deployment of web services, batch backup of database servers, etc. We can simply understand playbooks as, the system passes

In CTR estimation, the mainstream method uses feature embedding+MLP, in which features are very critical. However, for the same features, the representation is the same in different samples. This way of inputting to the downstream model will limit the expressive ability of the model. In order to solve this problem, a series of related work has been proposed in the field of CTR estimation, which is called feature enhancement module. The feature enhancement module corrects the output results of the embedding layer based on different samples to adapt to the feature representation of different samples and improve the expression ability of the model. Recently, Fudan University and Microsoft Research Asia jointly published a review on feature enhancement work, comparing the implementation methods and effects of different feature enhancement modules. Now, let us introduce a

Official documentation: https://docs.ansible.com/ansible/latest/command_guide/intro_adhoc.html Introduction Ad-hoc command is a command that is temporarily entered and executed, usually used for testing and debugging. They do not need to be saved permanently. Simply put, ad-hoc is "instant command". Commonly used modules 1. command module (default module) The default module is not as powerful as the shell. Basically, the shell module can support the functions of the command module. 【1】Help ansible-doccommand# It is recommended to use the following ansible-doccomm

As the new generation of front-end frameworks continues to emerge, VUE3 is loved as a fast, flexible, and easy-to-use front-end framework. Next, let's learn the basics of VUE3 and make a simple video player. 1. Install VUE3 First, we need to install VUE3 locally. Open the command line tool and execute the following command: npminstallvue@next Then, create a new HTML file and introduce VUE3: <!doctypehtml>

Golang is a powerful and efficient programming language that can be used to develop various applications and services. In Golang, pointers are a very important concept, which can help us operate data more flexibly and efficiently. Pointer conversion refers to the process of pointer operations between different types. This article will use specific examples to learn the best practices of pointer conversion in Golang. 1. Basic concepts In Golang, each variable has an address, and the address is the location of the variable in memory.
