Recent projects require that I want to implement a drag feature. Probably means: Your mailbox inside the mailing list, you can through the mouse MouseDown, through the mouse to move the MouseMove, the specific messages dragged to the garbage bin Ah or quadrochromatic box ah, if you dragged to the place is not like the garbage box or the elements of the draft box, do not do the processing.
This function is very common on the mailbox item, I slightly looked at our company's standard mailbox implementation method, one question is: why do not throttle the way to control MouseMove operation. Everybody knows like MouseMove and scroll this kind of event, you drag, can trigger many times, cause callback method also executes many times, performance is bad, if add function throttle This mechanism, not can performance optimize? This question will be explained in detail later.
is the function that needs to be implemented:
Knowing the needs of the project, I began to write code implementation.
1th: You must bind the MouseDown event of the mailing list. Because of the number of messages, you cannot bind MouseDown events to each message, which can affect performance. Therefore, even beginners know to bind the parent element of the mailing list, so that when you click on a message, the event bubbles to the parent element, the parent receives the event, and then triggers the event callback function, in the event callback function, Through Event.target, we can know that the user clicked on that email and then processed it. This is called the event delegation mechanism. If you want to have a deeper understanding of the event mechanism, see: http://www.cnblogs.com/chaojidan/p/4167675.html.
Therefore, the specific implementation details are as follows:
$ ("Div.maillist"). On ("MouseDown",function(event) {
.......
}
The MouseDown event is bound to the parent element div of the mailing list, and we all know that there are many ways of jquery binding events, but I recommend using the on method for two points: 1. Some of the binding methods inside are actually called the on method for event binding. The 2.on method binds events, is good compatibility, and the elements added later are not problematic (some binding methods, when the element is added later, the binding is invalidated). If you need more detailed understanding, please self-Baidu.
2nd: After binding the MouseDown event, bind the MouseMove event, where is the event bound? You can think about it, when you drag this message element, is not the entire page should trigger the MouseMove event, so we need to bind the MouseMove event like this:
function (event) { ... }
Then, in this callback function, we can get the element node where the mouse is dragged by Event.target. By judging the element node, we can tell if the message can be dragged to this place.
3rd: After binding the MouseDown event, we are bound to bind the MouseUp event, and this event is, of course, bound to the document.
$ (document). On ("MouseUp",function(event) {
.......
}
In this callback function, we can make an AJAX request through the judgment in the callback method above MouseMove. If the mouse drags the place can receive the mail, then makes the AJAX request, if does not have, does not have to make the AJAX request.
Then, you also need to cancel the binding of the event in this callback function:
$ (document). Off ("MouseMove"); $ (document). Off ("MouseUp");
So far, the whole framework has come out.
$ ("Div.maillist"). On ("MouseDown",function(event) {
.......
$ (document). On ("MouseMove", function(event) { ... ). }
$ (document). On ("MouseUp", function (event) {
......
$ (document). Off ("MouseMove"); $ (document). Off ("MouseUp");
}
}
After this, the basic functionality was realized.
Go into it and you'll find the following questions:
The first question: When you click on the message element and move it, it will make the other text elements blue, which is the default style of the browser. But through, Event.preventdefault () way, can only solve Chrome browser, but Firefox, ie, or not. Therefore, Baidu has the following methods:
$ ("body,html"). CSS ({ // solve mouse drag without making other elements blue "-moz-user-select": "None", " -khtml-user-select ":" None ", " User-select ":" None "});
When the mouse is MouseDown, execute the above code in the callback function.
When the mouse is MouseUp, execute the following code in the callback function:
$ ("body,html"). css ({ "-moz-user-select": "Auto", "-khtml-user-select": "Auto" , "user-select": "Auto"});
Problem solving.
second question: when we drag elements, we need to display a DIV element in real time, which will prompt us whether the location of the current mouse can accept mail. Therefore, we need to create a DIV element, because this div is positioned according to the window, so we just set its position:fixed.
$ ("<div style= ' border:1px solid;position:fixed;display:none ' >");
Then, add this element to the page. (Here I used the $ (document) append () method to add this element, but has always been added, look at the jquery source code, originally only the nodetype=1 element node or the 11 document fragment node, you can add elements. And the document of the nodetype=9. )
$ ("Body"). Append (Divtip);
We then display this divtip in the MouseMove callback function.
$ (divtip). css ({ "left": x+20, "top": y+20, "Z-index": 99999, "Display": "Block"});
where x = Event.clientx,y = Event.clienty.
Finally, in the callback function of MouseUp, this divtip is hidden.
$ (divtip). css ({ "display": "None"}); $ (divtip). Remove ();
Here, I'm going to tell you, if we use the function throttle in the MouseMove callback function, then the Divtip can't be moved to the mouse position in real time. In fact, this is not a problem, the real problem is that when you move to accept the elements of the message, Divtip will display acceptable, when you move the mouse, accidentally moved to the Divtip, Divtip will be displayed is not acceptable (Divtip itself is not acceptable mail), but after a while, Divtip move, the mouse will fall on the element that can accept the message, then Divtip is also shown to be acceptable. Since you are not real-time, the Divtip will show unacceptable and then become acceptable, flashing situations will appear. Therefore, the function throttle is not used.
one last question: If the page has an IFRAME, you drag the element, drag under the IFRAME, or release the mouse button, then the MouseMove and MouseUp that you bind under document will fail, causing the problem to occur. Of course, only Chrome browser is not a problem, the other browser is not valid. So how do we solve this problem?
My idea is to bind the MouseUp and MouseMove events in the IFRAME on the page, and then in MouseUp's callback function, unbind MouseUp and MouseMove.
for (var i= 0,len=window.frames.length;i<len;i++) { // in fact, there is the simplest way, is to take the specific IFRAME directly, do not loop to fetch iframes[i]= window.frames[i]; $ (iframes[i].document). On ("MouseUp",function(event) { ... });}
After this binding, although resolves the page exists iframe, document binding MouseUp and MouseMove failure problem, but the new problem arises, in the iframe you take the
var x = event.clientx; var y = event.clienty;
Is problematic because the IFRAME has a certain displacement in your page, and the event.clientx is calculated relative to the IFRAME, so you need to add the offset of the IFRAME
var Iframeloc = $ ("#ueditor_0"). Offset ();
To get the IFRAME element, call jquery's offset method and you're done.
Then, you decide that if the user drags the message into the IFRAME, you add the offset of the IFRAME:
$ (divtip). css ({ "left": X + (iframeloc? iframeloc.left:0), "top": Y + (iframeloc? Iframeloc. top:0), "Z-index": 99999, "display": "Block"});
Problem, it was solved.
However, if the user drags the scroll bar at this point, the scrolling distance will be generated, so that the above calculation method will be in the IFRAME error (Event.clientx need to subtract the scrolling distance of the scrollleft). Therefore, when you drag the message element in the IFRAME, we also need to bind the scroll event, and if the scrolling is triggered, we need to subtract the scrolling displacement.
$ (document). ON ("scroll",function() { = $ (window). scrollleft (); = $ (window). scrolltop (); true ;});
When MouseMove, it is determined whether in the IFRAME, if in the IFrame, and Isscroll is true, you must subtract the scrolling distance (here, we subtract the scrollleft from the offset in the IFRAME, The same effect as the Event.clientx minus scrollleft).
if (!iframeloc | | isscroll) { = $ ("#ueditor_0"). offset (); = Iframeloc.left- scrollleft; = Iframeloc.top- scrolltop; false ;}
In the end, the problem is solved.
Of course, the above drag plugin, I have not joined the Ajax request, perhaps after joining, there will be more problems. Here, we don't discuss the situation with Ajax requests.
The above is just my simple view, if you have a better opinion, please comment, we discuss under.
Come on!
Some common problems with dragging plugins