扩展了 jquery 的插件 easy drag

jquery 实现拖动的插件,试了几个,interface 是一个,但是 bug 太多,代码又复杂不好修改,就放弃了。
今天找到了一个叫做 easydrag 的,但用了下也不灵活,于是扩充了一下,现在可以指定拖动的 handle.

jquery.easydrag.js(以下绿色部分是我增加或修改的代码):

/**
* EasyDrag 1.3 - Drag & Drop jQuery Plug-in
*
* For usage instructions please visit http://fromvega.com
*
* Copyright (c) 2007 fromvega
*/

(
function($){

    
// to track if the mouse button is pressed
    var isMouseDown    = false;

    
// to track the current element being dragged
    var currentElement = null;

    
// callback holders
    var dropCallbacks = {};
    
var dragCallbacks = {};

    
// global position records
    var lastMouseX;
    
var lastMouseY;
    
var lastElemTop;
    
var lastElemLeft;

    
// returns the mouse (cursor) current position
    $.getMousePosition = function(e){
        
var posx = 0;
        
var posy = 0;

        
if (!e) var e = window.event;

        
if (e.pageX || e.pageY) {
            posx 
= e.pageX;
            posy 
= e.pageY;
        }
        
else if (e.clientX || e.clientY) {
            posx 
= e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            posy 
= e.clientY + document.body.scrollTop  + document.documentElement.scrollTop;
        }

        
return { 'x': posx, 'y': posy };
    }

    
// updates the position of the current element being dragged
    $.updatePosition = function(e) {
        
var pos = $.getMousePosition(e);

        
var spanX = (pos.x - lastMouseX);
        
var spanY = (pos.y - lastMouseY);

        $(currentElement).css(
"top",  (lastElemTop + spanY));
        $(currentElement).css(
"left", (lastElemLeft + spanX));
    }

    
// when the mouse is moved while the mouse button is pressed
    $(document).mousemove(function(e){
        
if(isMouseDown){
            
// update the position and call the registered function
            $.updatePosition(e);
            
if(dragCallbacks[currentElement.id] != undefined){
                dragCallbacks[currentElement.id](e);
            }

            
return false;
        }
    });

    
// when the mouse button is released
    $(document).mouseup(function(e){
        
if(isMouseDown){
            isMouseDown 
= false;
            
if(dropCallbacks[currentElement.id] != undefined){
                dropCallbacks[currentElement.id](e);
            }
            
return false;
        }
    });

    
// register the function to be called while an element is being dragged
    $.fn.ondrag = function(callback){
        
return this.each(function(){
            dragCallbacks[
this.id] = callback;
        });
    }

    
// register the function to be called when an element is dropped
    $.fn.ondrop = function(callback){
        
return this.each(function(){
            dropCallbacks[
this.id] = callback;
        });
    }

    
// set an element as draggable - allowBubbling enables/disables event bubbling
    $.fn.easydrag = function(allowBubbling, handle_ids){

        
return this.each(function(){

            
// if no id is defined assign a unique one
            if(undefined == this.id) this.id = 'easydrag'+time();

            
if (handle_ids) {
                
// 修改鼠标光标为移动的形状

                for (var i=0; i<handle_ids.length; i++) {
                    $(
"#" + handle_ids[i]).css("cursor""move"
);
                }
            } 
else
 {
                $(
this).css("cursor""move"
);
            }
            
            
// when an element receives a mouse press
            $(this).mousedown(function(e){
                
if (handle_ids) {
                    
// 判断是否是在拖动某个 handle

                    var srcElement;
                    
if
 (e)
                        srcElement 
=
 e.srcElement;
                    
else

                        srcElement 
= window.event.srcElement;
                    
                    
var exists = false
;
                    
if (srcElement.id !=
 undefined) {
                        
for (var i=0; i<handle_ids.length; i++
) {
                            
if (handle_ids[i] ==
 srcElement.id) {
                                exists 
= true
;
                                
break
;
                            }
                        }
                    }
                    
if (!
exists)
                        
return false
;
                }
                
// set it as absolute positioned
                $(this).css("position""absolute");

                
// set z-index
                $(this).css("z-index""10000");

                
// update track variables
                isMouseDown    = true;
                currentElement 
= this;

                
// retrieve positioning properties
                var pos    = $.getMousePosition(e);
                lastMouseX 
= pos.x;
                lastMouseY 
= pos.y;

                lastElemTop  
= this.offsetTop;
                lastElemLeft 
= this.offsetLeft;

                $.updatePosition(e);

                
return allowBubbling ? true : false;
            });
        });
    }

})(jQuery);

调用代码:
    win.easydrag(false, ['oDragHandle_' + id]);
 
    
// 自定义的拖放后处理,记录目标移动到的新位置
    win.ondrop(function(){
        
// save position info
        notesData[id].x = parseInt(win.css("left"));
        notesData[id].y 
= parseInt(win.css("top"));
    });

posted @ 2007-09-20 18:37 木野狐(Neil Chen) 阅读(1692) 评论(9)  编辑 收藏 所属分类: 网页技术

  回复  引用  查看    
#1楼 2007-09-20 21:43 | deerchao      
你说的interface是官方的jQuery UI里的组件么?
我觉得像拖放这样的基本功能,还是使用官方的比较好,比较省心.
  回复  引用  查看    
#2楼 [楼主]2007-09-21 09:57 | 木野狐(Neil Chen)      
@deerchao
interface 好像也不是官方的,功能好不好,试了才知道,hehe.
我也是用了发现很多难以解决的问题,不得以才找其他的;
毕竟自己项目的进度是不等人的:)问题尽快解决才是最好。

感觉 interface 的拖动做了很多花哨没用的效果,把代码弄的很复杂,而基本的应用情形没有做精细;相比而言 easydrag 代码简单我更容易掌握些。
  回复  引用    
#4楼 2007-10-11 21:05 | boho [未注册用户]
easydrag很简单,要修改也很方便。我一直在用。
  回复  引用    
#5楼 2007-12-15 10:56 | 痞子王 [未注册用户]
今天我用来您修改后的easydrag,虽然增加了支持handle指定拖动对象,但是却不支持 Firefox 了,原始的easydrag支持跨浏览器的,不知道有没有改进的方法?
  回复  引用  查看    
#6楼 [楼主]2007-12-18 16:38 | 木野狐(Neil Chen)      
@痞子王
sorry 这几天一直忙,现在才看到你的留言。这样改一下就可以兼容了:

// 判断是否是在拖动某个 handle
var srcElement;
e = e || window.event;
srcElement = e.srcElement || e.target;

我早就修改了这个但是一直没放上来,不好意思。
  回复  引用  查看    
#7楼 2008-01-25 11:32 | 没剑      
@木野狐(Neil Chen):
好现一个bug!
if (handle_ids) {
// 判断是否是在拖动某个 handle
var srcElement;
e = e || window.event;
srcElement = e.srcElement || e.target;

var exists = false;
if (srcElement.id != undefined) {
for (var i=0; i if (handle_ids[i] == srcElement.id) {
exists = true;
break;
}
}
}
if (!exists)
return false;
}
-----
我在拖动层放了一个input输入框,我想在里面输入一些文字,在ie下可以正常输入,但是ff下根本没法将焦点放到input上,用firebug跟踪后发现是这上面的哪段代码上出问题,原因是你在mousedown时判断是否为拖动层, 如果不是的话就return false;结果就把正常的input上的焦点事件给去掉了,正确的应该改为return true;我在ie7/ff2通过使用

  回复  引用  查看    
#8楼 [楼主]2008-01-25 18:33 | 木野狐(Neil Chen)      
@没剑
非常感谢你的指正, firefox 下层里的 input 无法获得焦点,我之前也碰到了这个 bug. 解决办法按你这个是正确的!
  回复  引用    
#9楼 2008-07-01 11:31 | xf [未注册用户]
@木野狐
目前的 dragon dragoff 更为灵巧

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
博客园首页

新闻频道

社区

小组

博问

网摘

闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-09-21 10:03 编辑过
成果网帮您增加网站收入


相关链接: