【冰极峰教程系列之三】:三层分离的完美九宫格
原创:冰极峰 转载请注明出处 时间:2009年6月24日 8:40:41
冰极峰教程系列之五:无hack并支持透明圆角框的全兼容九宫格布局
在我的前一篇教程《牢不可破的九宫格布局》中,我介绍了一种比较完美的九宫格布局方法,它能完全弹性地调整自己的宽高,从而实现比较灵活的布局风格。
然而为了弹性功能完美地体现出来,所付出的代价还是很沉重的,从结构上看,其结构是比较臃肿的,但是每个节点又是必不可少的,无法精简,否则会导致其灵活性不够。
在实战运用中,可能好多设计师并不喜欢这种布局结构,嫌其结构冗余。
一个完美的九宫格设计应该是一种三层分离的结构,我想达到的理想的九宫格应该是这样的:
1、 只需要应用一个class样式给想应用九宫格布局的容器,就能自动创建这种布局。结构应该足够精简,只用很少的结构就能实现丰富的颜色风格。
2、 能够将这种布局样式应用于一个页面的多个容器中。
3、 三层分离的设计,能提供丰富的颜色皮肤方案,便于将不同的样式应用于多个风格迥异的盒子上。
4、 要足够健壮,能兼容大多数浏览器。
因此,在这一篇文章中,我会将这种布局尽量向着这种理想化的境界靠近,让它更宜于应用在各个方面。
对于一、二点,又想要保持其灵活性,又想要达到精简的效果,就是说想“鱼和熊掌兼得”,除了应用js封装外,并无其它的办法。你可以说这是一种“掩耳盗铃”的做法,是的,我不得不承认,这种用JS封装的办法,从本质上说并没有精简其结构,只不过将其结构都用动态的方式来创建,但对冗余的html结构确实有立竿见影的效果,一下子就将所有冗余的结构化于无形之中。
我们还是从三层分离的做法中了解如何改进我们的九宫格吧。
【结构层】
这是我们要尽量精简的重点区域,我们用js的方式来动态创建其结构,所以现在的结构应该是如下的最最原始的结构了:
<div class="box" id=“one”>第二个九宫格盒子</div>
<div class="box" id=“two”>第三个九宫格盒子</div>
我唯一作了一点修改的是,将每一个盒子加了一个不同的ID,这为以后创建不同的颜色方式留下一个供样式表调用的钩子。通过这个ID在样式表中创建不同的图片或颜色风格。
我们应该只需要给div容器添加一个class=”box”,就会将九宫格布局成功地创建出来。这样是够简洁的了吧!
【样式层】
刚才在结构层中我们埋下了定制样式的突破点(那个不同的id),那么在写样式时就显得得心应手了。我们将所有的九个需要改变风格的地方的样式进行覆盖性重置,就能得到不同的风格样式。
#one .t_l{background:blue;}
#one .t_r{background:blue;}
#one .t_m{background:orange;}
#one .m_l{background:orange;}
#one .m_r{background:orange;}
#one .b_l{background:blue;}
#one .b_r{background:blue;}
#one .b_m span{background:orange;}
#one .context{background:#666;}
/*颜色方案二*/
#two .t_l{background:red;}
#two .t_r{background:red;}
#two .t_m{background:black;}
#two .m_l{background:black;}
#two .m_r{background:black;}
#two .b_l{background:red;}
#two .b_r{background:red;}
#two .b_m span{background:black;}
#two .context{background:#999;}
当然你可以将不同的图片应用于background上作为其背景,我只是为了演示方便而调用了颜色值而已,具体的界面风格就看你的设计功夫了。
【行为层】
我们在结构层中已经将所有用于创建九宫格的结构全部删除了,那么在我们就要在行为层(js)中动态的创建它。
在这里我们会遇到一个问题:我们想将所有应用了class="box"的div都用循环的方式遍历出来,以便于我们只需要一个class就可以自动应用这种九宫格样式,可是在js的dom方法中并没有一个已经存在的函数,就像“getElementsByTagName”一样通过一个标签名称来获得一个对象数组的方法,我想在这儿我们最想要的是一个如同“getElementsByClassName”(从字面的意思上是指:根据一个class类名获得一个对象的数组)的方法了。
因此在我们的js中就需要写一个这样的自定义方法:为了更贴近地表达的我们的意思,我们就将它取名为“getElementsByClassName”。
这个方法就是传递一个class类名,然后获得一个应用了这个class的容器的对象数组。
var j = 0;
var array = [];
for(var i = 0;(e = document.getElementsByTagName("*")[i]); i++){
if(e.className == theName){
array[j] = e;
j++;
}
}
return array;
}
获得了所有应用了这个class的div容器的对象数组后,我们就可以利用for循环遍历每个对象,然后分别给它内部装填我们刚才删除的九宫格结构。因此我们再创建一个函数,用来动态生成结构体:
function creatDiv(){
divs = document.getElementsByClassName('box');
for (var i = 0; i < divs.length; i++) {
var strhtml = divs[i].innerHTML;
//将结构体封装在这个变量中
var indiv = "<div class='top'><span class='t_m'></span></div><span class='t_l'></span><span class='t_r'></span><span class='m_l'></span><span class='m_r'></span><div class='context' id='m_m_" + i + "'></div><div class='b_m'><span></span></div><span class='b_l'></span><span class='b_r'></span>";
divs[i].innerHTML=indiv;
var dd1 = document.getElementById("m_m_"+i);
dd1.innerHTML=strhtml;
}
}
然后我们利用window.onload函数在窗体一加载时就加载这个creatDiv()方法。
window.onload=creatDiv;
这样在整个页面加载成功后,会自动将所有应用了class=”box”的div容器加载成九宫格的结构样式。
经过上述的一番改头换面的修改后,一个更健壮,三层分离的完美九宫格就被我们打造出来了。这种布局可以应用到很多地方,并且因为其强大的自适应功能和灵活多变的风格更受广大朋友的喜爱。下面是演示效果截图:
本模型在以下浏览器中测试通过:
IE5.5、IE6、IE7、IE8、FF3、TT、Maxthon2.1.5、Opera9.6、Safari4.0、Chrome2.0。
(PS:因博客园屏蔽页面中的js文件,请下载下面的文件到本地观看。)
下载:演示Demo