关于“大漠”的一点不好的记忆

关于大漠的一点不好的记忆。不过当年没搞清楚到底是哪个。发生了最近的事情,我觉得可能是这个……

我这个人不爱交际,在行业里一直是个小透明。

不过我当年也曾想试着改变一下自己,所以找了个前端交流群加了进去。具体的群名字忘记了,总之是“大漠”创建的群。

然后发现这个群真TM恶心。群主大漠有几个小弟,一副高高在上颐指气使的样子,对群里成员吆五喝六随意攻击,不仅对发问者提出各种限制,对回答者也提出各种限制。群主也是一副老子对你们这些废柴施恩,还不快快对我歌功颂德的气势。(具体做法记不清了,好多年了。)

然后我就受不了啦。如果前端圈子都这个吊样子,那我不交际也不要紧。于是吐槽两句自己退群了。

退了之后,想说这个大漠是谁啊,怎么这么差劲,然后搜了一下,发现叫这个名字的好多,无法确定是哪个,我也懒得跑回去确认。


发生了最近的事情后,我举得按人品和气度,有可能是这个……

准备搞一场专题直播

准备在 SegmentFault 搞一场专题直播,标题是《jQuery, Backbone, Vue》,计划通过对比老中青三代框架开发的差异,带领大家理解前端发展的趋势,接触更好的未来。https://segmentfault.com/l/1500000008694676 求关注,求购买。

准备在 SegmentFault 搞一场专题直播,标题是《jQuery, Backbone, Vue》,计划通过对比老中青三代框架开发的差异,带领大家理解前端发展的趋势,接触更好的未来。

直播地址:https://segmentfault.com/l/1500000008694676
幻灯片地址:https://meathill-lecture.github.io/jquery-backbone-vue/
范例代码仓库:https://github.com/meathill-lecture/jquery-backbone-vue

求关注,求购买。

一个超级诡异的 iOS Safari `position: fixed` 失效问题

iOS Safari 下,`input readonly` 仍然可以获得输入焦点,此时页面交互大部分正常,但 `position:fixed` 会受影响。

今天前同事李某找我咨询 Hybrid 开发的问题,想起来大前天搞这个问题搞了一天,赶紧记下来,省得忘记。

先说需求。东家让我做个日历组件,在手机 Web 上用。组件的样式是这样的,很多地方都可以见到,比如南航国航的客户端。

日历控件需求图

看起来并不复杂,事实上也是,基本上顺顺利利的开发完成,准备交付。这里有个伏笔,开发中我按老习惯,使用桌面 Chrome,和实际生产环境不太一样。不过我自然要去真机上测试,结果一测问题就出来了。

因为组件需要全屏展示,所以我设置了如下的CSS:

.date-picker {
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background-color: white;
  z-index:1024;
}

同时,对原本的 <input name="date">,我给它加上 readonly,避免弹出虚拟键盘。理论上,这样的就可以了。但实测时,不滚屏的时候,组件弹出时尺寸是准确的,盖满全屏;然则一旦滚屏,组件就会占据从页面最上方到当前最下面这截位置。大约相当于 position:absolte;top:0 的效果。

Safari 截图
手机截图
如图,可以看到组件占据了全屏,但实际是从页面最上面开始的,定位有问题。用桌面 Safari 调试也可以看出来它的高度是 968,远大于正常的 667。

这很诡异,上下左右全为0,是上古巨兽 IE6 都支持的做法。iOS Safari 虽然 Bug 多多,不应该连这个都有毛病啊。以 ios safari position fixed 为关键词 Google 之,结果 iOS Safari 历史不清白,当年 iPhone 刚出的时候的确有定位问题,于是虽有满屏的结果,但都不适用。

然后我想到找其它库,比如 Bootstrap,它的 Modal 组件也是类似的效果。但是怎么测都正常,于是我只好一个样式一个样式修改,仍然没有结果。

时间慢慢流逝,转眼已经凌晨2点了,就在我几欲放弃之际,突然发现,虽然组件弹出的时候定位有问题,但只要我点掉下面的完成,定位就会立刻恢复正常。

手机截图
注意,就是那个“完成”。

问题至此已经明朗:在 iOS Safari 里,即使 <input> 设置了 readonly,它仍然可以获取输入焦点。获取输入焦点之后,虽然没有弹出虚拟键盘,但仍然是待输入状态。

此时页面各种交互都是正常工作的,比如点击、滚屏。唯独 position:fixed 定位有问题。点击“完成”离开输入状态,Safari 自动刷新页面元素,定位就正常了。

于是我在组件弹出后,自动 input.blur(),使其失去焦点,组件的尺寸便正常无误了。


总结

移动端 Web 开发总有各种各样稀奇古怪的问题。有些好解决,有些不好解决,比如这个问题,很难定位:

  1. 历史不清白,搜也搜不到
  2. 组件要求全屏,需要避免虚拟键盘,所以会改变默认行为
  3. 其它情况下都是好的

我能想到的方案,就是想办法,用所有能用的工具,排除掉所有其它问题,最终还是能搞出来的。

FontAwesome 通过组合创建新图标

复合使用 FontAwesome 图标,创建符合需求的新图标。比如把“图片(fa-picture-o)”和“加(fa-plus-circle)”叠到一起,就可以创造”新增图片“的图标。

FontAwesome 提供了很多好看的图标,使用 WebFont 嵌入页面更是简单又好用,所以我基本上一直用它。不过有时候还是觉得不太够用,这就需要复合使用多个图标。

下面是个例子,我在图标的右下角增加一个圆形加号,表示增加、创建。

See the Pen add icon by Meathill (@meathill) on CodePen.

这里有两个选择:

  1. FontAwesome 提供了一个堆叠图标的样式:fa-stack,可以堆叠任意多的图标。
  2. 因为它实际上只占用了 :before,所以也可以使用 :after 来容纳新增的图标。如果只需要两个图标,这个方式更简单。

Bootstrap 4 发布 alpha 6

Bootstrap 4 发布 alpha 6 版本,在之前的基础上彻底拥抱 Flexbox,并对若干 class 和组件进行了升级。

这两天直播写 Meart 有点上瘾,博客好久没更了,公更私更都没更。刷推看到这则公告,小更一下吧。
图文无关,马上又要去台湾了,翻出来一张台湾公安局的照片阵楼。

Bootsrap 团队宣布 Bootstrap 4 推出 alpha 6 版本

如题。Bootstrap 4 alpha 已经是第六个版本了,我最近一直在用 alpha 5,感觉没有太大问题。

这次更新主要包含三个部分:

1. 拥抱 Flexbox

这个版本放弃了 IE9,从而可以彻底拥抱 Flexbox(之前的版本中,Grid 多半使用 display:tablefloat 实现,如果要启用 Flexbox,需要单独引用一个 bootstrap-flex.css)。

根据 CanIuse 显示,目前除了 IE 系列,大部分浏览器均已全面支持 Flexbox。

这次修改之后,绝大部分组件均已全面转向 Flexbox。

2. 加强布局和显示样式

增加了一批用于调整布局和显示的 class,这样从 Bootstrap 3 迁移也会方便一些。

这块儿我暂时没用到,没啥可说的。

3. 提升 Grid 布局

增加了更多的可控样式,可以调整 Grid 布局中的边距。

4. 升级导航栏

之前的版本中,导航栏还是个半成品,现在虽然不敢说是“完成版”,单也差不多了。

这个用途可能比较大,不过还没研究。


下次再发布就是 beta 版了,感觉离正式推出不远了。

Staticfile.org 搜索仓库还没更新,文件已经更新了。


感谢原作者和贡献者的努力,让我们得以用上越来越好用的开源框架,节省大量时间和精力,可以集中于更有产出的事情。


原文:Bootstrap 4 Alpha 6

Compass + cleancss 导致的灵异小问题

:blank伪类尚未被Chrome支持,会导致整条规则被忽略。

问题不大,不过很诡异。代码如下:

SASS:

.some-class
  display: none

.other-class:blank
  display: none

HTML:

<div class="some-class">...</div>

理论上说,这样这个div应该不显示。在本项目中,它的确没显示;但是在另外一个将本项目作为依赖的项目中,它却显示出来了。

经检查,本地开发和部署时,直接使用 compass compile 生成CSS,compass 配置中,设置输出模式(output_style)为 compressed,结果是这样的:

.some-class{display:none}.other-class:blank{display:none}

而在作为依赖时,用到的则是 grunt-contrib-cssmin 处理过的CSS,刚才那句就被压缩成

.some-class,.other-class:blank{display:none}

:blank伪类尚未被Chrome中支持,于是整条规则都被忽略,导致div显示出来。

啊,前端的轮子啊

学习新技术还是不要太激进,保持基础的了解即可。但是不关注也是不行的。

时势造英雄。

IT科技几十年来诞生过不少概念,但直接拿来就能作为宣传材料的不多,HTML5算一个。借助智能手机、微信微博快速普及带来的平台优势,HTML5快速成长,接连攻陷投资界、创业界、广告界,现在说起H5,在我的圈子里几乎无人不知无人不晓。

资金充裕,整个行业自然地位上升,财务上升;继而自然从业者增加;继而就会出产大量的产品。而作为前端从业人员,最大的感觉就是:轮子真TM多啊……这不,我前几天计划学习一下近来出现的各种新技术,今天正好看到Bable最新入门The Complete Guide to ES6 with Babel 6,正好我写xgame-api的时候饱受node不能完全支持ES6之苦,马上坐正准备好好看。

然后就看到:

Keeping up to date

Here’s a little story: while writing these guides, I learned that the require hook in babel-core used by Gulp and Mocha is already set to be deprecated.

跟上变化

讲个段子:就在我写这套入门的时候,babel-core里的require钩子,就是Gulp和Mocha使用的那个,被标记为“弃用”

Babel6是24天之前发布的,这套文章是上周写的,核心API已经发生变化了。这让我不禁去想,紧跟业界潮流的成本会不会太高了?ES6的确提供了不少语法糖,以及终于像样的模块管理。如果现在就开始使用ES6,不仅可以提前享受到这一切,到标准真正到来的时候,可以省去升级的时间。

不过这里面之考虑了标准变化,没有考虑需求变化和产品变化。如果是抽象性很强的代码,比如某种算法库,或者某个功能组件,那么从开发之日起,遇到的变化可能不会太多太大。但如果是业务代码,就不得不遭遇各种各样的修改和变化,于是功能稳定便于维护就更加重要。紧跟潮流,意味着必须付出多余的精力去应对各种不稳定导致的节外生枝,一不小心,业务逻辑就要延期交付鸟。

又有个切身例子。Tiger Prawn(后面简称TP)立项的时候,模块管理无论是AMD还是CMD还是sea.js都难以让人满意,所以我就用了最简单的直接引用和命名空间。前几日用Browserify感觉不错,赶上TP遇到个问题,就寻思着重构下。结果努力一天之后,架构变化还是太复杂,遂放弃。次日修正实际问题只花了半天。生产中,还是优秀的架构设计更重要,毕竟开发和维护效率至上;追新追潮流几乎都可以算是作死的行为。

那么什么时候学习新技术呢?程序员都应该做业余项目,不是私活,而是根据一些平日里瞎想出来的需求,用一些新技术去实现,即使实现不了,也能够实地演练各种新技术。这样,有朝一日新技术成熟了,就可以很快应用到新产品中。

新项目:诺兹多姆,时间的守护者

诺兹多姆是个专门针对后台的前端框架,能够覆盖各种后台的需求,也能提供漂亮的界面和良好的交互。

其实也不算新项目。加入点乐之后,我的主要任务之一就是做后台。我是个自视甚高的人,所以要做就做最好用的后台,经过不懈努力,现在的点乐后台V3.3版,无论从开发的角度还是使用者的角度来看,(应该说)都已经非常好用了。

不过问题仍然有很多,主要分为两方面:性能和弹性。

性能

先说性能,最初的版本是完全PHP的,用户操作都基于表单。我将其改成加载局部HTML片段,用户操作主要用ajax实现。显然,后台不可能停工,所以我边改边上线,架构上基本继承前人的设计,比如,大多数页面没有分页功能(很多同事用习惯了,也要求不要加分页)。

于是,大多数页面都要读取符合条件的全部数据,然后由Javascript实现排序、筛选、搜索等功能。当初我这么做的时候,公司业务量小,没什么问题;如今公司发展起来了,业务量越来越大,每次都加载全部数据,页面性能越来越差。尤其是手机端,很多页面一开就死。无奈之下,我只好先用Javascript分页顶着。

弹性

曾经懵懂少年的我动手时还不太会用Backbone,没有理解其精髓,只是觉得Backbone.View的事件代理比较好,写起来蛮舒服;更没想到借助Robotlegs的优秀设计开发Nervenet,所以前端架构上也有问题。比较严重的是数据同步(所谓数据双向绑定),即操作人员修改了某数据,保存到服务器后再回来,页面应该更新被修改的数据。那时候Knockout刚出来,Angular和Ember都还不堪大用,数据双向绑定对我来说只是个梦想。还好我码功扎实,也能解决的七七八八,比如主功能区共用一个Model作为中介(Mediator Pattern,中介者模式),数据交互都从它那儿走,其它组件监听change事件来更新视图。

不过这样终究不是办法,因为随着功能的增加,代码里各种写死的属性和方法越来越多,代码日益臃肿,弹性也是个大问题。

诺兹多姆诞生

恰在此时,新项目来了。新项目也需要后台,我当然不会直接把点乐后台拿来重用,而是花了一些时间剥离其中的前端框架,准备将其独立出来,成为一个新项目:诺兹多姆。

诺兹多姆,青铜龙之王,时间守护者。在炉石传说里,诺兹多姆将强制把每回合的事件降到15秒,这也是我的目的,无论用户要干什么,都能在很短的时间内——不妨假定是15秒——完成。

这是个专门针对后台的前端框架,能够覆盖各种后台的需求,也能提供漂亮的界面和良好的交互。等各种希望这个项目完成后,能够达到这些目的:

  1. 大大提高后台类应用的开发效率
  2. 前后端分离,独立开发,分开部署
  3. 丰富的组件,覆盖后台常用功能
  4. 灵活的插件机制,扩展能力强大
  5. 漂亮的界面,可以自由更换主题
  6. 全平台覆盖,甚至支持打包成移动应用

开源

此项目是在公司做的,当然要以公司的名义开源。当然,开源的结果基本上还是只有我们公司在用……

现在还在开发中,离最终目标还很远。

[github repo=”Dianjoy/nozdormu”]

致谢

此项目中用到了大量开源代码,感谢他们的创作者,是他们让世界变得更加美好。

感谢公司给我这个机会。感谢同事们让公司不断成长,给我留下尝试的机会。