一个刚完成的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 相关文章推荐
jquery插件之信息弹出框showInfoDialog(成功/错误/警告/通知/背景遮罩)
Jan 09 Javascript
限制上传文件大小和格式的jQuery插件实例
Jan 24 Javascript
jQuery实现动态表单验证时文本框抖动效果完整实例
Aug 21 Javascript
JS简单实现DIV相对于浏览器固定位置不变的方法
Jun 17 Javascript
JavaScript暂停和继续定时器的实现方法
Jul 18 Javascript
js封装tab标签页实例分享
Dec 19 Javascript
js实现京东轮播图效果
Jun 30 Javascript
JS设计模式之数据访问对象模式的实例讲解
Sep 30 Javascript
js通过Date对象实现倒计时动画效果
Oct 27 Javascript
vue中如何使用ztree
Feb 06 Javascript
D3.js(v3)+react 实现带坐标与比例尺的散点图 (V3版本)
May 09 Javascript
vue组件中watch props根据v-if动态判断并挂载DOM的问题
May 12 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+mysql扎实个人基本功
2008/03/27 PHP
php error_log 函数的使用
2009/04/13 PHP
理解和运用PHP中的多态性[译]
2011/08/02 PHP
浅谈php命令行用法
2015/02/04 PHP
php取出数组单个值的方法
2018/03/12 PHP
laravel withCount 统计关联数量的方法
2019/10/10 PHP
PHP数组与字符串互相转换实例
2020/05/05 PHP
jQuery Migrate 1.1.0 Released 注意事项
2014/06/14 Javascript
javascript搜索框效果实现方法
2015/05/14 Javascript
jQuery实现ctrl+enter(回车)提交表单
2015/10/19 Javascript
第一章之初识Bootstrap
2016/04/25 Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
2016/05/16 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
2017/03/08 Javascript
JS中将多个逗号替换为一个逗号的实现代码
2017/06/23 Javascript
jQuery实现拖动效果的实例代码
2017/06/25 jQuery
Angular PWA使用的Demo示例
2019/01/31 Javascript
详解使用angular框架离线你的应用(pwa指南)
2019/01/31 Javascript
Vue data的数据响应式到底是如何实现的
2020/02/11 Javascript
Vue export import 导入导出的多种方式与区别介绍
2020/02/12 Javascript
vscode 调试 node.js的方法步骤
2020/09/15 Javascript
Python切换pip安装源的方法详解
2016/11/18 Python
python实现简易版计算器
2020/06/22 Python
Python实现的列表排序、反转操作示例
2019/03/13 Python
django mysql数据库及图片上传接口详解
2019/07/18 Python
python装饰器使用实例详解
2019/12/14 Python
sklearn的predict_proba使用说明
2020/06/28 Python
GUESS西班牙官方网上商城:美国服饰品牌
2017/03/15 全球购物
G-Form护具官方网站:美国运动保护装备
2019/09/04 全球购物
给定一个时间点,希望得到其他时间点
2013/11/07 面试题
汽车销售求职自荐信
2013/10/01 职场文书
《狼和小羊》教学反思
2014/04/20 职场文书
员工安全生产承诺书
2014/05/22 职场文书
六查六看六改心得体会
2014/10/14 职场文书
超级礼物观后感
2015/06/15 职场文书
会议简报格式范文
2015/07/20 职场文书
Vue 打包后相对路径的引用问题
2022/06/05 Vue.js