项目要求实现目录和文章内容之间可以拖拽自由改变宽度,百度了很多,然后自己改了一下,效果如下。
html代码
这里只列出来最外层的框架,里面具体填什么看你自己咯
<div class="menu-content flex" id="content_box">
<div class="menu-tree" id="article_left"></div>
<div id="middle" >
<button class="iconfont icon-more1-s" id="set_menu_width" title="收缩侧边栏">
</button>
</div>
<div id="article_right"></div>
</div>
css 代码
最外层的content_box使用l了flex布局。
#middle {
width: 20px;
cursor: col-resize;
min-height: 767px;
position: relative;
}
#middle button{
cursor: col-resize;
position: fixed;
top: 50%;
color: #9999;
}
#article_left {
width: 150px;
}
#article_right {
width: 80%;
position: relative;
}
JS实现代码
// 实现拖拽改变宽度
window.onload = function(){
var resize = document.getElementById("middle");
var left = document.getElementById("article_left");
var right = document.getElementById("article_right");
var box = document.getElementById("content_box");
resize.onmousedown = function(e){
var startX = e.clientX;
resize.left = resize.offsetLeft;
document.onmousemove = function(e){
var endX = e.clientX;
var moveLen = resize.left + (endX - startX);
var maxT = box.clientWidth - resize.offsetWidth;
if(moveLen<59) moveLen = 59;
if(moveLen>maxT-500) moveLen = maxT-500;
resize.style.left = moveLen;
left.style.width = moveLen + "px";
right.style.width = (box.clientWidth - moveLen - 5) + "px";
}
document.onmouseup = function(evt){
evt.stopPropagation()
document.onmousemove = null;
document.onmouseup = null;
resize.releaseCapture && resize.releaseCapture();
}
resize.setCapture && resize.setCapture();
return false;
};
};
遇到的问题:
1,如果左边或右边div标签的旁边还存在其他标签,比如,我之前左边就还存在一个侧边导航栏,在拖拽的时候就会自动多跳一段宽度,这个宽度正好就是侧边导航栏的宽度。
2、因为在middle增加了按钮,用于点击收缩或展开目录就会出现onclick事件和onmousedown事件冲突。
解决:
1、首先需要了解几个概念clientX、offsetLeft等概念,本来想在这写的,查完资料发现好多东西自己都不清不楚的,决定另写一篇。
我的解决办法是把侧边导航栏给去掉了,不是办法的办法。有待解决…欢迎评论求教。
对于上面出现的setCapture()和releaseCapture()的用法。必须成对出现。
setCapture()用于在当前线程的指定窗口里设置鼠标捕获,而且所有的鼠标输入都只针对该窗口,无论鼠标是在窗口边界内外。注意setCapture()只能够捕获onmousedown、onmouseup、onmousemove、onclick、ondblclick、onmouseover、onmouseout鼠标消息。
releaseCapture()则是用于释放鼠标捕获,当你不再需要捕获窗口的鼠标消息时,一定要记得调用。
当然,还有一个行为会使鼠标捕获失效,当是鼠标在另一个线程创建的窗口上,鼠标按下时系统才将鼠标输入指向指定窗口,即鼠标按下时所在的窗口,原来设定setCapture()的那个窗口鼠标捕获失效。
2、因为鼠标点击事件就是由onmousedown、onmouseup、onclick组成。
当点击鼠标按钮时,会触发 onmousedown 事件。当释放鼠标按钮时,会触发 onmouseup 事件。当完成鼠标点击时,会触发 onclick 事件。
在这里我们想要的区分正确区分拖拽和点击,我的想法是根据鼠标抬起的时间来区分。一般onclick迅速就会完成,而
拖拽则需要比click长的时间。所以解决方案如下:
// 解决click和mousedown冲突
var key ; //设置了一个标志 false为点击事件 ture为鼠标移动事件
var firstTime = 0;
var lastTime = 0;
$("#set_menu_width").click(function() {
if(key){
// console.log('click');
}
});
$("#set_menu_width").mousedown(function() {
firstTime = new Date().getTime();
//console.log("a"+firstTime);
});
$("#set_menu_width").mouseup(function() {
//鼠标抬起后 记录时间 超过200ms就是移动拖拽事件
lastTime = new Date().getTime();
// console.log(lastTime - firstTime);
if( (lastTime - firstTime) > 200){
key = true;
return;
}
key = false;
});
效果是达到了要求,如果大家有更好的办法,希望能告诉我。感谢!