JS构建页面的DOM节点结构(二)

上个星期做了一个《JS构建页面的DOM节点结构》以及列表相关的一些操作,今天接着完善一下,把两者结合起来,做一个页面结构的DOM控制面板。

大致的情况如下:

先遍历当前页面的dom节点,然后将获得的节点构建成一个DOM树行菜单。

然后将DOM树行菜单菜单作为一个面板,将菜单的操作映射为页面DOM的行为。
暂时只能进行基本的页面DOM顺序拖动,类似Chrome控制台的Elements面板。
然后兼容IE6/7/8。

所有的操作在前面的文章里面都有涉及,所以算是个总结。

测试地址:

http://fronter.sinaapp.com/wp-content/demo/domTree.html

demo图(拖动旁边的节点可以控制文档内对应的节点):

 

 

demo:

View Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style type="text/css">
*
{ margin: 0; padding: 0; }
body
{ font-size: 12px; }
#wrap
{ width: 660px; margin: 0 auto;}
#article
{ font-size: 14px; font-family: 'TIMES NEW ROMAN'}
ul
{ list-style: none;}
#nodeTree
{-moz-user-select:none; position: absolute; right: 10px; top:10px; width: 200px; overflow: hidden; margin-left: 100px; padding: 15px 0; border: 3px solid #073749; background: #fff; border-radius: 4px; box-shadow: -5px 5px 10px #000; cursor: move;}
p
{ text-indent: 2em;}
li
{ line-height: 24px; padding: 0 0 0 20px; list-style: none; }
h3:hover
{ background: #e4e4e4; cursor: move;}
</style>
</head>
<body>
<div id="wrap">
<form action="" style="border: 1px solid #d4d4d4; line-height: 2em;">
<h2>测试表单</h2>
<p>有bug欢迎指出,联系<a href="http://www.cnblogs.com/xesam/">小西山子</a></p>
</form>
<div id="article">
<h1>Rush</h1>
<p>Swallows may have gone, but there is a time of return; willow trees may have died back, but thre is a time of regreening; peach blossoms may have died back, but they will bloom again. Now, you the wise, tell me , why should our days leave us, never to return? If they had been stolen by someone, who could it be? Where could he hide them? If they had made the escape themselves, then where could they stay at the moment?</p>
<p>I don't know how many days I have been given to spend, but I do feel my hands are getting empty. Takong stock silently, I find that more han eight thousand days have already slid away from me. Like a drop of water from the point of a needle disappearing into the ocean, my days are dripping into the stream of time, soundless, traceless.</p>
<p>Already sweat is starting on my forehead, and tears is welling up in my eyes.</p>
<p>Those that have gone have gone for good, those to come keep coming; yet in between, how swift is the shift, in such a rush?</p>
<p>When I get up in the morning, the slanting sun marks its presence caught, blankly, in his revolutiong. Thus-the day flows away though the sink when I wash my hands, wears off in the bowl when I eat my meal, and passes away before my day-dreaming gaze as reflect in silence. Icanfeel his haste now, so I reach out my hands to hold him back, but he keeps flowing past my withholding hand. In the evening, as I lie in bed, he strides over my body, glides past my feet, in his agile way. The moment I open my eyes and meet the sun again, ine whole day has gone.I bury my face in my hands and heave a sigh. but the new day begins to flash past in the sigh.</p>
<p>What can I do, in this bustling world, wiht my days flying in their escape? Nothing but to hesitate, to rush. What have I been doing in that eight-thousand-day rush, apart from hesitating?Those bygone days have been dispersed as smoke by a light wind, or evaporated as mist by the morning sun. What traces have I left behind me ? Have I ever left behind any gossamer traces at all? I have come to the world, stark naked; am I to go back, in a blink, in the same stark nakedness?</p>
<p>It is not fair though: why should I have made sush a trip for nothing?</p>
<p>Youthe wise, tell me, why hsould our days leave us, never to return?</p>
<p>By Zhu Ziqing</p>
</div>
</div>
<script type="text/javascript">
var Tree = (function(){
function walkDom(el){
var c = el.firstChild;
var retObj = {};
var array = [];
while(c !== null){//这里只是返回了元素节点,没有节点就是个空数组
if(c.nodeType == 1){
array.push(walkDom(c));
}
c
= c.nextSibling;
}
retObj[el.tagName]
= {};
retObj[el.tagName][
'domPointer'] = el;
retObj[el.tagName][
'nodeArray'] = array;
return retObj;
}
function createTree(tree){
for(var key in tree){
var h3 = document.createElement('h3');
h3.appendChild(document.createTextNode(key.toLowerCase()));
h3.domPointer
= tree[key].domPointer;
var li = document.createElement('li');
li.appendChild(h3);
if(tree[key]['nodeArray'].length != 0){
var ul = document.createElement('ul');
for(var i = 0; i < tree[key]['nodeArray'].length; i++){
ul.appendChild(createTree(tree[key][
'nodeArray'][i]));
}
li.appendChild(ul);
}
}
return li;
}
function createNodeList(root,target,id){
var nodeTree = walkDom(document.body);
var nodeList = document.createElement('ul');
nodeList.appendChild(createTree(nodeTree))
nodeList.id
= id || 'nodeTree';
target.appendChild(nodeList);
}
return {
walkDom : walkDom,
createTree : createTree,
createNodeList:createNodeList
}
})();
Tree.createNodeList(document.body,document.body,
'nodeTree');

function $(id){
return document.getElementById(id);
}
function getMousePos(e){
return {
x : e.pageX
|| e.clientX + document.body.scrollLeft,
y : e.pageY
|| e.clientY + document.body.scrollTop
}
}
function getElementPos(el){
return {
x : el.offsetParent
? el.offsetLeft + arguments.callee(el.offsetParent)['x'] : el.offsetLeft,
y : el.offsetParent
? el.offsetTop + arguments.callee(el.offsetParent)['y'] : el.offsetTop
}
}
function getElementSize(el){
return {
width : el.offsetWidth,
height : el.offsetHeight
}
}
function getEvent(event){
return event || window.event;
}
function getTarget(e){
return e.target || e.srcElement;
}
function toArray(arrayLike){
try{
return [].slice.call(arrayLike,0);
}
catch(ex){
var ret = [];
for(var i = 0,len = arrayLike.length ; i < len ; i++){
ret.push(arrayLike[i]);
}
return ret;
}
}
function createElementWithAttrs(elem,opts){
setElementAttributes(elem,opts)
return elem;
}
function setElementAttributes(elem,opts){
for(var key in opts){
if(typeof opts[key] != 'object'){
elem[key]
= opts[key];
}
else{
if(!elem[key]){
elem[key]
= {};
}
arguments.callee(elem[key],opts[key]);
}
}
}
function isContain(parent,child){
try{
return parent.contains(child);
}
catch(ex){
return !!(parent.compareDocumentPosition(child) & 16);
}
}
function after(newEl,el){
el.nextSibling
==null ? el.parentNode.appendChild(newEl) : el.parentNode.insertBefore(newEl,el.nextSibling);
return 0;
}
function before(newEl,el){
el.parentNode.insertBefore(newEl,el);
return 0;
}
function getMoveTitles(parent,tag){
return toArray(parent.getElementsByTagName(tag))
}
function checkTarget(target,titleTag){
return target.tagName.toLowerCase() == titleTag;
}
function moveIndicator(){}

var MOVE = {};
MOVE.isMove
= false;
var nodeTree = $('nodeTree');
var indicator = createElementWithAttrs(document.createElement('div'),{
style : {
width :
'150px',
height:
'1px',
'lineHeight':'0',
'fontSize' : '0',
background :
'red'
}
});
nodeTree.onmousedown
= function(event){
nodeTree.onselectstart
= function(){
return false;
};
var e = getEvent(event);
var target = getTarget(e);
var titleTag = 'h3';
var moveTitles = getMoveTitles(this,titleTag);
for(var i = 0,len = moveTitles.length; i <len; i++){
moveTitles[i][
'pos'] = getElementPos(moveTitles[i]);
moveTitles[i][
'size'] = getElementSize(moveTitles[i]);
}
if(checkTarget(target,titleTag)){
var targetParent = target.parentNode;
targetParent.original
= getMousePos(e);
targetParent.pos
= getElementPos(targetParent);
targetParent.size
= getElementSize(targetParent);

var moveClone = createElementWithAttrs(document.createElement('div'),{
pos : targetParent.pos,
size : targetParent.size,
original:targetParent.original,
style : {
left : targetParent.pos.x
+ 27 +'px',
top : targetParent.pos.y
+ 7 + 'px',
width : targetParent.size.width
+ 'px',
height : targetParent.size.height
+ 'px',
opacity:
0.7,
filter :
'alpha(opacity = 70)',
position :
'absolute',
background:
'#d4d4d4'
}
});
moveClone.innerHTML
= targetParent.innerHTML;
document.body.appendChild(moveClone);
document.body.onselectstart
= function(){
return false;
};
document.onmousemove
= function(event){
var e = getEvent(event);
var currentPos = getMousePos(e);
setElementAttributes(moveClone,{
style:{
left : moveClone.pos.x
+ 27 + currentPos.x - moveClone.original.x + 'px',
top : moveClone.pos.y
+ 7 + currentPos.y - moveClone.original.y + 'px'
}
});
for(var i = 0,len = moveTitles.length; i <len; i++){
if(currentPos.x > moveTitles[i]['pos']['x'] && currentPos.x < moveTitles[i]['pos']['x'] + moveTitles[i]['size']['width']){
if(currentPos.y > moveTitles[i]['pos']['y'] && currentPos.y < moveTitles[i]['pos']['y'] + moveTitles[i]['size']['height']/2){
//console.log('upper half');
if(!isContain(targetParent,moveTitles[i])){
MOVE.isMove
= true;
before(indicator,moveTitles[i].parentNode);
before(target.domPointer,moveTitles[i].domPointer);
};
}
if(currentPos.y > moveTitles[i]['pos']['y'] + moveTitles[i]['size']['height']/2 && currentPos.y < moveTitles[i]['pos']['y'] + moveTitles[i]['size']['height']){
//console.log('lower half');
if(!isContain(targetParent,moveTitles[i])){
MOVE.isMove
= true;
after(indicator,moveTitles[i].parentNode);
after(target.domPointer,moveTitles[i].domPointer);
};
}
}
}
}
document.onmouseup
= function(event){
document.onmousemove
= null;
if(MOVE.isMove){
indicator.parentNode.replaceChild(targetParent,indicator);
MOVE.isMove
= false;
}
document.body.onselectstart
= function(){
return true;
};
document.body.removeChild(moveClone);
moveClone
= null;
document.onmouseup
= null;
}
}
}

</script>
</body>
</html>

 

转载请注明来自小西山子【http://www.cnblogs.com/xesam/
本文地址:http://www.cnblogs.com/xesam/archive/2011/12/13/2286138.html

posted @ 2011-12-13 15:07  西山  阅读(771)  评论(1编辑  收藏  举报