mvvm 学习&vue 实践小结
In 未分类 on 2015年06月27日 by view: 25,748
8

1 mvvm 学习

1.1 实现原理

mvvm 类框架的实现原理不复杂,大致如下:

  • 模板分析得到依赖的属性
  • 通过某种变动监测手段监测这些依赖的属性
  • 当属性变动的时候,触发相应的 directive 的处理逻辑即可

实际上,directive 的处理逻辑不一定是对 view 进行操作,比如上报。但是,在 mv 的思想下,建议对 view 的操作都集中在 directive 里实现

浅尝 iconfont
In 未分类 on 2015年05月30日 by view: 3,525
0

1. iconfont 简介

什么是 iconfont?正如字面意思,就是图标字体,下面我给大家慢慢道来

web 页面包含什么元素?

  • 文字
    • 链接
  • 流媒体
    • 视频
    • 音频
  • 图片
    • 背景图(大)
    • 插图(中,例如照片集,课程封面等)
    • 图标(小)

在所有包含 ui 的程序架构中,以上不同的 ui 元素在各种环境中都会遭遇到不同的问题,同时也都有与之对应的解决方案
iconfont 就是一个解决【图标】问题的解决方案之一

1.1 图标问题

首先来看一下图标会有什么难题:

  • 图标的大小会变,在两种情况下:
    • 每次 ui 改版,那些厌倦一成不变喜欢尝鲜的设计师们总是会淘气地改变图标大小,图标一般是点缀其他事物,例如文字,有时候设计会把某个图标从一段描述文字改成标题的点缀,这时候图标就需要变大
    • 自适应页面,整个页面的大小都在变,难道图标还能独善其身吗?
  • 图标会经常换,这点还是那些设计师的问题,他们说不好看要换,作为开发我们还能说什么?
  • 图标自身也会变,“来把那个图标改成红色吧,鲜艳点!”,“那个谁,把那个图标的底色改成蓝色吧~”,“…”

背景图和插图一般不会有这些问题,他们偏向于主体内容而不是点缀,一般不会改变。背景图一般是平铺,插图一般也是定宽,所以大小也不怎么需要改变。

1.2 图标解决方案

图标的解决方案有:

  • 使用 png 图片,这是最传统的方案,兼容性最好,使用方面基本不会有技术问题。但是它不够方便,主要有以下两个问题:
    • 只要图标稍有改动都必须换新的图片,即使只是换个颜色或者透明度
    • 图标大小改变问题,不管是改图标还是需要自适应。使用大图片会造成两个问题:缩放效率和大图流量浪费加载慢
  • 使用 svg 图片可以很好的解决图片大小的问题,但是兼容性是这个解决方案的致命问题,svg 不兼容 IE6~8,svg 不兼容 Android2.3
  • css,对于一些简单的图标,比如箭头,叉叉等,可以使用 css 来绘制而成,这也是现在移动端经常使用的方式,毕竟移动端对 css3 兼容性较好,但是利用 css 绘制的图片的问题是不能支持自适应,自适应的 css 会出现小数点,图标本身就是小的,所以当位置相差 1px 看起来都会很明显

1.3 iconfont 解决方案

iconfont 是图标的另一种解决方案,它是把一些简单的图标制作成字体,然后让图标变成和字体一样使用
iconfont 有以下优点:

  • 字体是矢量的,所以可以随意改变大小
  • 因为它是字体,所以所有字体的 css 都可以使用,比如 font-size,color,background,opacity 等
  • iconfont 的制作也很简单,现在有很多线上制作 iconfont 的站点,只要上传 svg 的图标设计稿,就能线上生成 iconfont 字体文件,而且连使用代码都直接生成
  • iconfont 没有兼容性问题,IE6,Android2.3 都能够兼容

2. 使用 iconfont

虽然使用 iconfont 没有图片那么简单,但也没有想象中那么难,下面来看看怎么使用 iconfont
首先,你需要制作 iconfont,现在有许多 iconfont 的站点,比如 fontello
我们随便选择一个图标:

然后我们可以自定义字码:

最后我们就可以下载字体文件了:

下载完,解压出来,我们可以看到有 demo,有字体文件,也有使用代码:

可以看到使用代码里面已经把各种兼容性考虑到了:

使用代码也给到,注意使用类名也是可以在站点中自定义的:

另外注意的是,字体文件也是可以内链的,在 fontello-embedded.css 文件里面:

基本上,利用提供的代码,基本我们就可以完全兼容的使用 iconfont,下面介绍移动端使用 iconfont,在移动端只需要如下代码:

在移动端,只需要 truetype 类型

效果如下:

使用 iconfont,我们可以应用许多字体样式,现在我们改变一下样式:

效果如下:

可以发现,改变一个图标的颜色,背景色,大小都是非常方便的一件事

另一方面,当需要改一个图标的时候,我们可以在制作 iconfont 的时候,替换掉一个图标即可,使用的类名和字码都是可以定制的,这样就可以在不用修改业务使用代码的情况下,只需要替换掉内链的字体代码就可以完成替换图标的工作

以上代码经过实机测试,兼容 IOS4,Android2.3
在移动端,iconfont 也可以使用外链形式,这里就不再赘述

3. 小结

在解决图标的问题上,不管是兼容性,灵活性,扩展性,iconfont 都是一个很好的解决方案

3.1 iconfont 优势

  • 灵活性,改变图标的颜色,背景色,大小都非常简单
  • 兼容性,兼容所有流行的浏览器,不仅 h5 可以使用 iconfont,app 也可以使用 iconfont,关于这方面可以查看其它线上分享
  • 扩展性,替换图标很方便,新增图标也非常简单,也不需要考虑图标合并的问题,图片方案需要 css sprite
  • 高效性,iconfont 有矢量特性,没有图片缩放的消耗高
  • 在使用上字体文件和普通的静态资源一样,既可以外链也可以内链,并且字体文件也可以使用 gzip 压缩
  • 在移动端上,可以只使用 truetype 类型,非常灵活小巧
  • 现在很多项目已经在使用 iconfont,先不说国外,比如国内,阿里巴巴各个平台(不仅 pc,h5,还有 app)已经全面使用 iconfont,并且阿里巴巴还搭建了一个线上 iconfont 站点,这是一个很完善的站点,上面有阿里几个主要业务的图标资源库,也可以让用户自己制作图标,完善用户自身的图标库,让用户之间可以共享形成生态,同时站点的使用说明也非常完整,从图标设计,iconfont 制作和 iconfont 使用(里面包含了各个平台的使用方法)都有很完善的说明

3.2 iconfont 缺点

  • 制作 iconfont 需要 svg 设计稿,对于开发来说没有图片来的方便
  • iconfont 有些特有的问题,详情可参考 @font-face and performance,不过许多问题在移动端是不存在的

3.3 结语

总的来说,iconfont 是可以应用的,特别是在移动端,如果不兼容 Android2.3,使用 svg 图片也是可以接受的,实际上制作 iconfont 也是需要 svg 资源的,所以两者其实很类似

另外,阿里巴巴主要业务都已经广泛应用 iconfont,并且还有成熟的线上站点支持,最起码在可行性方面是可以不用过多考虑的,虽然在使用 iconfont 的过程中可能会遇到许多问题,但是鉴于 iconfont 应用广泛的前提下,线上的资源也会非常丰富,应该不需要过多的担心

最后想说,我们业务是可以考虑使用的!如果要应用 iconfont,我们还需要设计们的支持!

:before,:after 伪元素妙用
In 未分类 on 2015年04月29日 by view: 9,864
1

这两个伪元素分别表示元素内容的【前】【后】,利用这两个伪元素可以在元素内容的前后添加内容,其实这没有什么前后的概念,如果应用了 absolute 的特性之后,你可以把这些伪元素放在任何位置,有了这两个伪元素,就代表每个元素都有两个助手可供使用,灵活运用它们的话将会得到很多有趣的实现,简化许多实现。

伪元素特性(目前已经遇到的)

  • 它不存在于文档中,所以 js 无法操作它
  • 它属于主元素本身,有些伪类仅仅是代表元素内容的一部分,譬如:first-letter 代表第一个字母;因此当伪元素被点击的时候触发的是主元素的 click 事件
  • 块级元素才能有:before, :after,譬如 img 就不能设置,亦即某些元素是没有:before, :after 的,只要知道一般的块级元素都可以用就行了

注:css3 中,为了与伪类区分,伪元素前应该使用两个冒号,即:hover 伪类,::before 伪元素。当然为了向下兼容,用一个冒号也是可以的,不过建议尽量使用规范的写法。

各种图标

利用这两个伪类,可以实现需要简单的图标,例如搜索的放大镜,叉叉,箭头等等

上述图标的效果如下图:

扩大可点区域

在 mobile,特别是小屏手机,可点区域一般需要大一点,这样对用户友好一点。
当主元素实在没办法扩大自身的时候,可以利用:before, :after 来实现可点区域的扩大,还记得伪元素的特性之一,伪元素属于主元素,点伪元素就是点击主元素。

实现效果如下图:

这个算是个综合例子,应用了多种技巧。这是一个收藏按钮,两种状态:已收藏和未收藏,正好符合 checkbox,因此应用了 checkbox,修改了样式给了一个底图。然后下面的文字是:after,利用了动态 label 的技巧(详见 1.4),然后:before 应用了扩大可点区域技巧,使得 40*50 的区域内点击都有效。

实现 label

对于一些静态的文字,说明性的文字,譬如最常见的上图下字单元,完全可以用:after 实现那个文字。
还记得 form 家族的 label 标签吗?它的特性是 label 和 input 的联动,点击 label 元素就等同于点击 input,这个效果和伪元素的特性是一模一样的,用:before 完全可以替代 label。

唯有一点是 label 独有的,就是 label 元素和 input 元素的位置相距较远,这种联动是伪元素无法实现的,毕竟伪元素还是要围绕主元素存在的,远距离 absolute 将会引发灾难的。

实现效果如下图:

实现动态信息

如果你认为伪元素只能实现静态 label,那就把 CSS3 想得简单了。
:before, :after 的 content 属性的值除了是静态字符串之外,还有其他的一些特殊值,其中一个是 attr(…),这个特性的作用是用主元素的某个属性的值作为 content 的值,当这个属性的值改变的时候,伪元素的值也会跟着改变,利用这个特性就可以实现动态信息了。

可以有两种动态方案:

  1. 用 js 动态修改主元素的属性值,这个很直观
  2. 修改伪元素 content 关联的属性

下面看一个例子:

实现的效果如下图:

这里用到第二种动态方案,日期列表里面,日期上面默认显示月份信息,但是选中态需要显示星期信息。
预先把每个单元用到的月份信息和星期信息放到主元素的 data 属性上面(缓存的思想),选中的时候一般都是要添加一个选中态样式,这时,除了基本的凸显性样式外,同时切换伪元素关联的 data 属性即可轻松地解决这个问题,而不用通过 js 去找到 label 元素,然后修改 text。

小结

伪元素帮助我们选择那些有特殊意义,但是却无法具体定位的 “东西”,它们对这些 “东西” 不做任何限制,它们只是代表这些特殊意义,譬如:first-letter,不限制首字母是哪一个字母,只是代表了首字母元素。

通过伪元素,可以让 CSS 更好的处理一些有特殊意义的元素,这些元素一般很难定位,甚至有些是代表状态的元素,譬如:target。

结合伪元素的特点,利用它们的灵活性,可以为我们提供更多的特性,下面总结一下目前想到的伪元素的优缺点:

优点/用途

  • 减少 dom 节点数
  • 让 css 帮助解决一部分 js 问题,让问题变得简单

缺点

  • 不利于 SEO
  • 代码读起来 “可能” 会有疑惑
iScroll 学习小结
In 未分类 on 2015年03月29日 by view: 1,406
1

前言

最近项目需要实现一个 fixed 标题栏的功能,很普通的功能,实现核心也是在 sroll 事件中切换到 fixed 状态即可,但是在某些版本 ios 的某些内核中,在惯性滚动过程中不执行任何 js 代码,亦即不会触发 scroll 事件,基本任何事情都做不了,为了解决这个问题不得不使用 div 内滚动,然后使用 iscroll 库实现滚动逻辑。

基于使用过程中的一些问题,抱着学习的态度,稍微看了一下源代码,现把学习所得记录如下。

源代码学习

核心实现

滑动相关组件(如 swipe 库)的实现基本都是类似的,就是通过 3 个核心事件:touchstart,touchmove,touchend 完成操作。

注:下面的源码只罗列核心部分,而且只展示 y 轴方向

touchstart 需要做的事情有:

touchmove 需要做的事情有:

touchend 需要做的事情有:

基本所有滑动相关的组件所做的事情都是这些,都可以借鉴一二的。

特殊 css prefix 缓存

用 js 处理特殊 css 的时候,可以先缓存 prefix,这样就不用每次都操作所有的内置属性

事件绑定

addEventListener 绑定事件可以传入一个对象而不是一个 cb 函数,事件触发的时候,就会调用该对象的 handleEvent 方法来处理事件。例如:

这种绑定方式的优点有:

  1. 删除事件方便
  2. 事件集中处理
  3. 程序结构清晰

还记得那种绑定事件时 bind(this) 的日子吗。。。
这种方式也方便了实现事件代理

事件触发频率调整

对于一些触发频率较高的事件,我们通常会控制一下事件处理的频率,例如 scroll,resize 事件。
另一方面,在实现一个公共组件的时候可以考虑从组件本身来解决这个问题,iScroll 通过配置来设置 scroll 事件的触发频率

缺点与使用问题

下面是针对版本 5.1.3 的 iscroll 使用过程中的一些问题

1. 没有插件版

iScroll 没有 zepto/jquery 插件版本,一些基础方法都需要自己实现,导致了库的体积偏大。

2. 没有暴露停止滑动(惯性滑动)的接口

通过查看源代码找到了停止滑动的方法,如下:

3. 调用 scrollTo 方法不会触发 scroll 事件

可以通过 scrollTo 方法来手动滑动,但是这样的滑动过程是不会触发 scroll 事件的。

总结

在使用 iScroll 的过程中遇到不少坑,但使用起来还是比较容易的,文档也比较齐全。
iScroll 在实现上也非常成熟,里面许多实现细节都是值得学习的