前面一段时间在继续深入优化diigo流程时,遇到了需要在js中写入大量HTML来作为ajax完成后的处理。

内容短的html直接写入js中还算合适,但随着html越长,便开始难于阅读和维护,即使像webstorm对HTML string有较好的书写支持,但仍不够。

后来想到以前diigolet的项目中,也有同样的问题,diigolet那边的做法是将所有的html写到一个template.html文件中,用注释表明变量模块,然后最终在build时使用rakefile来把html文件中的块读出并合并到js文件中作为一个string变量。

现在有grunt,理论可以用node更简单的做这样一件事情,便花了一天时间写出了一个grunt task。

https://github.com/Yixi/grunt-YHtmlToJs

在package.json中加上依赖:



“y-html-2-js”:”latest”


然后


npm install

详细用法参考github readme

所有前端开发者被js的异步编程折腾不是一天两天的事,复杂的回调嵌套和回调条件判断都会产生一些不易于阅读维护甚至潜藏问题的代码。

Common JS提出了一种 Promises/A的建议来解决这个问题,一是易于阅读维护,其次是防止回调堆栈太深错误不易抛出的问题。

现在成熟的库都有自己的基于Promise的实现,比如jQuery的deferred机制,但感觉用起来最顺手和直观的还是在做win8开发时的WinJS实现的promise机制,后来终于有空尝试基于winJS的设计实现了一个简单的Promise库。

https://github.com/Yixi/YPromise

简单使用如下,更详细的请参考github

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
function fun3(){
return new YPro(function(comp,err){
setTimeout(function(){
comp('fun3 done');
},3000);
})
}
function fun4(){
return new YPro(function(comp,err){
setTimeout(function(){
comp('fun4 done');
},1000);
})
}
var aPromise = fun3()
.then(function(d){console.log(d); return fun4();})
.then(function(){return fun3();})
.then(function(){return fun4();})
.done(function(){
console.log("fun3->fun4->fun3->fun4 done");
})

setTimeout(function(){
aPromise.cancel(function(){
console.log("Promise canceled");
});
},9000);

在看seajs源码的时候,看到里面一个数组去重的方法太巧妙了。

 

//定义foreach。 ES5中数组扩展了foreach方法。

var forEach = util.forEach = AP.forEach ?
      function(arr, fn) {
        arr.forEach(fn)
      } :
      function(arr, fn) {
        for (var i = 0; i < arr.length; i++) {
          fn(arr[i], i, arr)
        }
      }

//去重算法
util.unique = function(arr) {
    //声明空数组ret,空对象o
    var ret = []
    var o = {}

    //将数组对象执行forEach方法,得到去重后的对象o
    forEach(arr, function(item) {
      o[item] = 1
    })

    //对象以键值数组化
    if (Object.keys) {
      ret = Object.keys(o)
    }
    else {
      for (var p in o) {
        if (o.hasOwnProperty(p)) {
          ret.push(p)
        }
      }
    }

    //返回数组
    return ret
  }

simple gray3

 

昨天晚上花了几个小时时间把博客主题做了一些改动,整体设计改动不大,主要在原主题的基础上添加了响应式支持。

有兴趣的可以用iPhone和iPad分别横向和竖向查看网站。

为了更好的支持响应式设计,将原来的CSS文件完全重写,所以可能有一些细节地方的CSS并没写到可能变现很诡异。

主题内容并没有采用液态内容的方式来支持响应,而是计算了11栏的栅格来做各种宽度的基本框架。因以前文章中的图片img标签中都写死了width 和 height,所以用js删除掉了图片的width 和 height 属性来支持液态图片。

 

先放上未完成的chrome文档访问地址:

Chrome插件中文开发文档(非官方)

 
因为某些上网障碍,以及部分人的英语障碍,导致很多想做chrome插件开发的童鞋无法访问和正常理解chrome插件的开发文档。

很多人在开发的时候选择了360翻译的那份文档,但那份文档因为很久没更新,和现在chrome的文档已经有很大差别。

所以用360那份文档来做Chrome的插件开发,基本上没有任何参考价值,甚至导致你按照360文档中的教程写插件根本没法正常载入。

尤其是在chrome在mainfest V2版本的改动上。

有位网友 Samuel V 做了一份很好的现在版本的chrome翻译,host在google site上面,但同样,因为一些网络访问障碍,并不能正常访问。

基于在chrome插件/应用程序两年多的开发经验上,故,希望尽最大的能力重新做一份搬运到墙内版本的chrome文档,并基于Samuel V的翻译版本做翻译。

因为翻译是一项体力活,即使有一份很不错的翻译版本作为参考,但为了保证和原文档所有样式和链接进行对应,所以其中细致的工作量比较大,所以需要完全完成翻译还需要花一段时间。

开始本来是打算将所有页面翻译完成后再放出,但发现需要全部完成翻译并不是一天两天的事情,所以先放出一个未完成的版本,让需要的人能够在墙内访问一份与官方接近的文档版本。一有空余时间我都会更新翻译内容。

你也可以在Github中clone一份来本地访问 https://github.com/Yixi/ChromeExtensionDocument ,也希望有朋友能和我一起贡献中文翻译,请用email联系我: lyh1112(at)gmail.com

文档遵循cc by 3.0

contenteditable 的 div 内容标签格式化问题,以前在做quick note的时候都有遇到过,因为会遇到从网页中拷贝内容进去,或者拖拽内容进去。在这种情况下,在div的编辑区域会保留原页面内容的DOM结构以及样式,即使从其他地方复制一个纯文本内容也会产生一个inline的div标签。

之前在quick note中为了保证内容是纯文本的text,在每次内容变动时都会使用一个函数来去掉内容中多余的标签。当时借鉴了readability中的一个算法,通过递归来逐层去掉内容中的标签。但这个算法在处理过大的内容时,明显会有较长的时间延迟,并不是一个最佳的方案。

最近在研究一个新的项目时,遇到同样的问题。想到以前的quick note中的问题,想重新找一种方案来实现文字的clean处理,以前是找出element标签来通过正则去掉标签,效率自然低下。是否可以尝试通过递归将div中的textNode内容提取出来再处理呢?

简单尝试了下,确实可行,但文字按照原顺序重组的却遇到了问题,特别在那种块级标签包含行级标签的内容中(应该是我想的还不够透彻,所以暂时没有管这个问题)。

这时候却让我突然想起了<pre>标签。

<pre>标签中的内容是预格式化的文本标签。

当把内容放进去过后,让我很是高兴,无论拷贝什么内容进去,最后保留下来的便是纯粹的text内容。根据这一特性,写出了一个新的处理clean内容的办法。

 


//base on Jquery;
//use  var clearn = $(this).getPreText();

$.fn.getPreText = function () {
    var text = $("
").html(this.html());
    if ($.browser.webkit)
        text.find("div").replaceWith(function () { return "\n" + this.innerHTML; });
    if ($.browser.msie)
        text.find("p").replaceWith(function () { return this.innerHTML + "
"; });
    if ($.browser.mozilla || $.browser.opera || $.browser.msie)
        text.find("br").replaceWith("\n");
    return text.text();
};

DIV中可能会产生标签的情况是可以列举出来的,我们只需要控制固定的来源就行了。比如这个方法我们可以监听到ctrl+v时间时再来执行。
当然,还有其他很多种来源都会产生标签的,比如回车,会产生一个新的div,等等。如果需要保证内容纯文本,还需要监听各种来源情况,这是后话,以后再谈。

复制数据很简单。

var a = jsonobj;

简单的就将jsonobj的值复制到了变量a中,但如果jsonobj是个json数据的话,你会发现修改a的值时,jsonobj也会跟着改变。

如果你对javascript中的prototype那套机制比较了解的话可能就会大概明白是怎么回事,是的,因为json其实也是个object,所以var a = jsonobj 赋值时,中间有个原型链会将两个关联起来。

要达到想要的复制数据也很简单:

var a = JSON.parse(JSON.stringify(jsonobj));
将json序列化为string再还原成json,因为中间产生了新的对象,所以两者不再关联。

这种写法看起来很不科学,但应该是比较好的办法了。