非等宽图片列表的布局

各大搜索引擎的图片频道的搜索结果页,搜索出来的结果都是较零碎的图片,图片质量、尺寸都是参差不齐的,并限定了每一行的总宽度。这种非等宽的图片列表,在Google+、flickr也都有用到。

searchlist_demo

最近刚好对360搜索的图片搜索结果页进行了一次重构和改版,对于这种图片布局也花心思研究了一番,接下来说说我的一些处理思路。

非等宽的单个图片要排列到一个固定了宽度的容器中,那么这个等宽的容器就是最大的限制和障碍,开始怀念那种常见等宽瀑布流的布局(没有限制真好)。

先理下基本的需求:

  • 1、图片的宽度是不固定的;
  • 2、图片的高度是固定的;
  • 3、每行图片的总宽度是固定的,所以每行能容纳的图片的数量是无法确定的;
  • 4、确保图片质量不变,不能有拉伸变形导致图片失真的情况出现;
  • 5、图片之间的间距是固定的;
阅读全文 »

浅谈DOM事件的优化

在 JavaScript 程序的开发中,经常会用到一些频繁触发的 DOM 事件,如 mousemove、resize,还有不是那么常用的鼠标滚轮事件:mousewheel (在 Firefox 中,滚轮事件为 DOMMouseScroll)。

浏览器为了确保这些事件能够及时响应,触发的频率会比较高,具体的触发频率各浏览器虽然有出入,但出入不大。很多时候在需要注重性能的场景下使用这些事件会想各种办法对事件的触发频率进行优化,下面说说我的一些优化方法。

mousemove 在拖拽中的优化

拖拽( Drag )是很常见的一个功能,在浏览器还没实现原生的拖拽之前,通过 mousedown、mousemove、mouseup 3种事件类型就可以模拟出拖拽效果来,当然这里不谈如何去实现一个拖拽功能。

mousemove 事件在拖拽的应用中既要确保拖拽的流畅度,又要确保拖拽时的性能,如何保持两者的平衡呢?

阅读全文 »

模块加载器的进化–并行加载

easy.js的模块加载器的详解(如果你没有阅读过,最好是先去阅读下,这样才能更好的理解这篇博文)中我详细的介绍过有关 easy.js 的加载器的实现。其加载和执行的顺序都要严格依赖队列一个一个的加载和执行,这种加载和执行方式就是串行。此文将介绍模块加载器并行加载的实现。

在讲解并行加载的实现原理之前,首先有必要对 JavaScript 文件的加载的执行有一个初步的了解。

JavaScript 在页面渲染时可能会对 DOM 元素进行修改,并且多个文件之间还会有依赖的关系,因此必须严格按照顺序依次执行,正是由于此种特性就势必对之后的页面资源的加载造成阻塞。但是请注意,这里说到的是按顺序执行

由于 JavaScript 阻塞的特性,也影响到浏览器对 JavaScript 文件的加载,在老版本浏览器中,加载完就执行,执行完再加载,这正是上面说到的串行加载。为了提升性能,在现代浏览器中,如新版本的 Firefox 和 Chrome,将加载改成了并行。并行加载允许一次性同时加载多个文件,在 HTTP1.1 中,多个文件并行加载只需要发起一个 TCP 连接数。试想下,一条流水线依次生产十个产品肯定要比十条流水线同时生产一个产品要慢得多。虽然在现代浏览器中可以实现并行加载 JavaScript,但是其执行顺序还是要按照顺序来执行的。

之前的 easy.js 的模块加载器的确是按照老版本浏览器串行加载和执行的思路来实现的,而最新版的模块加载器就是按照现代浏览器的并行加载,串行执行的思路来实现的。

阅读全文 »

使用Promise模式来简化JavaScript的异步回调

网页的交互越来越复杂,JavaScript 的异步操作也随之越来越多。如常见的 ajax 请求,需要在请求完成时响应操作,请求通常是异步的,请求的过程中用户还能进行其他的操作,不会对页面进行阻塞,这种异步的交互效果对用户来说是挺有友好的。但是对于开发者来说,要大量处理这种操作,就很不友好了。异步请求完成的操作必须预先定义在回调函数中,等到请求完成就必须调用这个函数。这种非线性的异步编程方式会让开发者很不适应,同时也带来了诸多的不便,增加了代码的耦合度和复杂性,代码的组织上也会很不优雅,大大降低了代码的可维护性。情况再复杂点,如果一个操作要等到多个异步 ajax 请求的完成才能进行,就会出现回调函数嵌套的情况,如果需要嵌套好几层,那你就只能自求多福了。

阅读全文 »

easy.js的模块加载器的详解

模块加载器的实现方法应该比较多,主要还是看哪种实现起来更简单,更易扩展。对于遵循不同规范的模块加载器,实现原理又千差万别。不管是用哪种实现方法,最终都是要满足模块加载器的那些最基本的功能。那么模块加载器的最基本的功能基本就可以概括成下面这几点。

  • 定义模块
  • 处理依赖
  • 加载模块

定义模块

define( "hello", function(){
 return "hello world";
});
阅读全文 »