一个刚完成的layout(拖动流畅,不受iframe影响)


Posted in Javascript onAugust 17, 2007

写一个layout本来是一个很简单的事情,可这次的一个layout问题确让我为难了许久才做出来,下面来大概讲解一下问题的出现与解决过程。

注:本文代码皆基于jquery实现。

按照普通的方法写一个layout,一般是用一个table来实现,用中间的td拖动来控制左右两个td的大小,这个问题简单,很快就搞定。代码如下:

QUOTE:
<!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>Untitled Document</title>
    <style type="text/css">
        *{margin:0px;padding:0px}
        html{overflow:hidden}
        #sideBar{width:200px;height:100%;overflow:auto}
        #toggleBar,.div{
            width:7px;height:100%;
            overflow:hidden;background:#eee;
            cursor:e-resize;border-left:1px solid #ccc;border-right:1px solid #ccc;
        }
        td{display:block;overflow:auto;word-break:break-all;}
    </style>
    <script type="text/javascript" src="../Common/jquery.gif"></script>
    <script type="text/javascript">
        $(document).ready(function(){
                //及时调整页面内容的高度
                setInterval(function(){
                    var winH=(document.documentElement||document.body).clientHeight;
                    $("#tbl,#sideBar,#toggleBar,#main").css("height",winH);
                    $("td").each(function(){$(this).html()||$(this).html(" ")});
                },100)
            }
        );

        var begin_x; 
        var drag_flag = false; 
        document.onmousemove = mouseDrag
        document.onmouseup = mouseDragEnd
        //半透明拖动条
        var alphaDiv="<div class='div' id='alphaDiv' style='position:absolute;height:2000px;top:0;z-index:10001;filter:alpha(opacity=50);opacity:0.5;left:200px'> </div>";
        function setDrag(){
            drag_flag=true; 
            begin_x=event.x;
            //添加半透明拖动条
            $(alphaDiv).css("left",$("#toggleBar")[0].offsetLeft).appendTo("body");
        }

        //拖动时执行的函数
        function mouseDrag(){
            if(drag_flag==true){
                if (window.event.button==1){
                    var now_x=event.x;
                    var value=parseInt($("#alphaDiv")[0].style.left)+now_x-begin_x;
                    $("#alphaDiv")[0].style.left=value+"px";
                     begin_x=now_x;
                }    
                $("body").css("cursor","e-resize");    //设定光标类型
            }else{
                try{
                    $("#sideBar")[0].style.pixelWidth=$("#alphaDiv")[0].style.left;
                    $("#alphaDiv").remove();
                }catch(e){}
            }
        }

        function mouseDragEnd(){
            //设置拖动条的位置
            if(drag_flag==true){
                //设定拖动条的位置(设定左侧的宽度)
                $("#sideBar")[0].style.pixelWidth=parseInt($("#alphaDiv")[0].style.left);
                $("#alphaDiv").remove();    //删除半透明拖动条
                $("body").css("cursor","normal");    //恢复光标类型
            }
            drag_flag=false;
        }
    </script>
    </head>
    <body>
        <table id="tbl" border="0" bordercollaspe="collapse" cellpadding="2" cellspacing="0" width="100%" height="100%">
            <tr>
                <td width="1"><div id="sideBar" style="width:200px;"><div style="height:1200px">asdfasdf</div></div>
                </td>
                <td width="1" onmousedown="setDrag()" id="toggleBar"></td>
                <td id="main">
                    right Panel
                </td>
            </tr>
        </table>
    </body>
</html>
演示地址:http://www.ajaxbbs.net/test/layout/JqSplit/noiframe.htm上面的这种写法也是大多数layout的写法,著名框架dojo好像也是这么实现的,其他的没试。

但现在的情况仍然不能满足我们的需求,我们需要左侧或右侧是ifame,通过iframe调用相关的页面,在前面的代码中将右侧改为iframe。
演示地址:http://www.ajaxbbs.net/test/layout/JqSplit/iframeRight.htm

这时我们就发现问题了,只能向左边拖动,但不能像右边拖动,这是为什们呢?
经过检查,发现原来当鼠标移动到iframe上就无法捕获鼠标的位置了,event对象也不存在。得不到鼠标的位置我们的拖动当然会出现问题了。

这个问题着实让我郁闷了许久,然后测试其他的一些layout(对iframe进行了处理)发现凡是使用iframe的都有一个缺陷,当鼠标拖动速度很快的时候,拉动条速度跟不上(当然这些并没有那个模拟的半透明的拖动条,直接拖动真实的拖动条的),感觉就是很不流畅很不同步。
我们看一下直接拖动真是滚动条的情况
演示地址:http://www.ajaxbbs.net/test/layout/JqSplit/iframeRightNoAlpha.htm我们慢速度拖动还是可以向右移动的,但一但速度稍快便不能拖动了。

对于这个问题始终没有想到好的解决办法,就在我悲伤的即将放弃时,看到前几天写的一个模拟弹出框,因为当时测试弹出框应该要遮住包括iframe在内的select。所以页面中使用了ifame。突然发现一个索引很高的层能够遮住iframe,突然间就有了灵感,马上实验。

思路如下:拖动拉条时在页面添加一个索引很大的层(如10000),将其透明度设为0(完全透明),这样鼠标就不会移动到iframe中,但iframe仍然存在可以看到。当拖动结束(onmouseup)时去掉这个层即可,这样就实现了比较完美的拖动。

演示地址:http://www.ajaxbbs.net/test/layout/JqSplit/demo.htm我们看一下完整的代码:

QUOTE:
<!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>Untitled Document</title>
    <style type="text/css">
        *{margin:0px;padding:0px}
        html{overflow:hidden}
        #sideBar{width:200px;height:100%;overflow:auto}
        #toggleBar,.div{
            width:7px;height:100%;
            overflow:hidden;background:#eee;
            cursor:e-resize;border-left:1px solid #ccc;border-right:1px solid #ccc;
        }
        td{display:block;overflow:auto;word-break:break-all;}
    </style>
    <script type="text/javascript" src="../Common/jquery.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
                //及时调整页面内容的高度
                setInterval(function(){
                    var winH=(document.documentElement||document.body).clientHeight;
                    $("#tbl,#sideBar,#toggleBar,#main").css("height",winH);
                    $("td").each(function(){$(this).html()||$(this).html(" ")});
                },100)
            }
        );

        var begin_x; 
        var drag_flag = false; 
        document.onmousemove = mouseDrag
        document.onmouseup = mouseDragEnd
        //半透明的拖动条(模拟)
        var alphaDiv="<div class='div' id='alphaDiv' style='position:absolute;height:2000px;top:0;z-index:10001;filter:alpha(opacity=50);opacity:0.5;left:200px'> </div>";
        function setDrag(){
            drag_flag=true; 
            begin_x=event.x;
            //添加蒙板
            createMask();
            //添加半透明拖动条
            $(alphaDiv).css("left",$("#toggleBar")[0].offsetLeft).appendTo("body");
        }

        //关键部分
        function createMask(){
            //创建背景
            var rootEl=document.documentElement||document.body;
            var docHeight=((rootEl.clientHeight>rootEl.scrollHeight)?rootEl.clientHeight:rootEl.scrollHeight)+"px";
            var docWidth=((rootEl.clientWidth>rootEl.scrollWidth)?rootEl.clientWidth:rootEl.scrollWidth)+"px";
            var shieldStyle="position:absolute;top:0px;left:0px;width:"+docWidth+";height:"+docHeight+";background:#000;z-index:10000;filter:alpha(opacity=0);opacity:0";
            $("<div id='shield' style=\""+shieldStyle+"\"></div>").appendTo("body");
        }
        //拖动时执行的函数
        function mouseDrag(){
            if(drag_flag==true){
                if (window.event.button==1){
                    var now_x=event.x;
                    var value=parseInt($("#alphaDiv")[0].style.left)+now_x-begin_x;
                    $("#alphaDiv")[0].style.left=value+"px";
                     begin_x=now_x;
                }    
                $("body").css("cursor","e-resize");    //设定光标类型
            }else{
                try{
                    $("#shield").remove();
                    $("#sideBar")[0].style.pixelWidth=$("#alphaDiv")[0].style.left;
                    $("#alphaDiv").remove();
                }catch(e){}
            }
        }

        function mouseDragEnd(){
            //设置拖动条的位置
            if(drag_flag==true){
                //设定拖动条的位置(设定左侧的宽度)
                $("#sideBar")[0].style.pixelWidth=parseInt($("#alphaDiv")[0].style.left);
                $("#shield").remove();    //删除蒙板
                $("#alphaDiv").remove();    //删除半透明拖动条
                $("body").css("cursor","normal");    //恢复光标类型
            }
            drag_flag=false;
        }
    </script>
    </head>
    <body>
        <table id="tbl" border="0" bordercollaspe="collapse" cellpadding="2" cellspacing="0" width="100%" height="100%">
            <tr>
                <td width="1"><div id="sideBar" style="width:200px;"><div style="height:1200px">asdfasdf</div></div>
                </td>
                <td width="1" onmousedown="setDrag()" id="toggleBar"></td>
                <td id="main">
                    <iframe src="test.htm" id="frmMain" width="100%" height="100%"></iframe>
                </td>
            </tr>
        </table>
    </body>
</html>
自己的一点发现,一点心得,不知对大家有没有用处,只管拿出来献丑了!

Javascript 相关文章推荐
IE8 兼容性问题(属性名区分大小写)
Jun 04 Javascript
Javascript实现带关闭按钮的网页漂浮广告代码
Jan 12 Javascript
jQuery提示效果代码分享
Nov 20 Javascript
js控制多图左右滚动切换效果代码分享
Aug 26 Javascript
基于jQuery实现拖拽图标到回收站并删除功能
Nov 25 Javascript
浅谈Vue的基本应用
Dec 27 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
Aug 24 Javascript
ng-zorro-antd 入门初体验
Dec 03 Javascript
在vue-cli 3中给stylus、sass样式传入共享的全局变量
Aug 12 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
Mar 14 Javascript
vue双击事件2.0事件监听(点击-双击-鼠标事件)和事件修饰符操作
Jul 27 Javascript
Vue实现点击导航栏当前标签后变色功能
Aug 19 Javascript
wordpress之js库集合研究介绍
Aug 17 #Javascript
FormValid0.5版本发布,带ajax自定义验证例子
Aug 17 #Javascript
Autocomplete Textbox Example javascript实现自动完成成功
Aug 17 #Javascript
如何用js控制css中的float的代码
Aug 16 #Javascript
javascript 函数式编程
Aug 16 #Javascript
总结AJAX相关JS代码片段和浏览器模型
Aug 15 #Javascript
(currentStyle)javascript为何有时用style得不到已设定的CSS的属性
Aug 15 #Javascript
You might like
PHP脚本的10个技巧(6)
2006/10/09 PHP
完美解决thinkphp验证码出错无法显示的方法
2014/12/09 PHP
thinkPHP5使用Rabc实现权限管理
2019/08/28 PHP
(jQuery,mootools,dojo)使用适合自己的编程别名命名
2010/09/14 Javascript
javascript实现日历控件(年月日关闭按钮)
2012/12/12 Javascript
js复制到剪切板的实例方法
2013/06/28 Javascript
jquery实现全选功能效果的实现代码
2016/05/05 Javascript
jQuery 的 ready()的纯js替代方法
2016/11/20 Javascript
Bootstrap页面标题Page Header的实现方法
2017/03/22 Javascript
JS运动特效之完美运动框架实例分析
2018/01/24 Javascript
JavaScript实现的简单Tab点击切换功能示例
2018/07/06 Javascript
Array数组对象中的forEach、map、filter及reduce详析
2018/08/02 Javascript
解决jquery有正确返回值但不执行success函数的问题
2018/08/20 jQuery
基于React Native 0.52实现轮播图效果
2020/08/25 Javascript
利用Vue实现一个markdown编辑器实例代码
2019/05/19 Javascript
简单了解vue.js数组的常用操作
2019/06/17 Javascript
webpack是如何实现模块化加载的方法
2019/11/06 Javascript
如何基于JavaScript判断图片是否加载完成
2019/12/28 Javascript
解决Echarts 显示隐藏后宽度高度变小的问题
2020/07/19 Javascript
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
浅析Python中将单词首字母大写的capitalize()方法
2015/05/18 Python
Python使用爬虫爬取静态网页图片的方法详解
2018/06/05 Python
使用pandas将numpy中的数组数据保存到csv文件的方法
2018/06/14 Python
numpy matrix和array的乘和加实例
2018/06/28 Python
python使用pandas处理excel文件转为csv文件的方法示例
2019/07/18 Python
python模拟哔哩哔哩滑块登入验证的实现
2020/04/24 Python
探讨HTML5移动开发的几大特性(必看)
2015/12/30 HTML / CSS
关于HTML5+ API plusready的兼容问题
2020/11/20 HTML / CSS
马来西亚在线健康商店:Medipal Malaysia
2020/04/13 全球购物
小学生成长感言
2014/01/30 职场文书
初中英语演讲稿
2014/04/29 职场文书
爱岗敬业演讲稿
2014/05/05 职场文书
2015年母亲节活动总结
2015/02/10 职场文书
Idea连接MySQL数据库出现中文乱码的问题
2021/04/14 MySQL
python如何利用traceback获取详细的异常信息
2021/06/05 Python
Linux中sftp常用命令整理
2022/06/28 Servers