前言
一直以来,我的前端技术栈其实都很弱。这并不是说我不会这些东西,而是非常的生疏。相关的理论其实我读过很多,但是实操很少。就导致,如果要我去做这些,由于手生,想得又多,就会非常慢。结果就是,前端基本都不会由我 亲自解决。也就造成了如今我前端手残的事实。最近虽然有意接触前端,但是秉承着,既然学就学最先进的想法。于是,我逐渐熟悉的前端技艺如何和公司项目产生联系就变得非常不好说了。直到现在,公司就剩我一个写软件代码的了。遗留下来的整个前后端包含移动端的项目,都等着我去做。就只能硬着头皮上了。我做的第一件事,就是在项目中加入gulp管理工具,要不然就太原始了,很难对项目的结构和过程进行管理。但是那个过程,没有记录在这里,在我的另一篇博客里https://www.jianshu.com/p/e8df7160facc。本博客纯粹是记录我改造前端功能代码的过程。
layer弹窗
这里是我入手改造项目的地方。因为其原来的弹窗全部是写在当前页面然后隐藏起来的。但是,我有个功能是管理监测单元的。随着监测单元型号的增加,这种做法带来了灾难性的复杂度。而且,当我希望在别的模块呈现监测单元的信息以及对其进行编辑的时候,前端工程师会告诉我这件事情工作量非常大。直到我现在看到了他的实现,我才意识到,他说的是真的,而我要做的是将其隐藏的页面放到单独的页面中去,然后用iframe引入进来。
基本思路
其实这里我纠结过两种实现。他们分别是将页面打入某个div或者直接使用iframe引入。最后,我选择了后者。为什么呢?直觉上我觉得前者可能更加符合前端的实现思路,而且我怀疑现在单页应用框架也是这个思路来的。但是,考虑到我的技能熟练程度和技术栈,后者对于我来说坑更少,上手更快,而我面临的问题无非是各种设计问题。
其中最主要的设计问题,就是如何在iframe里面和外面进行通信。这个,我借鉴了原来那个前端的思路,不过利用我的设计功底。我设计了一个部分视图管理器,里面有所有的部分视图的实例的引用。然后,这个管理器是存储在window.top的。所以,单一tab页中,所有的页面都可以找到它。剩下的无非就是生命周期管理的问题了,这是我的强项。
具体前端的问题
弹窗嵌套
其实实现的过程都很顺利,无非就是不断的调试。直到我出现了弹窗嵌套弹窗的情况时,我蒙了。
默认layer弹窗会在当前弹窗弹出。但是,如果我的弹窗里面弹出弹出框,由于是iframe嵌套,里面弹出来的弹窗框就只能存在于那个iframe里面。这就很尴尬了。官方文档没有找到这个问题的答案,但是网上的帖子找到了。其实在调用layer的时候如下:
layui.layer.open({
其实,前面这个layui就是个window对象,只不过是当前window的。所以,如果你把它换成parent,就是上一个window的。这样,这个困局的出路明显也就找出来了。就是,要管理自己的window树结构,在弹窗的时候选择合适的window对象。
iframe大小
默认情况下,iframe的大小是和内容无关的,于是可能就出来滚动条里三层外三层的情况。以下两种代码可以让iframe的高度和其展示内容完全一致:
<div class="iframe-wrapper">
<iframe name="iframe1" onload="this.height=this.contentWindow.document.body.scrollHeight" src="iframe1.html" frameborder="0" width="100%"></iframe>
<iframe name="iframe2" onload="this.height=iframe2.document.body.scrollHeight" src="iframe2.html" frameborder="0" width="100%"></iframe>
</div>
布局
之前都是对现有内容的改造和迁移,当我要自己写一个新的页面时,布局的问题是我遇到的第一个问题。于是系统性得补了一下。
display
我的学习地址:http://zh.learnlayout.com/ 下面是我根据我的目的学习的总结。
display的说明,这个很重要。
display的值 | 描述 |
---|---|
block | 块级元素默认为block。block会单独占用一行。 |
inline | 行内元素默认为inline。inline不会独立换行 |
none | 设置为none之后,元素将不会被删除,但是无法被看见。它和visibility: hidden; 的区别是,display设置为none后,元素不会占用原来的位置。而visibility就还会在那里,只是看不见罢了。 |
inline-block | 这会让这个容器里面block元素呈现出inline的特性,这样我们就不用使用float了,也就不用clear去清除了。这时vertical-align会影响元素的表现,我们可以使用它来做布局。 |
盒模型
这里主要是关于margine、border和padding的设置,外边距、线宽和内边距。这样很讨厌的是,总宽度需要根据你设置的width和这些数据相作用才能确定,而下面的代码可以让宽度是确定的。
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
有了上述代码后,宽度就是决定元素宽度的唯一要素了。可以试试看
position
这个属性说明了坐标会被怎么处理,而且有不少值,不好记,我整理如下:
值 | 说明 |
---|---|
static | static 是默认值。任意 position: static; 的元素不会被特殊的定位。一个 static 元素表示它不会被“positioned”,一个 position 属性被设置为其他值的元素表示它会被“positioned”。 |
relative | 相对定位。在一个相对定位(position属性的值为relative)的元素上设置 top 、 right 、 bottom 和 left 属性会使其偏离其正常位置。其他的元素的位置则不会受该元素的影响发生位置改变来弥补它偏离后剩下的空隙。 |
fixed | 一个固定定位(position属性的值为fixed)元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。和 relative 一样, top 、 right 、 bottom 和 left 属性都可用。 |
absolute | absolute 与 fixed 的表现类似,但是它不是相对于视窗而是相对于最近的“positioned”祖先元素。如果绝对定位(position属性的值为absolute)的元素没有“positioned”祖先元素,那么它是相对于文档的 body 元素,并且它会随着页面滚动而移动。记住一个“positioned”元素是指 position 值不是 static 的元素,也就是设置过position属性的元素。 |
flex | flexbox布局模式被用来重新定义CSS中的布局方式。遗憾的是它最近变动频繁,即使ie10或者ie11也不完全兼容,不过新版的edge和其它最新的浏览器都是兼容的。 |
其它一些属性
属性 | 说明 |
---|---|
float | 可以用来实现文字环绕图片的效果 |
clear | 使用这个值可以清除相应的漂浮方向(left、right、both)并把元素设置在漂浮元素的下方 |
overflow | 可以清除浮动。overflow: auto;兼容ie6的话,需要加入zoom:1。虽然清除浮动水很深,但是这已经基本兼容了所有的浏览器。 |
媒体查询
“响应式设计(Responsive Design” 是一种让网站针对不同的浏览器和设备“呈现”不同显示效果的策略,这样可以让网站在任何情况下显示的很棒!这用到的是@media,下面是个具体的例子:
@media screen and (min-width:600px) {
nav {
float: left;
width: 25%;
}
section {
margin-left: 25%;
}
}
@media screen and (max-width:599px) {
nav li {
display: inline;
}
}
说实话,我还不是很理解这些内容,不过,响应式布局就是它了。
多列布局
.three-column {
padding: 1em;
-moz-column-count: 3;
-moz-column-gap: 1em;
-webkit-column-count: 3;
-webkit-column-gap: 1em;
column-count: 3;
column-gap: 1em;
}
上述代码可以帮助我们在一个块里实现多列布局。不过这是一个很新颖的布局,所以它不支持ie9以下和opera mini
flexbox布局
在display设置为flexbox时,元素内为该布局。
额外收获
- 查阅兼容性的网站:https://caniuse.com/
前端的研发流程
昨天查了布局,今天先把布局搞定了,接下来就得给自己列个计划了,要不然我的拖延症肯定会发作得很频繁的。结合这段时间调整前端的经验,我觉得编写一个页面的过程应该主要分为这样几个步骤:
- 设计。其实我昨天下班前对今天的页面长什么样子是做过一番设计的。虽然没有做出高保真,但是,我做了原型,以确保我做的东西功能是完整的。不会做的时候通过调整代码来调整这些东西。
- 布局。其实,接下来就是按照原型把页面做出来了,但是是一个非常耗时且细节非常多的过程,所以也需要被切分。所以,第一个过程我写的是布局。这决定着我使用什么样的思维体系来看待接下来的页面中的各种元素,它们处于什么位置。
- 绘制。这看起来会是一个比较大的过程。但是,如果这个过程仅仅是让页面变成看起来需要的样子的话,可能也就没有那么可怕了。
- 交互。这个交互并不包含页面和服务器之间的交互,仅仅是对页面中会出现的操作编写js,确保他们能够把数据联动传入ViewModel中,并产生相应的效果。对的,这里要写ViewModel了,而ViewModel也是需要经历思考之后,再编写的,否则可能会陷入细节的挣扎。
- 联调。到这一步其实才是所谓的前后端联调。不过,能到这里才考虑联调的事情是基于在很早的阶段就把接口文档定好了,这样前端就可以没有什么顾虑的去设计ViewModel的交互逻辑了。对的,接口长什么样子,只会影响ViewModel的逻辑,不应该影响界面。至此,一个页面就完成了。
网友评论