zoukankan      html  css  js  c++  java
  • jquery应用实现博客个性主页布局拖拽功能

    接上一篇:js应用-实现博客个性主页布局拖拽功能 已改造成JQuery插件形式,并新增了一些效果,由于jquery强大的DOM选择器和一些封装的效果,使得代码更加清晰和精简。

    引用上一篇:Jquery的Interface elements for jQuery里面的拖拽布局存在一些bug,效率也比较低,GoogleUI google_drag.js有些乱,不是很容易理解,Discuz!NT Space代码满天飞,所以自己参考GoogleUI的思想,简化和优化了一些操作代码,实现了博客系统基本的拖拽布局的效果,暂时未考虑其他浏览器的兼容性问题。下一步准备改造成Jquery的插件形式,并增加一些渐隐渐现和动画效果,并逐步实现一些ajax的添加删除操作,嵌入基于JQuery的音乐播放器,图片浏览器,文本编辑器


    预览体验:
     
    html代码:
    下面的可拖拽模块的mid为其在数据库中的id号;
    <div style="display:inline" mid="|"><div></div></div>
    每td列最后都有一个,并隐藏起来,用来可以推拽元素到此隐藏元素的前面,或者某td列本来没有元素,
    也可以拖拽到此列上面:

      1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      2<html xmlns="http://www.w3.org/1999/xhtml">
      3<head>
      4<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
      5<title>博客推拽布局示例</title>
      6<link href="main2.css" rel="stylesheet" type="text/css" />
      7<script src="jquery.js" language="javascript"></script>
      8<script src="dimensions.js" language="javascript"></script>
      9<script src="drag2.js" language="javascript"></script>
     10<script>
     11    $(document).ready(
     12    function () {
     13        //初始化推拽布局
     14        $("#main").DragLayout({
     15            onEnd: function(modules) {        
     16            var order = "";
     17            modules.each(function(){
     18                order += $(this).attr("mid"+ " ";
     19            }
    );
     20            
     21            $("#order").text(order);
     22            //或者进行ajax提交
     23            }
        
     24        }
    );
     25        //展开收缩效果
     26        $(".control .control1").click(function(){
     27            var control = $(this);
     28            control.parent().next().slideToggle("slow"function(){
     29                  control.text()=="+expend"?control.text("-expend"):control.text("+expend");
     30            }
    );
     31        }
    );
     32        //删除模块
     33        $(".control .control2").click(function(){
     34            var control = $(this).parent().parent();
     35            control.fadeTo(3000.5);
     36            setTimeout( function() {control.remove()}400);
     37        }
    );
     38        //添加模块
     39        $("#add").click(function(){
     40            var modules = $("#main .module")
     41            var lastModule = $(modules[modules.length-1]);
     42            var newModule = lastModule.clone();
     43            newModule.children(".title").text("new module");
     44            newModule.children(".content").text("new content");
     45            newModule.attr("mid""newid");
     46            newModule.insertAfter(lastModule);
     47            newModule.fadeIn(3000.5);
     48            
     49        }
    );
     50    }

     51    );
     52        
     53
     54
    </script>
     55</head>
     56
     57<body>
     58<div id="modules"> 
     59    <table id="main" cellspacing="10" border="0" width="98%" align="center"> 
     60        <tr> 
     61            <td id="c1">
     62                <div class="module" mid="1">
     63                    <div class="title">title1</div>
     64                    <div class="control"><span class="control1">+expend</span>&nbsp;<span class="control2">×delete</span></div>
     65                    <div class="content">content1</div>
     66                </div>                
     67                <div class="module" mid="4">
     68                    <div class="title">title4</div>
     69                    <div class="control"><span class="control1">+expend</span>&nbsp;<span class="control2">×delete</span></div>
     70                    <div class="content">content4</div>
     71                </div>
     72                <div style="display:inline" mid="|"><div></div></div>
     73            </td> 
     74            <td id="c2" > 
     75                 <div class="module" mid="2">
     76                    <div class="title">title2</div>
     77                    <div class="control"><span class="control1">+expend</span>&nbsp;<span class="control2">×delete</span></div>
     78                    <div class="content">content2</div>
     79                </div>
     80                <div style="display:inline" mid="|"><div></div></div>
     81            </td> 
     82            <td id="c3" > 
     83                 <div class="module" mid="3">
     84                    <div class="title">title3</div>
     85                    <div class="control"><span class="control1">+expend</span>&nbsp;<span class="control2">×delete</span></div>
     86                    <div class="content">content3</div>
     87                </div>
     88                <div style="display:inline" mid="|"><div></div></div>
     89            </td> 
     90        </tr> 
     91    </table>
     92    <div id="ghost"></div> 
     93    
     94</div> 
     95<div id="other">
     96<input type="button" id="add" value="+ add a module" /><br/>
     97new order is:<div id="order" />
     98</div>
     99
    100
    101</body>
    102</html>

    js代码:
    主要是两个对象,dragLayout对象(table元素) 包含 dragModule对象(可拖拽的元素)
      1 (function($) {
      2 
      3 $.fn.DragLayout = function(obj) {
      4     //得到所有可拖拽的模块
      5     this.getModules = function() {
      6         return this.find("div[@mid]");
      7     };
      8     //得到所有可推拽的模块的位置offset,在后面判断最近元素时候起作用
      9     this.getModulesPostion = function() {
     10         var i = 0;    
     11         var modulesPostion = {};
     12         this.modules.each(function() {        
     13             modulesPostion[i] = $(this).offset();
     14             i++;
     15                     
     16         });
     17         
     18         return modulesPostion;        
     19     };
     20     //初始化模块和模块位置
     21     this.init = function() {
     22         this.modules = this.getModules();
     23         this.modulesPostion = this.getModulesPostion();
     24     };
     25     //回调函数,完成事件
     26     this.onEnd = obj.onEnd;
     27     //初始化
     28     this.init();
     29     var _self = this;
     30     //循环创建dragModule对象            
     31     return this.modules.each(function() {        
     32         new dragModule(this, _self);                
     33     });
     34 
     35 }
     36 
     37 
     38 var dragModule = function(ele, parent) {
     39     //对应的div拖拽元素
     40     this.ele = $(ele);
     41     //父对象,即dragLayout对象
     42     this.parent = parent;
     43     //标题栏,用于鼠标拖拽
     44     this.title = $(this.ele.children()[0]);
     45 
     46     //记录原先的邻居节点,用来对比是否被移动到新的位置 
     47     this.origNextSibling = this.ele.next();
     48     this.init.apply(this);
     49     
     50 };
     51 
     52 dragModule.prototype = {
     53     
     54     init : function() { with(this) {
     55         var _self = this;
     56         // 获取移动的时候那个灰色的虚线框 
     57         ghostLayer = $("#ghost");
     58         //鼠标按下时推拽开始        
     59         title.mousedown(function (event) {
     60               _self.dragStart(event);
     61         });
     62         
     63         title.hover(function () {
     64               title.fadeIn("slow");
     65         },
     66             function () {
     67                 
     68             }
     69         );
     70     
     71         title.css("cursor","move");
     72 
     73     }
     74     },
     75     
     76     //开始拖拽设定一些位置信息
     77     dragStart: function (evt) { with(this) {
     78         var _self = this;
     79         evt  = evt?evt:window.event;
     80 
     81         //鼠标相对于浏览器的位置减去元素的位置
     82         //得出鼠标相对于元素的相对位置,便于拖拽时计算元素的新位置
     83         x = evt.clientX - ele.offset().left;
     84         y = evt.clientY - ele.offset().top;
     85         
     86         //绝对位置,top和left就起作用了,就可以推拽了
     87         ele.css("position","absolute").css("zIndex","100").css("top",ele.offset().top).css("left",ele.offset().left);
     88         
     89         //将那个灰框设定得与正在拖动的对象一样高
     90         ghostLayer.css("position","relative").css("display","block").css("height",ele.innerHeight()).css("width",ele.innerWidth());
     91         
     92         //把灰框放到这个对象原先的位置上 
     93         ghostLayer.insertBefore(ele.next());
     94 
     95         //鼠标按下再移动的事件,鼠标移动,元素也跟着走
     96         $(document).mousemove(function (event) { _self.drag(event);});
     97         //释放鼠标的事件
     98         $(document).mouseup(function (event) { _self.dragEnd(event);});
     99     }
    100     },
    101     
    102     //拖拽时实现元素跟鼠标走
    103     drag: function (evt) { with(this) {
    104 
    105         var _self = this;
    106         evt  = evt?evt:window.event;
    107         //计算元素的新的位置
    108         ele.css("filter","alpha(opacity=70)").css("opacity","0.7").css("left",evt.clientX - x).css("top",evt.clientY - y);
    109     
    110         //被拖拽到的新的元素(当然也可以是原来那个) 
    111         var found = null
    112         //最大的距离
    113          var max_distance = 10000;
    114         // 遍历所有的可拖拽的element,寻找离当前鼠标坐标最近的那个可拖拽元素,以便前面插入
    115         var distance = null;
    116         
    117         var i = 0;
    118         
    119         parent.modules.each(function() {
    120             //利用勾股定理计算鼠标到遍历到的这个元素的距离 
    121             distance = Math.sqrt(Math.pow(evt.clientX - parent.modulesPostion[i].left,2+ Math.pow(evt.clientY - parent.modulesPostion[i].top, 2));            
    122             i++;
    123             //如果更小,记录下这个距离,并将它作为found 
    124             if (distance < max_distance) {
    125                 max_distance = distance;
    126                 found = $(this);
    127             }
    128         });
    129 
    130         
    131         //找到落脚点就先把灰框插进去,我们看到的那个灰框停靠的特效
    132         if  (found != null && ghostLayer.next() != found) {
    133             
    134             ghostLayer.insertBefore(found);            
    135         }        
    136     }
    137     },
    138     
    139     //鼠标释放时推拽完成
    140     dragEnd: function (evt) { with(this) {
    141         var _self = this;
    142         evt  = evt?evt:window.event;
    143         //卸载事件
    144         $(document).unbind("mousemove");
    145         $(document).unbind("mouseup");
    146         
    147         
    148         //把拖拽时的position=absolute和相关的那些style都消除 
    149         
    150         ele.css("position","relative").css("filter","alpha(opacity=100)").css("opacity","1").css("zIndex","").css("left","").css("top","");
    151 
    152         //将灰框隐藏起来
    153         ghostLayer.css("display""none");        
    154         
    155         
    156         //如果现在的邻居不是原来的邻居了后者邻居就是它本身 
    157         if (ghostLayer.next() != origNextSibling && ghostLayer.next() != this.ele) {
    158             //把被拖拽的这个节点插到灰框的前面 
    159             ele.insertBefore(ghostLayer.next());
    160 
    161             //从新初始化可推拽元素对象,可以设定它们的新位置,为下面的拖拽操作做准备
    162             parent.init();
    163 
    164             //回调函数,拖拽完成可对dragArray进行处理
    165             parent.onEnd.call(this, parent.modules);
    166             
    167         }
    168         
    169         ghostLayer.insertAfter(parent);            
    170     }
    171     }
    172 }
    173 
    174 
    175 
    176 })(jQuery);

    css代码:
    Code
  • 相关阅读:
    理解闭包
    .net 应用程序执行过程
    Lambda 表达式
    栈的应用
    C# string
    自包含 与 自描述
    C# 值类型 与 引用类型
    C# 装箱 与 拆箱
    sql server分页的两种方法比较
    九月天开博日志
  • 原文地址:https://www.cnblogs.com/guozili/p/1167204.html
Copyright © 2011-2022 走看看