前言
接着昨天的内容写,为了保证内容连续性,这里还是把昨天的内容拷了过来。
请用现代浏览器测试
引出问题
有图有真相,我们来看一个智联招聘里面经常出现的图层:
他这个是没有什么问题的,我们来简单看看其实现:
View Code
复制代码
1 <div id="zbwJobSearch">
2 <div style="width: 710px;" class="sPopupDiv">
3 <div class="sPopupTitle213 sPopupTitle">
4 <h1>
5 选择职位</h1>
6 <div class="sButtonBlock">
7 <a onclick="return zbw.PopupDiv.allIns['buttonSelJobType'].fnClickAll()" href="#"
8 class="blueButton">不限</a> <a onclick="return zbw.PopupDiv.allIns['buttonSelJobType'].fnClickClose()"
9 href="#" class="blueButton">关闭</a></div>
10 <div class="clear">
11 </div>
12 </div>
13 <div class="clear">
14 </div>
15 <div class="sPopupBlock">
16 </div>
17 </div>
18 </div>
复制代码
他一开始便有一个容器在页面上,看着我们这个“zbwJobSearch”的容器,他是一个一般流的东西,里面放了3个绝对定位的东西,从这里看出,他这个不只是用于职位选择还有城市选择什么的。。。。
然后我们把多余的东西给去掉,点击了一下我本来以为会发送http请求什么的,重新获取数据,再生成我们看到的那颗树,但是解压js后发现这个东西好像被写到了js中,基本就是生成了这个东西:
生成的职位列表
他是一个表格,里面有很多事件!!!
我们这个td里面有一个span元素,给span了一个click事件,点击后会弹出我们要的结果:
然后进行最后的操作。
分析问题
好了,到了这里我们不知道我把问题解释清楚没有:
1 点击外部按钮便弹出了我们要的第一个弹出层。
2 点击其中的“加号”或者文字便弹出具有多选框的可选项
3 选择项目点击确定。
以上几个做完,我们的流程便结束了。
优化方案
不知从什么时间开始,我有了一点代码洁癖,看着这个代码我怎么就感觉有点不爽,他这个东西主要有以下问题:
1 table渲染速度慢
2 td/span有太多的事件,过多的事件绑定对我们的性能也有影响。
3 他的click函数全部写到了标签上(仁者见仁,我是非常不喜欢这样做)
其它
我们来看看,他其它地方其实做了一定处理:
<span onclick="zbw.PopupDiv.allIns['buttonSelJobType'].fnPopupChildren(this,['348','物流/仓储'])" class="availItem">物流/仓储</span>
为了防止命名冲突,我们看看这家伙定义的命名空间可长可长了。长到我都不想看了。。。。
好了暂时其它问题我这里还没发现,只不过我认为其中几个图片按钮相关可以用标签实现啦。。。
既然说都说了这么多,那我们不如先来写一个呗,写了再继续我们的问题吧!
实现职位选择功能
我们现在一起来实现这个职位选择功能,所以我们先分析下我们需要干些什么:
① 点击text在text处出现弹出层
② 弹出层出来后,我们点击其中的“加号”或者文字便弹出第三个弹出层
③ 选择第三个弹出层里面的checkbox项目最后点击确定后便将选择插入text(多项以分号分割)
若是想要优化的话,也许可以尝试点击后再加载数据再生成dom,一旦生成后便将dom缓存起来,我们这里作为demo就不搞那么多事情了。
第一步,准备工作
下拉选择文本
实现功能前,我们先准备一点点小东西,第一个就是长得像下拉菜单的文本框:
复制代码
1 <html xmlns="http://www.w3.org/1999/xhtml">
2 <head>
3 <title></title>
4 <style type="text/css">
5 .dropText { display: inline-block; border: 1px solid #B6B6B6; border-right: none; border-radius: 5px 0 0 5px;
cursor: pointer; margin-right: 20px; }
6 .dropText input { border: none; border-radius: 5px 0 0 5px; cursor: pointer; padding-left: 5px; }
7 .dropText span { display: inline-block; margin-right: -10px; width: 20px; border: 1px solid #B6B6B6;
border-radius: 0 5px 5px 0; margin: -1px -20px -1px 0; text-align: center; padding: 4px 0 4px 8px; }
8 .dropText i { display: inline-block; border: 6px solid black; border-color: black transparent transparent;
border-bottom: none; vertical-align: 3px; }
9 </style>
10 <script src="../../scripts/jquery-1.7.1.js" type="text/javascript"></script>
11 <script type="text/javascript">
12 $(document).ready(function () {
13 });
14 </script>
15 </head>
16 <body>
17 <div style="margin: 100px auto; padding-left: 100px;">
18 <div class="dropText" id="dropText">
19 <input type="text" placeholder="请选择职位" /><span><i></i> </span>
20 </div>
21 <span>dddd</span>
22 </div>
23 </body>
24 </html>
复制代码
我们来看看我们形成的这个框,这个在现代浏览器还能看,而且各位千万不要小看这个东西,这个东西真不像各位想象那么简单,比如我这个代码就有很大的优化空间!
PS:各位看到我的span里面多了一个 我为什么会这么做?不这么做有什么影响?i被设置为inline-block对整体行对齐有什么影响,这块代码还可以如何优化?这个问题暂时留给各位了,我们下来再一起解决,这个对行内元素的理解有莫大的帮助,请各位动手吧。
十字开关
复制代码
1 <style type="text/css">
2 /*十字开关*/
3 .croSwitch { display: inline-block; border: 1px solid #108efe; border-radius: 4px; width: 16px;
height: 16px; text-align: center; position: relative; cursor: pointer; }
4 .croSwitch i { background-color: #108efe; border-radius: 6px; position: absolute; }
5
6 .croSwitch .horizontal { width: 12px; height: 2px; left: 2px; top: 7px; }
7 .croSwitch .vertical { height: 12px; width: 2px; top: 2px; left: 7px; }
8 .cls .vertical { display: none; }
9 </style>
10
11 <span class="croSwitch"><i class="horizontal"></i><i class="vertical"></i></span>
12 <span class="croSwitch cls"><i class="horizontal"></i><i class="vertical"></i></span>
复制代码
虽然很丑但是很温柔。。。
Ps:请思考若是外层span不设置高度会有什么后果
好啦,小东西大概懂弄好了,我们现在来组织职位的dom结构吧。
职位列表样式
我们首先根据上面的表格,使用jquery操作他生成如下结构:
最新的结构
好了,我们现在来调整一下样式。
由于这个家伙着实太丑了,我放弃了,我这里上传个图片好了。。。。
可运行代码:
基本列表样式
PS:第三个坑,不知道各位发现没,就算使用背景图片,我们的小图片看上去感觉还是有一些问题呢,我们是不是应该看看呢?
好了,我们将我们第一阶段的代码连起来:
带交互代码
三层弹出:
我们在样式上做一点优化,加上鼠标hover效果,其它暂时不管。于是我们来看看他点击时候再弹出功能如何实现呢?我们这里看看原来的代码:
<span onclick="zbw.PopupDiv.allIns['buttonSelJobType'].fnPopupChildren(this,['306','生产/加工/制造'])" class="availItem">生产/加工/制造</span>
我们看着,他这里有一个id,所以我这里有这样一个实现思路:
① 这个id必定对应着自己的id,我们根据此id可以选出其子项(根据省id可以得出市id)
② 由于他这个数据是一次性读出的,所以父级id对应子项应该已经缓存起来了,可以是字符串,也可以是dom结构
③ 然后我们这里先预先定义一个这样的结构:
复制代码
1 var jobListObj = {
2 '1': 'dom',
3 '2': 'dom',
4 '3': 'dom',
5 '4': 'dom'
6 }
复制代码
现在的逻辑便是,我们点击“加号”或者文字,从而获取我们的id(1-4),我们根据id获取dom,我们再定位我们的dom在应该出现的位置,整个逻辑结束。
于是我们来测试下我们的思路是否正确,因为原来就没有绑定id上,我们现在为四个角搞一个id即可,四个方向上能正常显示,我们这里就不管了。
PS:写到这里其实已经离题了,想说的问题还没说呢,我们其实没必要实现这个功能的,但是都走到这一步了只能硬着头皮写下去了。。。
最后形成的代码:
View Code
演示效果,可运行(友情提示请使用IE9+)
咳咳,离题离的离谱
昨天最初想写的东西和以上的东西没有多大关联,偏题偏得离谱啊!!!
我当时很臭屁的认为自己能1,2个小时完成这个功能来着,最后发现这家伙还真不是那么简单的。。。这不,今天又花了2个小时才搞出这么一个四不像的东西,而且我也不想继续搞这个了,因为这次的主题不是这个,职位选择框我们暂时就这个样式吧,以后有机会再形成插件。
现在我们开始进行下一步探讨,看看问题出现在哪。
正文开始
我们看到,这个职位选择框,其实本身没有什么问题,但是卡了组员1.5天的东西到底是什么呢?
其实是需求,因为需求变更,原来放在页面上,好好的元素,现在被放在了一个弹出层里面,于是各种各样的问题都出来了。。。。
① 弹出层的遮盖层z-index过大,遮盖了我们的职位层
② 弹出层本身的z-index过大,也遮盖了我们的职位层
但是以上两个问题都比较好处理,比较难处理的出来了:
这个项目之前的项目人员并不是像我这样将各个弹出层独立出来,都是以body为包含快(containing block),而是放在了一个div里面
并且将这个div放进了弹出层那个容器里面,于是我们来看看可能出现的问题:
① 由于absolute的包含快有所不同,其依赖最近的布局元素,所以之前js计算位置的方法可能失效
② 不知道原来处于什么考虑,代码中div容器布局为relative。。。。。其定位方法十分诡异
③ 奇怪的现象就是二级弹出层正常显示,三级弹出层你压根找不到!!!
以上便是组员遇到的问题,还有一个客观的因素就是原来的js依次分布到三个不同的地方,然后代码又全部压缩过了,我处理的时候还需要解压什么的,而且原来的代码中有很多地方没有分号,没有报错真是个奇迹(其实经常出现莫名的js错误啦,总之坑很多)。
我看着代码后不一会就发现了问题所在,问题本身并不难,解决也比较轻易,但是知不知道就很重要了。
原来实现思路:
① 由于装第一个弹出层的div是relative定位的,所以他定位到下拉框的实现方法和我们想象的不一样,是相对于div的位置,而不是body
他这个实现方案,我们不予评价,但是就这种方法要伤害多少我多少脑细胞,我就确实不想去想了。。。这里我居然还有点佩服原来开发的思维能力了。。。
② 他第一步,弹出层居然还能精准定位到下拉文本,但是当他再点击弹出层里面的文字准备弹出最终的东西时,终于开始悲剧了。。。
我那两个倒霉的组员要干神马事情呢,他们面临的又是什么呢:
① 在绝对定位弹出层上面(parent)有个正常流文本下拉文本框与div容器(div),并且该容器是relative定位的
② div中有2块弹出层(tan1,tan2),点击parent上面的下拉文本便弹出tan1,并且其定位必须精准,1像素只差都会很难看
③ 在tan1出来后,便点击tan1中的文字,根据该文字元素定位tan2
PS:不知道你们晕没有,反正我是晕了
人家这个插件本来是用于普通流的,其根元素为body,但是现在搞到弹出层里面来了,所以出现了这些问题。
我最后就直接总结了一下他这个最大的问题,就是实现过于复杂,所以昨天才忍不住自己写了一个(虽然效果不好。。。)
当然,最后我的解决方案更加诡异,这里就不说明了,因为没有什么意义,但是根据这个东西,我却提炼了一点点很有意思的东西与大家分享呢。这也是组员找不到问题的原因。
relative与鼠标点的定位
有例子有真相!!!
View Code
各位看看我们这个代码干的事情:
复制代码
1 <html xmlns="http://www.w3.org/1999/xhtml">
2 <head>
3 <title></title>
4 <style type="text/css">
5 body { font: 12px 'PTSansRegular',Arial,Helvetica,sans-serif; background: #D1D1D1; }
6 ul, li { margin: 0; padding: 0}
7 li { list-style: none; }
8
9 #tabs_container { width: 400px; height: 200px; background: white;}
10 #tabs { border-bottom: 1px solid #1C87D5; padding: 5px 5px 0; width: 690px; margin: 0 auto; }
11 #tabs li { padding: 5px 10px; cursor: pointer; display: inline-block; background: #1C87D5; color: White; }
12 #tabs li.sec { color: black;}
13
14 #parent { width: 700px; height: 400px; background: white; margin: 0 auto; position: relative; }
15 #parent div { filter:alpha(opacity=50); -moz-opacity:0.5; opacity:0.5; font-weight:bold; background: red; position: absolute; }
16 </style>
17 </head>
18 <body>
19 <ul id="tabs" >
20 <li type="draw" class="sec">画矩形框</li>
21 <li type="drag">拖到矩形框</li>
22 </ul>
23 <div id="parent">
24 </div>
25 <div id="state"></div>
26 </body>
27 </html>
复制代码
① parent容器的定位是relative
② 我们在parent里面画的div是absolute
③ 但是,我们div定位是根据鼠标的x/y确定的,而这个是相对于body的,所以我们这里会错位(因为div是相对于parent布局,不是body)
④ 为了解决错位问题,我们便要用x/y减去parent的offset top与left
此块单独处理问题不大,就怕页面中弹出层过多时候导致你已经分不清谁是谁的包含快了,所以便会出现错位问题,这也是同事迟迟不能解决问题的症结点。
z-index
扩展知识:http://www.qianduan.net/that-thing-on-the-z-index.html
说道定位就不得不提z-index,这个家伙在IE7以下又是一个坑爹的货,了不起哪天各位又会碰到,反正我组员就碰到了,在IE7下,这个就是个混蛋!!!
关于html堆栈的那块,各位可以看看博客园寒冬的博客,堆栈顺序对z-index影响很大,我这里就不描述了。
我们遇到z-index时候,会很天真的认为z-index设置的越大时候,便应该更靠近我们,但是定位元素多了后,却总是发现这样那样的bug一大堆!!!(IE7以下尤其恶心),具体这块的拓展可以看看聂微东大哥的博客,关于z-index的描述已经十分详尽了,我这里简单说下:
每一个定位元素都有其根元素,当根元素为定位元素时,该元素的子元素若是也出现定位元素,子元素将受到父元素z-index的制约。
借用东哥一句话,元素要靠前也是拼爹的!
inline与inline-block
关于PS中的问题,感觉没人关注,我这里也不花精力去描述了,但是有个东西应该提出来:
我们上次说了,其实IE6/7是支持inline-block的,只不过块级元素对其支持不是很好罢了,但是我这里想把inline-block再一次提出来说一下,因为我们可能被他的名字迷惑了!!!
inline-block便应该包含inline与block的特性,对不!
是的,他包含了block的特性,但是我不认为他包含了inline的特性,因为inline的特性的核心是inline boxes,那么我们的inline-block拥有吗?
PS:答案是拥有的,我私下搞了半个小时,昨天以为没有inline boxes,以为发现新大陆了,丢人啦,,,,
结语
我今天又唧唧歪歪说了一大堆,也不知道各位有没有什么收获呢,明天我们还是一起来研究点有意义的事情吧,我感觉我对行内元素还是不够熟悉,明天我们就一起看看行内元素哇?
本文转自叶小钗博客园博客,原文链接:http://www.cnblogs.com/yexiaochai/p/3141582.html,如需转载请自行联系原作者