本周一直在忙公司的活动项目,没有太多时间看一些额外的东西。总结一下近期公司 618 大促项目开发过程的一些笔记吧。


移动端及 PC 下各种兼容性的处理过程中,有不少的坑,下面是一些近期的开发总结:

如果只想某种样式在 IE6 下起作用,CSS 名前加 _,即如果只想在 IE6 下不显示,可以使用 _display: none;,只想 IE67 下起作用,前面加 *

1
2
3
4
5
6
7
.eq {
color:#f00; /* 标准浏览器 */
color:#f30\0; /* IE8,IE9,opera */
color:#a00\9; /* IE9 专属 */
*color:#c00; /* IE7 及 IE6 */
_color:#600; /* IE6 专属 */
}

PC 下,最大的问题在兼容 IE,这也要求我们书写规范的 HTML 结构。考虑到各浏览器本身对一些元素默认样式解释的不一致,在开发兼容性高的页面时,尽量不要滥用 HTML 语义化标签。另外, PC 下 inline-block 的 IE 兼容性也有问题,除 spana 外都不要用 inline-block,可使用浮动来做。

z-index 的使用需要配合 position: relative; 来使用。

浮动清除是一个老生常提的概念,页面开发(尤其是 PC)过程中,我们的商品图强和导航就需要用到浮动,但是,浮动元素的父结构上,我们需要对浮动清除(clearfix),以避免页面父结构高度的坍塌及排版的混乱。具体的 clearfix 方法,可以参考这篇文章。

对于定高的商品块,尽量使用 overflow: hidden 来对于超出高度外的内容截断,以避免干扰到其它元素块的排版。关于这一点,可以参考 BFC 的一些知识。

触发 BFC 的一些方法:

  • 根元素
  • float 属性不为 none
  • position 为 absolute 或 fixed
  • display 为 inline-block, table-cell, table-caption, flex, inline-flex
  • overflow 不为 visible

BFC 布局规则:

  • 内部的 Box 会在垂直方向,一个接一个地放置。
  • Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠
  • 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触 (对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  • BFC 的区域不会与 float box 重叠。
  • BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  • 计算 BFC 的高度时,浮动元素也参与计算

另外,如果文字只需要显示一行,而且超出范围就使用点号表示的话,最好使用

1
2
3
4
5
6
.text-hide {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
}

由于我们的商品图墙页面一般都是一个顶部加一系列的商品块,而商品块一般都需要贴着左边沿及右边沿来排列,这种情况可以使用父容器负的 margin 和 商品块 margin-left 样式组合来实现。可以套用下面的模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// scss
$item-width: 300px;
$container-width: 960px;
$item-padding: ($container-width - $item-width * 3) / 2;
.container {
margin: 0 auto;
width: $container-width;
.item-list { /* 需要在其上加清除浮动 */
margin-left: -$item-padding;
// clearfix
&:after, &:before {
content: " "; /* 1 */
display: table; /* 2 */
}
&:after {
clear: both;
}
*zoom: 1;
.item {
float: left;
width: $item-width;
height: 330px; /* 定高加 overflow */
overflow: hidden;
margin-left: $item-padding;
margin-top: 30px;
}
}
}

在写秒杀导航 H5 的时候,出现了一点样式上的小问题,记录一下:我将每一个导航块写成了 inline-block,但是块与块之间总是有一定的空白缝隙。解决方法也是有的:

  • 使用父样式上加 font-size: 0 来解决,这时块元素的 font-size 的继承性被破坏了,需要自己手工写。
  • 书写 HTML 的时候,块与块之间不要有空白,即要么将空白注释掉,要么全写到一行上。<div></div><div></div><div></div><!-- --><div></div> 即可。
  • 如果是在移动端或者只需要支持高版本浏览器,可以尝试使用 display: flex;,亲测有效。
  • 还有一种很鬼畜的方法,就是不要闭合块标签。不推荐。

H5 下,我们需要兼容不同尺寸的屏幕,这时,很多内容需要随页面尺寸动态变化。一般情况下使用分段式的 rem 替代 px:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*media rem 字体适配 */
/* 针对 360px 以上的屏幕做适配 */
@media (min-width: 360px) {
html{font-size:112px !important;}
}
/* 针对 400px 以上的屏幕做适配 */
@media (min-width: 400px) {
html{font-size:125px !important;}
}
/* 适配 480px 以上屏幕 */
@media (min-width: 480px) {
html{font-size:150px !important;}
}
/* 适配 540px 以上屏幕 */
@media (min-width: 540px) {
html{font-size:168px !important;}
}
/* 适配 640px 以上屏幕 */
@media (min-width: 640px) {
html{font-size:200px !important;}
}

补充(07.20):

上面的分段 rem 设置其实因为截断,会有一定的不连续问题。可以考虑使用 js 动态地设置 rem 大小:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// http://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript
function setPageRem() {
var width = window.innerWidth || (document.documentElement || document.body).clientWidth,,
rem = width / 320 * 100,
css = `html {font-size: ${rem}px !important; } `;
var head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
}

移动端开发的一些注意点可以参考 http://airjd.com/view/iaiw7wma000qwka#25

opacity 一般会造成背景和文字一起透明,所以必须使用 rgba,设置背景透明度(包含的图片、文字不透明):(注意 ie 和其他浏览器的不同)

1
2
background:none rgba(255, 255, 255, 0.6);
filter:progid:DXImageTransform.Microsoft.gradient(enabled='true',startColorstr='#99FFFFFF',endColorstr='#99FFFFFF');

解释:DXImageTransform.Microsoft.gradient 滤镜里的 startColorstr 参数值是 #AARRGGBB 形式的,其中的 AA(startColorstr 的前两位) 是代表不透明度的十六进制,00 表示完全透明,FF 就是全不透明,化成十进制的范围就是 0~255,剩下的 RRGGBB 就是颜色的十六进制代码。例子中 background:rgba(125,0,0,0.4); 表示的是 30% 不透明度的红色背景。如何把 40% 的不透明度转换成十六制呢?很简单,先计算 #AA 的的十进制 x,x/255 = 4/10,解得 x=4*255/10,然后再把 x 换算成十六进制,等于 66。

下面参照一张透明度十进制对应的十六进制的表:

1
2
3
4
5
6
7
8
9
10
11
0.0——00
0.1——19
0.2——33
0.3——4C
0.4——66
0.5——7F
0.6——99
0.7——B2
0.8——CC
0.9——E5
1.0——FF

TODOs

  1. 有空可以多看下流式布局和弹性布局。
  2. sticky 的细节

iScroll:

document.addEventListener('click', param, false);param 可以是回调函数或支持 handleEvent 接口的对象,这样做的好处在于,添加或移除事件的时候,可以使用 addEventListener|removeEventListener('evt', this, false)

在 iscroll 中,事件的触发顺序很重要,有时候,如果绑定了 tap 事件,可能会导致滚动的动画失效,其原因在于 tap 发生顺序有时候会早于 touchend,导致 tap 设置的动画时间被 touchend 回调给清除掉。

如果使用了 iscroll 中 snap 这个概念,就不要再使用 scrollTo 来滚动,使用 goToPage 来替代。