经常用的几个javascript代码片段

刚到公司的时候,做了几个通用js组件,原生js写的,所以积累下一些比较好的代码片段,经过几次反复使用,质量还是比较有保证的。太长时间没写博客,这里分享出来刷刷人气。文章中的代码都在gist上同步了。


简单的模板引擎

Handlebars等模板引擎非常好用,但是比较重量级,对于组件来说显然是不合适的,这里分享个简单的模板引擎,原生js实现:

function templateEngine(tpl, data) {
    var reg    = /\{\{(?!\}\})(.*?)\}\}/g,
        regOut = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g,
        code   = 'var r=[];\n',
        cursor = 0,
        match;

    var add = function(line, js) {
        js ? (code += line.match(regOut) ? line + '\n' : 'r.push(' + line + ');\n') :
            (code += line !== '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
        return add;
    };
    while (match = reg.exec(tpl)) {
        add(tpl.slice(cursor, match.index))(match[1], true);
        cursor = match.index + match[0].length;
    }
    add(tpl.substr(cursor, tpl.length - cursor));
    code += 'return r.join("");';

    return new Function(code.replace(/[\r\t\n]/g, '')).apply(data);
}

使用方法也很简单:

var tmpl = '<p>'+
        '<span>{{ this.name }}</span>'+
        '{{ if( this.age > 18) { }}'+
            '<span>成年</span>'+
        '{{ } else { }}'+
            '<span>未成年</span>'+
        '{{ } }}'+
    '</p>';

var data = { name: '张三', age:17 };

var html = templateEngine(tmpl,data);

//....

js语句和模板混合使用。


安全字符串

上面的模板有个小问题,就是没有过滤html标签等“不安全字符”,下面在给一个方法,可以用来安全的输出html结构,是从Handlebars的源码中提取的,很简单实用:

function safeString(string) {
    if(!string) {
        return "";
    }
    var escape = {
        "&": "&amp;",
        "<": "&lt;",
        ">": "&gt;",
        '"': "&quot;",
        "'": "&#x27;",
        "`": "&#x60;"
    };
    var badChars = /[&<>"'`]/g;
    
    return string.replace(badChars, function(chr) {
        return escape[chr];
    });
}


强化window.onload事件

下面这个片段是在很久之前的代码中抽出来的,用来强化window.onload 事件的绑定

function windowOnload(fun) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = fun;
    } else {
        window.onload = function () {
            oldonload();
            fun();
        }
    }
}

使用windowOnload 函数,就可以多次绑定window.onload 事件,并且依次执行了。

–2014/12/10更新,翻看Evernote的时候,又发现几个不错的代码–


实例化函数技巧

如下声明函数,可以不使用new 关键字实例化:

function Uploader(options) {
  if (!(this instanceof Uploader)) {
    return new Uploader(options);
  }
}

使用的时候,下面两种方式是等效的:

var uploader1 = new Uploader(options);
var uploader2 = Uploader(options);


利用浏览器特性解析URL

来自:http://james.padolsey.com/javascript/parsing-urls-with-the-dom/

javascript处理URL还是比较麻烦的,这里巧妙的利用a标签一些属性,实现解析URL,上代码:

function parseURL(url) {
    var a =  document.createElement('a');
    a.href = url;
    return {
        source: url,
        protocol: a.protocol.replace(':',''),
        host: a.hostname,
        port: a.port,
        query: a.search,
        params: (function(){
            var ret = {},
                seg = a.search.replace(/^\?/,'').split('&'),
                len = seg.length, i = 0, s;
            for (;i<len;i++) {
                if (!seg[i]) { continue; }
                s = seg[i].split('=');
                ret[s[0]] = s[1];
            }
            return ret;
        })(),
        file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1],
        hash: a.hash.replace('#',''),
        path: a.pathname.replace(/^([^\/])/,'/$1'),
        relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,''])[1],
        segments: a.pathname.replace(/^\//,'').split('/')
    };
}

使用方法:

var myURL = parseURL('http://abc.com:8080/dir/index.html?id=255&m=hello#top');
 
myURL.file;     // = 'index.html'
myURL.hash;     // = 'top'
myURL.host;     // = 'abc.com'
myURL.query;    // = '?id=255&m=hello'
myURL.params;   // = Object = { id: 255, m: hello }
myURL.path;     // = '/dir/index.html'
myURL.segments; // = Array = ['dir', 'index.html']
myURL.port;     // = '8080'
myURL.protocol; // = 'http'
myURL.source;   // = 'http://abc.com:8080/dir/index.html?id=255&m=hello#top'

-暂时这么多,有了再补充-



标签: ,

  1. 有一个不理解,为什么生成对象的时候 不用new是好事? 我的理解是 ‘var uploader2 = Uploader(options);’ 这样的代码会让人不知道 这里是生成一个对象。

    • 1、js本来就是弱类型语言,写起来很灵活
      2、不是说“不使用new”是好事,只是这样写代码可以更健壮,不少类库都有这样的实现

无觅相关文章插件,快速提升流量