、需求分析
现在电脑的屏幕越来越大,为了利用好宽屏,我们在设计系统UI时喜欢在左侧放个菜单或选项面板,在右边显示与菜单或选项对应的内容,两者之间用分隔条splitter来间隔,并可以通过拖动分隔条splitter来动态调研左右两边的宽度。
要在网页上实现这种UI界面,也有不少现成的组件,比如jQuery中提供的Splitter.js,不过自已用HTML+JavaScript+CSS来DIY一下,从而加深对HTML+JavaScript+CSS的了解,也是不错的选择。
二、构造界面
首先我们来打造界面。在id 为divMain 的<div>中,左边有一个id 为 divLeft的<div>,右边有一个左边有一个id 为 divRight的<div>,两者中间有一个id为divSplitter 的<div>作为分隔条splitter。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="PurpleEndurer"> <meta name="Keywords" content="HTML,JavaScript,CSS,DIY,分隔条,splitter,演示"> <meta name="Description" content="HTML+JavaScript+CSS DIY 分隔条演示splitter"> <title>HTML+JavaScript+CSS DIY 分隔条演示splitter</title> <style> #divMain { position: relative; width: 800px; height: 300px; } #divLeft { width: 200px; background: #ffff99; position: absolute; top: 0; bottom: 0; } #divRight { margin-left: 210px; background: #ccffcc; height: 100%; } #divSplitter { position: absolute; top: 0; bottom: 0; left: 200px; width: 10px; background: #e7e7e7; box-shadow: 0px 0px 8px #ccc; cursor: w-resize; vertical-align:middle; } p.title { background: #ccccff; color:yellow; border-top:1px solid purple; border-left:1px solid purple; text-align:center; width: 800px; margin: 0px; } </style> </head> <body> <p class="title">HTML+JavaScript+CSS分隔条演示splitter</p> <div id="divMain"> <div id="divLeft">left:0123456789abcdefghijklmnopqrstuvwxyz</div> <div id="divRight">right:0123456789abcdefghijklmnopqrstuvwxyz</div> <!-- 分隔条 --> <div id="divSplitter" title="我是分隔条,可以双击我^_^"></div> </div> </body> </html>
三、编写代码
(一)定义全局变量和常量
var divMain = document.getElementById('divMain'), divLeft = document.getElementById('divLeft'), divRight = document.getElementById('divRight'), divSplitter = document.getElementById('divSplitter'); // 改变分隔条左右宽度所需常量 const divOrgLeftWidth = 200, // 左边部分原始宽度 rightDivLeftGap = 10, // 右边部分与左边部分的距离 divSplitterMinLeft = 20, // 分隔条左边部分最小宽度 divSplitterMaxLeft = 780;// 分隔条左边部分最大宽度
(二)挂接鼠标事件
在windows.onload中挂接divSplitter的onmousedown()和ondblclick(),其中onmousedown()用于拖放分隔条,ondblclick()用于双击分隔条隐藏左边的内容,比如菜单或选项,尽可能显示右边的内容。
window.onload = function () { divSplitter.onmousedown = splitDiv; divSplitter.ondblclick = hideOrShowLeft; };
(三)双击分隔条代码
当用户双击分隔条时,我们就隐藏左边的内容,比如菜单或选项,为右边的内容提供更大显示范围。
这里我们需要先判断左边否已经处于隐藏状态,如果左边否已经处于隐藏状态,那么就恢复到系统默认状态,否则就将左边的内容隐藏起来,尽可能显示右边的内容。
function hideOrShowLeft(e) { if ('none'==divLeft.style.display) { divLeft.style.display = 'block'; divLeft.style.width = divSplitter.style.left = divOrgLeftWidth + 'px'; divSplitter.innerHTML = ''; divRight.style.marginLeft = '210px'; } else { divLeft.style.display = 'none'; divSplitter.style.left = '0px'; divSplitter.innerHTML ='<p style="padding-top:100px;"><span style="color:red; font-size:16pt;">></span></p>'; divRight.style.marginLeft = '10px'; } return false; }// hideOrShowLeft(e)
(四)拖放分隔条代码
在响应鼠标拖放事件时,我们首先要判断左边否已经处于隐藏状态,如果左边否已经处于隐藏状态,那么就恢复到系统默认状态,否则进行拖放操作:
// 拖动分隔条操作 function splitDiv(e) { if ('none'==divLeft.style.display) { hideOrShowLeft(); return false; } // 记录下初始位置的值 var disX = e.clientX; divSplitter.left = divSplitter.offsetLeft; document.onmousemove = function (e) { var moveX = e.clientX - disX; // 鼠标拖动的偏移距离 var iT = divSplitter.left + moveX, // 分隔条相对父级定位的 left 值 maxT = divMain.clientWidth - divSplitter.offsetWidth; //iT < 0 && (iT = 0); //iT > maxT && (iT = maxT); if (iT < 0) { iT = 0; } else { if (iT > maxT) { iT = maxT; } } if (iT > divSplitterMinLeft && iT < divSplitterMaxLeft) { divLeft.style.width = divSplitter.style.left = iT + 'px'; divRight.style.marginLeft = iT + rightDivLeftGap + 'px'; } //document.onmousemove() return false; }; // 鼠标放开的时候取消操作 document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; }; // document.onmouseup() }//splitDiv(e)
四、改进显示
上面的演示代码中,左右两边显示的内容都比较短。实际应用中,两边显示的内容多。
当我们把代码界面定义改为:
<p class="title">HTML+JavaScript+CSS分隔条演示splitter by PurpleEndurer</p> <div id="divMain"> <div id="divLeft">left:0123456789abcdefghijklmnopqrstuvwxyz</div> <div id="divRight">right:0123456789abcdefghijklmnopqrstuvwxyz</div> <!-- 分隔条 --> <div id="divSplitter" title="我是分隔条,可以双击我^_^"></div> </div>
问题就来了:
两边的内容会重叠。
我们需要通过css来解决这个问题。
解决方法有两种:
(一)让内容自动换行
利用word-wrap 来实现:
<style> div { word-wrap: break-word; /*自动换行*/ }
效果如下:
当内容较多时,自动换行显示效果并不是很好。所以我们更喜欢用下面的另一种方法 。
(二)超出部分隐藏
要隐藏超出部分,需要用到display、overflow等几个属性:
div { display: -webkit-box; /* 将对象作为弹性伸缩盒子模型显示 */ -webkit-box-orient: vertical; /* 设置或检索伸缩盒对象的子元素的排列方式 */ overflow: hidden;/* 超出部分隐藏 */ }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="PurpleEndurer"> <meta name="Keywords" content="HTML,JavaScript,CSS,DIY,分隔条,splitter,演示"> <meta name="Description" content="HTML+JavaScript+CSS DIY 分隔条演示splitter"> <title>HTML+JavaScript+CSS DIY 分隔条演示splitter</title> <style> div { /*--word-wrap:break-word; 自动换行 */ display: -webkit-box; /* 将对象作为弹性伸缩盒子模型显示 */ -webkit-box-orient: vertical; /* 设置或检索伸缩盒对象的子元素的排列方式 */ overflow: hidden;/* 超出部分隐藏 */ } #divMain { position: relative; width: 800px; height: 300px; /*margin: 20px auto;*/ } #divLeft { width: 200px; background: #ffff99; position: absolute; top: 0; bottom: 0; } #divRight { margin-left: 210px; background: #ccffcc; height: 100%; } #divSplitter { position: absolute; top: 0; bottom: 0; left: 200px; width: 10px; background: #e7e7e7; box-shadow: 0px 0px 8px #ccc; cursor: w-resize; vertical-align:middle; } p.title { background: #ccccff; color:yellow; border-top:1px solid purple; border-left:1px solid purple; text-align:center; width: 800px; margin: 0px; } </style> </head> <body> <p class="title">HTML+JavaScript+CSS分隔条演示splitter</p> <div id="divMain"> <div id="divLeft">left:0123456789abcdefghijklmnopqrstuvwxyz</div> <div id="divRight">right:0123456789abcdefghijklmnopqrstuvwxyz</div> <!-- 分隔条 --> <div id="divSplitter" title="我是分隔条,可以双击我^_^"></div> </div> </body> <script> // 改变分隔条左右宽度所需常量 const divOrgLeftWidth = 200; // 左边部分原始宽度 const rightDivLeftGap = 10;//20; // 右边部分与左边部分的距离 //const divSplitterWidth = 10; // 分隔条宽度 const divSplitterMinLeft = 20; // 分隔条左边部分最小宽度 const divSplitterMaxLeft = 780;// 分隔条左边部分最大宽度 var divMain = document.getElementById('divMain'), divLeft = document.getElementById('divLeft'), divRight = document.getElementById('divRight'), divSplitter = document.getElementById('divSplitter'); function hideOrShowLeft(e) { if ('none'==divLeft.style.display) { divLeft.style.display = 'block'; divLeft.style.width = divSplitter.style.left = divOrgLeftWidth + 'px'; divSplitter.innerHTML = ''; divRight.style.marginLeft = '210px'; } else { divLeft.style.display = 'none'; divSplitter.style.left = '0px'; divSplitter.innerHTML ='<p style="padding-top:100px;"><span style="color:red; font-size:16pt;">></span></p>'; divRight.style.marginLeft = '10px'; } return false; } // 分隔条操作 function splitDiv(e) { if ('none'==divLeft.style.display) { hideOrShowLeft(); return false; } // 记录下初始位置的值 var disX = e.clientX; divSplitter.left = divSplitter.offsetLeft; document.onmousemove = function (e) { var moveX = e.clientX - disX; // 鼠标拖动的偏移距离 var iT = divSplitter.left + moveX, // 分隔条相对父级定位的 left 值 maxT = divMain.clientWidth - divSplitter.offsetWidth; //iT < 0 && (iT = 0); //iT > maxT && (iT = maxT); if (iT < 0) { iT = 0; } else { if (iT > maxT) { iT = maxT; } } if (iT > divSplitterMinLeft && iT < divSplitterMaxLeft) { divLeft.style.width = divSplitter.style.left = iT + 'px'; divRight.style.marginLeft = iT + rightDivLeftGap + 'px'; } return false; }; // 鼠标放开的时候取消操作 document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; }; }// window.onload = function () { divSplitter.onmousedown = splitDiv; divSplitter.ondblclick = hideOrShowLeft; }; </script> </html>
五、完整代码
HTML+JavaScript+CSS DIY 分隔条splitter代码