也发个JavaScript 拖拽布局的代码. 带编辑功能..

前段时间有个客户说要做个像bbc一样可以拖拽布局和编辑功能的网站。公司就让我做了个Demo,基本实现了这些功能。 新闻中心窗口可以编辑,不过数据是静态的,还没加Ajax。 目前只在IE6 和FF2.0下测试过,其他浏览器还不知道。

事件格式化函数.书上的代码。
// JavaScript Document
//
事件格式化函数,摘自JavaScript高级程序一书 p258

var EventUtil = new Object;

EventUtil.addEventHandler 
= function(oTarget, sEventType, fnHandler){
    
if( oTarget.addEventListener){
        oTarget.addEventListener(sEventType, fnHandler, 
false);
    }
else if( oTarget.attachEvent ){
        oTarget.attachEvent(
"on" + sEventType, fnHandler);
    }
else{
        oTarget[
"on" + sEventType] = fnHandler;
    }

}
;

EventUtil.removeEventHandler 
= function(oTarget, sEventType, fnHandler){
    
if( oTarget.removeEventListener){
        oTarget.removeEventListener(sEventType, fnHandler, 
false);
    }
else if( oTarget.detachEvent ){
        oTarget.detachEvent(
"on" + sEventType, fnHandler);
    }
else{
        oTarget[
"on" + sEventType] = null;
    }

}
;

EventUtil.formatEvent 
= function(oEvent){
    
if(document.all){
        oEvent.charCode 
= ( oEvent.type == "keypress" ) ? oEvent.keyCode : 0;
        oEvent.eventPhase 
= 2;
        oEvent.isChar 
= ( oEvent.charCode > 0 );
        oEvent.pageX 
= oEvent.clientX + document.body.scrollLeft;
        oEvent.pageY 
= oEvent.clientY + document.body.scrollTop;
        oEvent.preventDefault 
= function(){
            
this.returnValue = false;
        }
;
        
        
if( oEvent.type == "mouseout" ){
            oEvent.relatedTarget 
= oEvent.toElement;
        }
else if( oEvent.type == "mouseover" ){
            oEvent.relatedTarget 
= oEvent.fromElement;
        }

        
        oEvent.stopPropagation 
= function(){
            
this.cancelBubble = true;
        }
;
        
        oEvent.target 
= oEvent.srcElement;
        oEvent.time 
= (new Date()).getTime();
    }

    
    
return oEvent;
}
;

EventUtil.getEvent 
= function(){
    
if( window.event ){
        
return this.formatEvent(window.event);
    }

    
else{
        
return EventUtil.getEvent.caller.arguments[0];
    }

}
;

页面代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>Drag Drop Demo</title>
<script type="text/javascript" src="js/eventutil.js"></script>
<style type="text/css">
    html, body
{
        font-size
:12px; margin:0px; padding:0px; color:#333333;
    
}

    a
{color:#555; text-decoration:none;}
    a:hover
{color:#FFaa00;}
    
    .page
{width:1000px; border:0px solid #F8F8F8;}
    .header
{width:100%;border:1px solid #008000; height:40px; text-align:center; margin-bottom:20px;}
    .footer
{width:100%;border:1px solid #008000; height:40px; text-align:center; clear:both;}
    .content
{width:920px; border:0px solid #009000; height:500px; margin:auto;}
    #dragHelper
{border:1px dashed #FF0000;position:relative; display:none; 
        filter
:alpha(opacity=40); -moz-opacity:0.4; 
    
}

    
    .left
{ width:600px; float:left;}
    
    .left .focus
{
        width
:600px; border:1px solid #004578; height:100px;
        float
:left; overflow:auto; margin-bottom:10px;
    
}

    .left .container1
{
        width
:290px; border:0px solid #004578;
         height
:auto; min-height:100px; float:left; 
    
}

    .left .container2
{
        width
:290px;  border:0px solid #004578;
        height
:auto; min-height:100px; float:right;
    
}

    .content .container3
{
        width
:290px; border:0px solid #000090;
        height
:auto; min-height:100px; float:right;
    
}

    .box 
{ 
        position
:relative; width:100%; height:116px;
    
}

    .fwwin
{
        border
:1px solid #76c2eb;  
    
}

    .fwwinDrag
{
        border
:1px dashed #76c2eb; height:100px;
        filter
: alpha(opacity=50); -moz-opacity:0.5; 
    
}

    .fwwin .title
{
        background
:#d4eeff;
        filter
: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#d4eeff,endcolorstr=#fcfdff,gradientType=0);
        height
:26px;
        border-bottom
:1px solid #76c2eb;
    
}

    .fwwin .title .text
{
        float
:left; width:80%; cursor:move; height:100%; 
        line-height
:25px; padding-left:10px;
    
}

    .fwwin .title .button
{
        width
:15%; float:right; cursor:pointer;
        line-height
:25px;
    
}

    .fwwin .editor
{
        display
:none; width:100%; background:#EEEEEE;
    
}

    .fwwin .body
{
        background
:#F8F8F8; height:62px; 
        padding
:5px;
    
}

    .box .message
{
        display
:none; width:100%;
    
}

    .box .message table
{
        border
:0px solid #DEDEDE;
    
}

    .box .space
{
        height
:15px;
    
}

</style>
<script type="text/javascript">
function Rect(){
    
this.left = 0;
    
this.top = 0;
    
this.width = 0;
    
this.height = 0;
}

Rect.prototype 
= {
    getObjPos : 
function(e){
        
this.top=e.offsetTop; 
        
this.left=e.offsetLeft; 
        
this.width=e.offsetWidth; 
        
this.height=e.offsetHeight; 
        
while(e=e.offsetParent)
            
this.top += e.offsetTop; 
            
this.left += e.offsetLeft; 
        }

    }
,
    isInRect : 
function(x, y, obj){
        
this.getObjPos(obj);
        
if(x < this.left || x > this.left+this.width || y < this.top || y > this.top+this.height){
            
return 0;
        }
else if(y - this.top > this.height /2){
            return 1;
        }
else{
            
return 2;
        }

    }
,
    toString : 
function(){
        
var str = "{ left : " + this.left + ",";
        str 
+= "top : " + this.top + ",";
        str 
+= "width : " + this.width + ",";
        str 
+= "height : " + this.height + "}";
        
return str;
    }

};
var dragObj = {};
var editObj = {};
var rect = new Rect();

function debug(str){
    $(
"debug").innerHTML += str + "<br>";
    $(
"debug").scrollTop += 50;
}

function initObject()
    String.prototype.inc
=function(s){return this.indexOf(s)>-1?true:false};
    
var agent=navigator.userAgent ;
    window.isOpr
=agent.inc("Opera") ;
    window.isIE
=agent.inc("IE")&&!isOpr ;
    window.isMoz
=agent.inc("Mozilla")&&!isOpr&&!isIE ;
    window.$
=function(obj){return typeof(obj)=="string"?document.getElementById(obj):obj} ;
    window.oDel
=function(obj){if($(obj)!=null && $(obj).parentNode){$(obj).parentNode.removeChild($(obj))}} ;
    window.getElementsByClassName 
= function(className, parentElement){
        
var elems = ($(parentElement)||document.body).getElementsByTagName("*");
        
var result=[];
        
for (i=0; j=elems[i]; i++){
           
if ((" "+j.className+" ").indexOf(" "+className+" ")!=-1){
                result.push(j);
           }

        }

        
return result;
    }
 
}

function initEvent(){
    
var content, tmpObj;
    dragObj.wndCount 
= 0;
    dragObj.wnds 
= new Array();
    
    content 
= $("content").getElementsByTagName("div");
    
for(var i=0; i<content.length; i++){
        
if(content[i].className == "text"){
            content[i].onmousedown 
= onMouseDown;
        }
else if(content[i].className == "button"){
            content[i].onclick 
= onClick;
        }
else if(content[i].className == "box"){
            dragObj.wnds.push(content[i]);
            dragObj.wndCount
++;
        }

    }

    
    
//container
    dragObj.cons = new Array();
    dragObj.cons[
0= $("con1");
    dragObj.cons[
1= $("con2");
    dragObj.cons[
2= $("con3");
    
if(isIE){
        
for(i=0; i<3; i++)
            dragObj.cons[i].style.height 
= "100px";
    }

}

function initDragObject(){
    dragObj.isMouseDown 
= false;
    dragObj.o 
= null;
    dragObj.gh 
= $("dragHelper");
    
    dragObj.x 
= 0;
    dragObj.y 
= 0;
}

function initEditObject(){
    editObj.isShow 
= false;
    editObj.o 
= null;
}


function startDrag(){
    dragObj.gh.style.width 
= dragObj.o.offsetWidth - 2 + "px";
    dragObj.gh.style.height 
= dragObj.o.offsetHeight - 2 + "px";
    dragObj.gh.realheight 
= dragObj.o.offsetHeight;
    dragObj.gh.style.display 
= "block";
    dragObj.o.parentNode.insertBefore(dragObj.gh, dragObj.o);
    
    rect.getObjPos(dragObj.o);
    dragObj.o.style.position 
= "absolute";
    dragObj.o.style.left 
= rect.left + 2 + "px";
    dragObj.o.style.top 
= rect.top - rect.height + 2 + "px";
    dragObj.o.style.width 
= rect.width + "px";
    dragObj.o.style.height 
= rect.height + "px";
    document.body.appendChild(dragObj.o);
}


function onMouseDown(e){
    
if(!dragObj.isMouseDown){
        e 
= EventUtil.getEvent(e);
        dragObj.isMouseDown 
= true;
        dragObj.o 
= e.target.parentNode.parentNode.parentNode;
        dragObj.o.style.filter 
= "alpha(opacity=50)";
        dragObj.o.style.MozOpacity 
= 0.5;
        
        startDrag();
        
        dragObj.x 
= e.pageX;
        dragObj.y 
= e.pageY;
        
        
//
        //debug("onMouseDown:" + dragObj.o.id)
    }

}

function onMouseMove(e){
    
if(dragObj.isMouseDown && dragObj.o){
        e 
= EventUtil.getEvent(e);
        
var left, top, wid, hei;
        wid 
= e.pageX - dragObj.x;
        hei 
= e.pageY - dragObj.y;
        left 
= parseInt(dragObj.o.style.left) + wid;
        top 
= parseInt(dragObj.o.style.top) + hei;
        
        dragObj.o.style.left 
= left + "px";
        dragObj.o.style.top 
= top + "px";
        
        dragObj.x 
= e.pageX;
        dragObj.y 
= e.pageY;
        
        
//
        var tmp = null, obj;
        
for(var i=0; i< dragObj.wndCount; i++){
            obj 
= dragObj.wnds[i];
            
if(dragObj.o == obj) {
                
continue;
            }

            ret 
= rect.isInRect(dragObj.x, dragObj.y, obj);
            
if(ret == 1)//down
                tmp = obj.nextSibling;
                
if(tmp == null){
                    obj.parentNode.appendChild(dragObj.gh);
                    
//
                    //debug("onMouseMove: ->down ->appendchild ->" + obj.id);
                }
else if(tmp != dragObj.gh && tmp.parentNode == obj.parentNode){
                    
try{
                        obj.parentNode.insertBefore(dragObj.gh, tmp);
                        
//
                        //debug("onMouseMove: ->down ->insertBefore ->" + tmp.id);
                    }
catch(e){}
                }

                
return;
            }
else if(ret == 2)//up
                tmp = dragObj.gh.nextSibling;
                
if(tmp == obj) return;
                obj.parentNode.insertBefore(dragObj.gh, obj);
                
//
                //debug("onMouseMove: ->up ->insertBefore ->" + obj.id );//+ "-tmpid" + tmp.id);
                return;
            }

        }

        
//con
        for(var i=0; i<dragObj.cons.length; i++){
            obj 
= dragObj.cons[i];
            ret 
= rect.isInRect(dragObj.x, dragObj.y, obj);
            
if(ret > 0 && dragObj.gh.parentNode != obj){
                wins 
= getElementsByClassName("box", obj);
                
if(wins.length == 0){
                    obj.appendChild(dragObj.gh);
                    
//
                    //debug("onMouseMove: ->down ->container.appendchild ->" + obj.id);
                    return;
                }

            }

        }
// end for
    }

}

function onMouseUp(e){
    dragObj.isMouseDown 
= false;
    
if(dragObj.o){        
        dragObj.o.style.cssText 
= "";
        dragObj.o.className 
= "box";
        dragObj.o.style.height 
= dragObj.gh.realheight + "px";
        dragObj.gh.parentNode.insertBefore(dragObj.o, dragObj.gh);
        dragObj.o 
= null;
    }
    
    oDel(dragObj.gh);
}


function onClick(e){
    
var obj, btn, edit;
    e 
= EventUtil.getEvent(e);
    btn 
= e.target;
    obj 
= btn.parentNode.parentNode.parentNode;
    
    edits 
= getElementsByClassName("editor", obj);
    
if(edits.length >=1 ){
        showEditor(edits[
0]);
        resetPara(edits[
0]);
    }

    
/*if(obj.id != "win22"){
        oDel(obj);
        return;
    }
*/

}


window.onload 
= function(){
    initObject();
    initEvent();
    initDragObject();
    initEditObject();
}
;
document.onmousemove 
= onMouseMove;
document.onmouseup 
= onMouseUp;
</script>

<script type="text/javascript">
//height
var nMax, nStart, oMove;
function move(){
    
}

function addHeight(edit, hei){
    
var obj = edit.parentNode.parentNode;
    edit.style.display 
= "block";
    hei 
= edit.offsetHeight;
    wid 
= edit.offsetWidth;

    
if(!isIE){
        tmp 
= obj.offsetHeight + hei;
        obj.style.height 
= tmp + "px";
    }

    edit.style.height 
= hei + "px";
    edit.style.width 
= wid + "px";
}

function subHeight(edit){
    
var obj = edit.parentNode.parentNode;
    
    hei 
= edit.offsetHeight
    hei2 
= edit.clientHeight;
    
if(hei2>hei) hei = hei2;
    edit.style.display 
= "none";
    
//debug("sub:" + edit.id + "-" + hei);
    
    tmp 
= obj.offsetHeight - hei ;
    obj.style.height 
= tmp + "px";
    
if(arguments[1&& edit.parentNode.childNodes.length == 1){
        edit.parentNode.style.display 
= "none";
    }

}

function showEditor(edit){    
    
var obj = edit.parentNode.parentNode;
    
if(edit.isShow)//close
        edit.isShow = false;
        subHeight(edit)
    }
else//show
        edit.isShow = true;
        addHeight(edit);
        
//save parameters
        edit.prevPara = getPara(edit);
    }
    
}

function getPara(obj){
    
var chks, para;
    chks 
= obj.getElementsByTagName("input");
    para 
= "";
    
for(var i=0; i<chks.length; i++){
        
if(chks[i].checked)
            para 
+= "|" + chks[i].value;
        
else
            para 
+= "";
    }

    
return para.substr(1);
}

function setPara(obj, paras){
    
var chks, para;
    para 
= paras.split("|");
    
if(para.length > 0){
        chks 
= obj.getElementsByTagName("input");
        
for(var i=0; i<chks.length; i++){
            
if(para[i] == " ")
                chks[i].checked 
= false;
            
else
                chks[i].checked 
= true;
        }

    }

}

function resetPara(obj){
    setPara(obj, obj.prevPara);
}

function doChange(objEdit, option, n){
    
var objAdd = $(objEdit.id.replace("edit""add"));
    
var objDoID = objAdd.id + n;
    
    
if(!option.checked)//del
        objDo = $(objDoID);
        subHeight(objDo, 
true)
        oDel(objDo);
        
return;
    }

    
//get data
    var data = ["测试新闻1","测试新闻2","测试新闻3"];
    
var url = ["http://www.baidu.com""http://www.google.cn""http://www.smarta.cn"];
    
    objDo 
= document.createElement("div");
    objDo.setAttribute(
"id", objDoID);
    title 
= option.getAttribute("title")
    html 
="<table width='100%' cellspacing='1' cellpadding='3' border='0' style='background:#FFFFFF'>";
    html
+="<tr><td style='height:20px; background:#DEDEDE; font-weight:bold; padding-left:5px'>" + title + "</td></tr>";
    
    
for(var i=0; i<data.length; i++){
        html 
+= "<tr><td style='background:#F8F8F8;'><a href='" + url[i] + "' target='_blank'>" + (i+1+ "" + data[i] + "</a></td></tr>";
    }

    html 
+= "</table>";;
    objDo.innerHTML 
= html;

    objAdd.style.display 
= "block";
    objAdd.appendChild(objDo);
    addHeight(objDo);
}

function doAction(action, sObj){
    
var obj = $(sObj);
    showEditor(obj);
    
if(action == "save"){
        obj.currentPara 
= getPara(obj);
        
if(obj.currentPara != obj.prevPara)//
            cp = obj.currentPara.split("|");
            pp 
= obj.prevPara.split("|");
            chks 
= obj.getElementsByTagName("input");
            
for(var i=0; i<cp.length; i++){
                
if(cp[i] != pp[i]){
                    doChange(obj, chks[i], i);
                }

            }

        }
 
    }
else{
        resetPara(obj);
    }

}

</script>
</head>

<body>
<div class="page">
    
<div class="header">Header</div>
    
<div class="content" id="content">
        
<div class="left">
            
<div class="focus" id="debug"></div>
            
<div class="container1" id="con1">
                
<div class="box" id="win11">
                    
<div class="fwwin">
                        
<div class="title">
                            
<div class="text">window 11 </div>
                            
<div class="button">[编辑]</div>
                        
</div>
                        
<div class="editor">
                            选项
<br />1.<br />2.
                        
</div>
                        
<div class="body">b</div>
                    
</div>
                    
<div class="message">
                    
</div>
                    
<div class="space"></div>
                
</div>
                
<div class="box" id="win12">
                    
<div class="fwwin">
                        
<div class="title">
                            
<div class="text">window 12 </div>
                            
<div class="button">[编辑]</div>
                        
</div>
                        
<div class="editor">
                            选项
<br />1.<br />2.
                        
</div>
                        
<div class="body">b</div>
                    
</div>
                    
<div class="message">
                    
</div>
                    
<div class="space"></div>
                
</div>
            
</div>
            
<div class="container2" id="con2">
                
<div class="box" id="win21">
                    
<div class="fwwin">
                        
<div class="title">
                            
<div class="text">window 21 </div>
                            
<div class="button">[编辑]</div>
                        
</div>
                        
<div class="editor">
                            选项
<br />1.<br />2.
                        
</div>
                        
<div class="body">b</div>
                    
</div>
                    
<div class="message">
                    
</div>
                    
<div class="space"></div>
                
</div>
                
<div class="box" id="winNews">
                    
<div class="fwwin">
                        
<div class="title">
                            
<div class="text">新闻中心 </div>
                            
<div class="button">[编辑]</div>
                        
</div>
                        
<div class="editor" id="editNews">
                          
<table width="100%" border="0" cellspacing="0" cellpadding="0">
                          
<tr><td colspan="2" height="6"></td></tr>
                          
<tr><td>&nbsp;
                            
<input type="checkbox" name="chkNews" id="chkNews1" value="1" title="公司新闻" /><label for="chkNews1">公司新闻</label>
                          
</td><td>
                            
<input type="checkbox" name="chkNews" id="chkNews2" value="2" title="行业新闻" /><label for="chkNews2">行业新闻</label>
                          
&nbsp;</td></tr>
                          
<tr><td colspan="2" style="border-bottom:1px dashed #CCC; height:6px;font-size:6px;">&nbsp;</td></tr>
                          
<tr><td colspan="2" height="10"></td></tr>
                          
<tr><td colspan="2" align="right" valign="middle">
                              
<href="javascript:doAction('save', 'editNews');void(0);">[保存]</a>
                            
<href="javascript:doAction('cancel', 'editNews');void(0);">[取消]</a>
                            
&nbsp;
                          
</td></tr>
                          
<tr><td colspan="2" style="border-bottom:1px dashed #CCC; height:6px;font-size:6px;">&nbsp;</td></tr>
                          
</table>
                        
</div>
                        
<div class="body">推荐新闻</div>
                    
</div>
                    
<div class="message" id="addNews">
                    
</div>
                    
<div class="space"></div>
                
</div>
                
<div class="box" id="win23">
                    
<div class="fwwin">
                        
<div class="title">
                            
<div class="text">window 23 </div>
                            
<div class="button">[编辑]</div>
                        
</div>
                        
<div class="editor">
                            选项
<br />1.<br />2.
                            选项
<br />1.<br />2.
                            选项
<br />1.<br />2.
                            选项
<br />1.<br />2.
                            
                        
</div>
                        
<div class="body">b</div>
                    
</div>
                    
<div class="message">
                    
</div>
                    
<div class="space"></div>
                
</div>
            
</div>
        
</div>
        
<div class="container3" id="con3"> 
            
<div class="box" id="win31">
                    
<div class="fwwin">
                        
<div class="title">
                            
<div class="text">window 31 </div>
                            
<div class="button">[编辑]</div>
                        
</div>
                        
<div class="editor">
                            选项
<br />1.<br />2.
                        
</div>
                        
<div class="body">b</div>
                    
</div>
                    
<div class="message">
                    
</div>
                    
<div class="space">&nbsp;</div>
                
</div>
                
<div class="box" id="win32">
                    
<div class="fwwin">
                        
<div class="title">
                            
<div class="text">window 32 </div>
                            
<div class="button">[编辑]</div>
                        
</div>
                        
<div class="editor">
                            选项
<br />1.<br />2.
                        
</div>
                        
<div class="body">b</div>
                    
</div>
                    
<div class="message">
                    
</div>
                    
<div class="space">&nbsp;</div>
                
</div>
        
</div>
    
</div>
    
<div class="footer">Footer</div>
    
<div id="dragHelper">&nbsp;</div>
</div>
</body>
</html>

原文地址:https://www.cnblogs.com/Freewind22/p/1167118.html