简洁的html5 Slides Show(类ppt)

展开/收缩

由于最近准备分享chrome Dev Tools ,就简单弄了个基于html5 的 Slides Show,方便在讲工具时直接调试当前页面。

主要实现思路是利用transform: translate() ; 进行横向移位,有点类似absolute之后的left 值与top值,但这里的left值与top值已经用来居中了,所以这里用translate是最佳选择,然后配合css3的transition进行属性改变时动画,在翻页时根据页值,改变所有article的class值,来进行切换,每一页用hash标示,使用了hashchange为主要驱动事件,翻页按钮只改变hash,然后由hashchange事件来驱动翻页。

demo演示点这里

完整源代码点这里 (github上面的)

以下是完整的js代码:

/**
 * Author : Der (http://www.ueder.net)
 * Date : 2012/04/02
 */

//window 以参数方式传进来,沙箱模式,
//undefined定为局部变量,提高性能, 以及防止被恶意修改
;(function(window, undefined) { 

    //使document指向参数window里的document
    var document = window.document,
        location = document.location;

    /**
     * //扩展对象(默认值替换)
     * @param  {object} target 默认值对象
     * @param  {object} obj    待扩展的对象
     * @return {object}        返回扩展后的对象
     */
    var extend = function (target, obj) {
        if (obj) {
            for (var i in target) {
                if ((typeof obj[i]) === "undefined") {
                    obj[i] = target[i];
                }
            }
            return obj;
        } else {
            return target;
        }
    }

    /**
     * Slides 构造函数
     */
    var Slides = function(config) {

        //支持 Slides()直接调用
        if (!(this instanceof Slides)) {
            return new Slides(config);
        }

        //默认配置
        config = extend({
            container: '#slides', //slides的容器选择器
            pages: '.page', //所有slide页选择器
            hashPrefix: 'slide-', //hash里的前缀,后面为页值
            prev: '#prev', //前一页按钮
            next: '#next', //后一页按钮
            changeBtn: '#changeType', //切换风格的按钮
            changeTypes: ['slides', 'slides2'], //切换风格的class
            typeArr: ['p-current', 'p-past', 'p-past-far', 'p-next', 'p-next-far'],
            typeCount: 0 //默认的切换风格,对应changeTypes里的数组
        }, config);

        //挂载内部参数
        this.container = document.querySelector(config.container); //slides的容器
        this.pages = this.container.querySelectorAll(config.pages); //所有slide页
        this.prevBtn = document.querySelector(config.prev); //上一页按钮
        this.nextBtn = document.querySelector(config.next); //下一页按钮
        this.hashPrefix = config.hashPrefix; //hash前缀
        this.currentPage = null; // 当前页
        this.totalPages = this.pages.length; //ppt总页数
        this.changeBtn = document.querySelector(config.changeBtn); //
        this.changeTypes = config.changeTypes; //切换type数组
        this.typeCount = config.typeCount; //
        this.curType = this.changeTypes[this.typeCount]; //默认切换type为第一个
        this.typeArr = config.typeArr;

        this.init();

    };

    /**
     * 扩展构造函数
     * @type {Object}
     */
    Slides.prototype = {

        /**
         * 还原contructor
         * @type {Function}
         */
        constructor: Slides, 

        /**
         * 初始化
         * @return {undefined}
         */
        init: function() {
            var self = this;

            self.bindUI(); //用户事件绑定
            self.container.className = self.curType; //
            self.currentPage = self._getPageFromHash(); //从hash获取在第几页
            self._emptyClass();//先清空设置过的class
            self.gotoPage(self.currentPage); //跳转到第几页
            self._setPageToHash(self.currentPage); //设置hash状态

        },

        /**
         * 事件绑定
         * @return {undefined}
         */
        bindUI: function() {
            var self = this;

            //前一页
            this.prevBtn.addEventListener('click', function(e) {
                e.preventDefault();
                self.prev();
            }, false);

            //后一页
            this.nextBtn.addEventListener('click', function(e) {
                e.preventDefault();
                self.next();
            }, false);

            // onhashchange handle 哈希驱动事件
            // 所有的上一页下一页跳转到几页都只改变hash值,然后由hashchange事件驱动页面跳转
            window.addEventListener('hashchange', function(e) {
                var cp = self._getPageFromHash();
                self.currentPage = cp;
                self._emptyClass(); //先清空设置过的class
                self.gotoPage(cp);
            }, false);

            //切换风格
            this.changeBtn.addEventListener('click', function(e) {
                e.preventDefault();

                self._changeType();
                self.container.className = self.curType;
            }, false);

            //添加键盘事件
            window.addEventListener('keydown', function(e) {

                switch (e.keyCode) {
                    case 39: // right arrow
                    case 40: // down arrow
                    case 13: // Enter
                    case 32: // space
                    case 34: // PgDn
                        self.next();
                        break;

                    case 37: // left arrow
                    case 38: // top arrow
                    // case 8: // Backspace
                    case 33: // PgUp
                    case 27: //Esc
                        self.prev();
                        break;
                }

            }, false)

        },

        /**
         * 转换切换风格
         * @return {undefined}
         */
        _changeType: function() {
            var self = this;

            self.typeCount = (self.typeCount === self.changeTypes.length - 1)
                ? 0 : self.typeCount + 1;

            self.curType = self.changeTypes[self.typeCount];
        },

        /**
         * 从hash获取当前到第几页
         * @return {number} 返回第几页的数字
         */
        _getPageFromHash: function() {
            var self = this,
                hashPrefix = self.hashPrefix,
                tp = self.totalPages, //总slides数
                hash = location.hash.slice(1), //获取hash去掉#之后的字符串
                page = hashPrefix === '' ? hash : hash.split(hashPrefix)[1], //前缀为空直接取hash,否则取前缀之后的值
                pageN = parseInt(page, 10); //转为number

            //page为不合法或为0时,统一返回1
            if (isNaN(pageN) || pageN < 1) {
                pageN = 1;
            }
            //page大于总slides数,统一返回最大slides数
            else if (pageN > tp) {
                pageN = tp;
            }

            return pageN;
        },

        /**
         * 设置hash
         * @param {number} n 设置hash到第n页
         */
        _setPageToHash: function(n) {
            var self = this,
                hashPrefix = self.hashPrefix;

            location.hash = '#' + hashPrefix + n;
        },

        /**
         * 清空class
         * @return {undefined}
         */
        _emptyClass: function() {
            var classNameList = this.typeArr,
                i = 0,
                len = this.totalPages,
                l = classNameList.length,
                pages = this.pages;

            for (; i < len; i++){
                var el = pages[i];

                for (var j = 0; j < l; j++) {
                    el.classList.remove(classNameList[j]);
                }
            }
        },

        /**
         * 跳转到第n页
         * @param  {number} n 跳转到的页数
         * @return {undefined}
         */
        gotoPage: function(n) {
            var self = this,
                pages = self.pages,
                cur = n - 1, //当前页, 转为0起始
                past = n - 2, //上一页
                pastFar = n - 3, //上上一页
                next = n, //下一页
                nextFar = n + 1, //下下一页
                i = 0, len = self.totalPages,
                classNameList = this.typeArr;

            //改变当前slide以及前后各两个slide的className,
            //再利用css3 的translate偏离位置 + transition动画
            for (; i < len; i++) {
                var page = pages[i];

                switch (i) {
                    case cur:
                        page.classList.add(classNameList[0]);
                        break;

                    case past:
                        page.classList.add(classNameList[1]);
                        break;

                    case pastFar:
                        page.classList.add(classNameList[2]);
                        break;

                    case next:
                        page.classList.add(classNameList[3]);
                        break;

                    case nextFar:
                        page.classList.add(classNameList[4]);
                        break;
                }
            }
        },

        /**
         * 前一页
         * @return {undefined}
         */
        prev: function() {
            var cp = this.currentPage;

            if (cp === 1) return; //边界

            this.currentPage--;
            this._setPageToHash(this.currentPage);
        },

        /**
         * 后一页
         * @return {undefined}
         */
        next: function() {
            var tp = this.totalPages,
                cp = this.currentPage;

            if (cp === tp) return; //边界

            this.currentPage++;
            this._setPageToHash(this.currentPage);
        }
    };

    //将Slides暴露到全局
    window.Slides = Slides;

})(window);

从notepad++ 到 sublime text2

展开/收缩

之前一直在用notepad++ coding,最近接触了sublime text2 ,感受匪浅,这里暂且做下记录,记录下我所深度试用过的两款编辑器的优劣,有一款得心应手的编辑器,coding起来真是享受。先说np++,这货是一个台湾人做的开源的编辑器,已经许久不更新,界面也像win98时期的软件,不过软件本身够小,打开够快,这也是它的优点,列一下我常用的它的功能点吧(普通编辑器都具备的功能就不列举了):

1. 括号或标签高亮匹配 (sublime也实现了,不过高亮得太不明显了,不过可以有插件辅助)

2. 代码折叠(效果有点坑爹,折叠后没有结束,无法整块删除,折叠在文件关闭再打开后也不能保存)

3. 上下文中与选择内容一致的高亮显示 (这特性极有用,在看上下文时)

4. 在任意行打标记,F2切换标记点(标记在关闭后再打开也不能保存)

5. 自动完成(NP++的自动完成算是比较坑爹的,系统自带两种方式,一种函数自动完成,用于一些js关键字等,另一个是词法自动完成,就是你上文输过的文字自动完成,这两种还不能共存!)

6. np++提供块级或单行注释的快捷键,不过如果在HTML文件里有JS代码,那么注释就不会智能转换了。

7. NP++对GBK的支持还是很好的,自带编码转换功能

8. zencoding,这是一个插件,在很多编辑器里都有,方便输入html css等

9. NP++本身不带explore,装了插件后可以实现

10. NP++有FTP插件,这工具对于有自己空间需要管理的人来说,很是方便

11. 还有JSHINT,Compare等插件,但插件质量总不是太完美

以上大概就是我常用到的NP++功能,功能不多,算是比较纯粹的编辑器。

- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – -

下面介绍下sublime text2(点这官网下载) ,这几天深度试用中,对各种编辑辅助功能,语法高亮,快捷键,snippet,插件都有大致的了解,列下各个细节功能点吧:

1. 项目文件夹浏览: sublime不同于np++,它是基于项目管理,侧边栏可以导入正在开发的项目文件夹,(ctrl+k,ctrl+b)快捷键可以开关侧栏(ps: 这里逗号分隔的两个快捷键代表按下ctrl的同时先按K再按B,这种方式大大增加了快捷键的使用有效率),同时右键菜单里可以remove folder移除文件夹

2. 文件快速导航: 这是sublime上面很好用的功能之一,ctrl+p可以调出窗口,菜单上的解释是goto anythings ,确实如其所言,调出窗口后,直接输入关键字,可以在已打开的项目文件夹中进行快速文件名导航,而且支持模糊搜索 ,对于不想一直鼠标点开文件夹的同学来说极为方便,并且在该窗口里加上:前缀即为行跳转(ctrl+G),加上@(ctrl+R)前缀在html里是id关键字导航,css里是每条规则导航,js里则是每个function导航。

3. 命令行模式 ctrl+` 可以调出命令行模式,主要支持python语法等,没试用过只知 quit()可以退出 。。不过sublime的插件平台package controller可以用命令行安装,详见这里

4. ctrl+up, ctrl+down可以一行一行的滚动屏幕,pageUp pageDown一页一页翻动

5. ctrl+j是拼合两行,ctrl+shift+d是直接复制当前行,

6. ctrl+/ 单行注释, ctrl+shift+/块注释,sublime会自动根据语言选择注释方式

7. ctrl+L 选择当前行,ctrl+d 选择当前文字块,ctrl+shift+a 可以HTML标签内容,每按一次逐级往上, ctrl+shift+space可以选择js等语言里的块{内容}, ctrl+shift+F 是文件夹里查找,与普通编辑不同的地方是sublime允许添加多个文件夹进行查找(add directory)

8. 在 菜单View-syntax下可以将当前面面以指定的语言进行语法高亮,通常情况下sublime会自动进行判断选择

9. ctrl+F2可以进行标记,然后F2在标记之间切换,这里不爽的是无法进行鼠标添加标记

10. snippets 代码片段插件 ,在tools-snippets菜单下可以查看当前页面支持的snippets,可以在缩略词后加tab自动补全snippets, snippets也可以从安装插件进行扩展

11. Build编译,可以进行ruby等代码的编译,我安装了一个yui compressor后,就可以在css js页面里进行压缩,快捷键是ctrl+B, 会自动在当前目录下生成xx.min.js, xx.min.css等压缩文件

12. 在菜单Preferences 下面是各种配置文件,sublime与其他编辑器不同的是,他不提供可视化配置,软件的配置及快捷键配置全都是存在.xml文件里手动配置,Settings-default 是系统默认配置,最好不要改,要改动的东西存放 在Settings-User里,比如font-size等, Key-bindings是快捷键配置, color scheme是代码配色方案选择,sublime本身提供了很多很不错的配色方案

13. 在页面右下角,有快速设置tab转为spaces的菜单,可以指定页面的tab宽度,也可以将页面所有tab转为指定的spaces格数

接下来介绍一下sublime的亮点,插件机制:
sublime插件可以通过两种方式进行插件安装,一种直接下载所有源码放置到C:\Users\yourName\AppData\Roaming\Sublime Text 2\Packages下面,另一种则可以通过在线安装 package control的方式进行在线安装,
package control安装见其官网,就是在控制台里运行如下一段代码,再重启即可:

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'

安装完即可在菜单preferences-package control下打开(这里有个快捷键ctrl+shift+p是编辑器操作的命令集合,可以直接根据关键字索引,省却菜单栏寻找的过程),在package control下 Install Package是安装插件,选择后会连网获取插件列表,disabled package 是禁用某插件,enabled package 启用插件,remove package 移除插件,list package列出插件列表。

下面介绍几个我觉得比较有用的插件,及它的功用吧(安装方法直接package control install 在线搜索安装):
1. BracketHighlighter :该插件提供配对标签,或大括号或字符引号的配对高亮显示,算是对系统高亮的加强吧。

2. ClipboardHistory: 该插件提供多剪贴板支持,你就可以同时保存多个剪贴板里的内容了,ctrl+alt+v快捷键调出

3. DocBlockr :该插件提供文件注释,方便后期根据注释生成API文档,输入 “/**” + enter调出 (在function的上面一行才有效果)

4. GBK Encoding Support: sublime本身不支持GBK,根据国情,装下这个插件就可以支持GBK了,同时也提供GBK与UTF之间转换

5. jquery 提供jquery的一些snippets片段 ,方便直接调用

6. JS Minifer 提供js压缩功能,基于GG的closure complier,快捷键:ctrl+alt+M

7. js Format 提供JS格式化功能,快捷键 ctrl+alt+F,会根据

8. prefixr 提供CSS3属性的浏览器前缀自动填充像-webkit- -moz- -o- -m-, 快捷键:ctrl+alt+x

9. yui compressor 这个大家都知道yui的压缩工具,可以压缩CSS JS,直接CTRL+B,即可(需要安装配置了jdk之后才可用)

10. sublime v8 该插件提供jshint 及 v8引擎的js解析器console,jshint是JS语法校验器,较严格, v8则跟chrome里控制台一样。

11. zenCoding 大名鼎鼎的zencoding就不用多解释, 调用方式两种,一种是ctrl+alt+enter, 一种是输入完标签直接tab。

12. html5 该插件提供许多 html5相关的标签等snippets,也非常实用。

13. SFTP 该插件提供ftp服务器管理,用来管理自己的空间很不错,通过配置来操作

暂时就以上这些体验,日后再有新的东西再更新。。

javascript模版引擎-tmpl 的精简及bug修正

展开/收缩

在基于MVC框架开发的web app中,js模板引擎显得特别重要,只需一个模板文本加一段json数据,mix一下,内容就出来了,以往都是用mustache.js, 这里记录一下项目同事介绍一个超精简的模板引擎-tmpl ,对对于mustache.js的单独的模板语法,这个引擎亲切许多,因为可以直接使用js原生的语法,像for switch if,之类。原作为jquery的作者John Resig 开发,详细博客地址, 另有国内某牛人性能改进版,详细见 博文 ,但使用之后,发现还是有点问题,先贴下完整代码:

/**
 * 微型模板引擎 tmpl 0.2
 * 0.2 更新:
 * 1. 修复转义字符与id判断的BUG
 * 2. 放弃低效的 with 语句从而最高提升3.5倍的执行效率
 * 3. 使用随机内部变量防止与模板变量产生冲突
 * @example
 * 方式一:在页面嵌入模板
 * <scriptt type="text/tmpl" id="tmpl-demo">
 * <ol title="<%=name%>">
 *  < % for (var i = 0, l = list.length; i < l; i ++) { %>
 *      <li>< %=list[i]%></li>
 *  < % } %>
 * </ol>
 * </scriptt>
 * tmpl('tmpl-demo', {name: 'demo data', list: [202, 96, 133, 134]})
 *
 * 方式二:直接传入模板:
 * var demoTmpl =
 * '<ol title="<%=name%>">'
 * + '< % for (var i = 0, l = list.length; i < l; i ++) { %>'
 * +    '<li>< %=list[i]%></li>'
 * + '< % } %>'
 * +'</ol>';
 * var render = tmpl(demoTmpl);
 * render({name: 'demo data', list: [202, 96, 133, 134]});
 *
 * 这两种方式区别在于第一个会自动缓存编译好的模板,
 * 而第二种缓存交给外部对象控制,如例二中的 render 变量。
 * @blog http://www.planeart.cn/?p=1594
 * @see		http://ejohn.org/blog/javascript-micro-templating/
 * @param	{String}	模板内容或者装有模板内容的元素ID
 * @param	{Object}	附加的数据
 * @return	{String}	解析好的模板
 */
var tmpl = (function (cache, $) {
return function (str, data) {
	var fn = !/\W/.test(str)
	? cache[str] = cache[str]
		|| tmpl(document.getElementById(str).innerHTML)

	: function (data) {
		var i, variable = [$], value = [[]];
		for (i in data) {
			variable.push(i);
			value.push(data[i]);
		};
		return (new Function(variable, fn.$))
		.apply(data, value).join("");
	};

	fn.$ = fn.$ || $ + ".push('"
	+ str.replace(/\\/g, "\\\\")
		 .replace(/[\r\t\n]/g, " ")
		 .split("< %").join("\t")
		 .replace(/((^|%>)[^\t]*)'/g, "$1\r")
		 .replace(/\t=(.*?)%>/g, "',$1,'")
		 .split("\t").join("');")
		 .split("%>").join($ + ".push('")
		 .split("\r").join("\\'")
	+ "');return " + $;

	return data ? fn(data) : fn;
}})({}, '$' + (+ new Date));

[继续阅读全文...]

一个简单的中文字符转unicode的chrome插件

展开/收缩

插件安装地址(请用chrome打开): charCodeTranslate.crx
ps: 新版chrome已经无法直接在任何界面安装非应用商店的插件,请下到本地,然后拖到chrome插件页面安装(地址:chrome://extensions)

12-7-2011 更新增加了从unicode转字符,以及encode,decode等方便的功能
3-5-2012 更新增加了转义成HTML实体字符,例如’< ' 转成'&#60' 方便页面使用

界面截图:
unicode字符转换插件

在通常的JS或CSS文件里,汉字等字符是以unicode的16进制形式存在的, 如果直接输入汉字,在英文或其他语种的系统上,容易造成乱码无法识别的状况,如果把所有汉字转成unicode形式就没有问题了,所以就想到做一个chrome小插件,随时查看汉字的unicode编码,
直接看下主转换代码:

/**
 * 中文转unicode字符工具
 */
function toUnicode(str, cssType) {
    var i = 0,
        l = str.length,
        result = [], //转换后的结果数组
        unicodePrefix, //unicode前缀 (example:\1234||\u1234)
        unicode16; //转换成16进制后的unicode

    //如果是css中使用格式为\1234之类
    unicodePrefix = (cssType && cssType.toLowerCase() === 'css') ? '\\' : '\\u';

    for (; i < l; i++) {
        //转为16进制的unicode, js及css里须转成16进制
        unicode16 = str.charCodeAt(i).toString(16);
        result.push( unicodePrefix + unicode16 );
    }

    return result.join(' ');
}

[继续阅读全文...]

关于递归在项目中的几种常用应用

展开/收缩

项目中常常会对开发返回的json数据进行遍历,然后更新页面,如果数据只是简单的一层结构,只需一个for循环即可搞定,但如果数据存在较深且不确定的层次,此时就需要使用递归配合循环来搞定,先看下模拟的数据格式:

//json数据
var json = {
    status: 'success',
    data: [
        {
            status: 0,
            title: '文件夹1',
            data: [
                {
                    status: 0,
                    title: '文件夹2',
                    data: [
                        {
                            status: 0,
                            title: '文件夹3',
                            data: [
                                {
                                    status: 0,
                                    title: '文件夹4',
                                    data: []
                                },
                                {
                                    status: 0,
                                    title: '文件夹4',
                                    data: []
                                }
                            ]
                        },
                        {
                            status: 0,
                            title: '文件夹3',
                            data: []
                        }
                    ]
                },
                {
                    status: 0,
                    title: '文件夹2',
                    data: []
                }
            ]
        },
        {
            status: 1,
            title: '文件1',
        }
    ]
};

对于上面这种深层次的数据结构,普通的循环是无法搞定的,此时可以提取重复处理的代码片段,然后使用递归 即可搞定,直接看代码:

/**
 * 递归遍历数据
 */
function recursion(data) {
    var i = 0,
        len = data.length,
        j, item, current, flag;

    for (; i < len; i++) {
        item = data[i];

        for (j in item) {
            current = item[j];
            //是否数组判断
            flag = (Object.prototype.toString.call(current) === '[object Array]') ? true : false;

            if (flag) {
                recursion(current);
            } else {
                //这里执行对数据的相应操作
                console.log(current);
            }
        }
    }
}

//调用
recursion(json.data);

[继续阅读全文...]

模拟AJAX无刷新的文件上传功能

展开/收缩

传统的文件上传功能一般是用form包一个input:file直接提交到后端进行处理,form须指定enctype=”multipart/form-data”,代码如下:

<form action="test.php" target="" method="post" enctype="multipart/form-data">
    <input type="file" name="file" id="file" />
    <input type="submit" id="J_submit"  value="submit" />
</form>

在ajax盛行的现时,提交form再刷新整个页面,显得用户体验不佳,然而ajax与后端通信 只能传送字符串,是无法传递实体文件的,所以用ajax是无法实现直接文件上传的,这里提供一个解决方案就是用一个实时创建的隐藏iframe来完成上传功能, 具体的原理是,在点击提交按钮时,动态的生成一个隐藏iframe加入到页面上,并且 将form 的 target指向该隐藏iframe,服务端就接收到上传的file文件,并进行相应的操作,然后将返回结果返回到隐藏的iframe里面,这时我们可以与后端开发约定返回结果的格式,可以是json格式,便于我们前端操作,然后前端部分就可以用iframe.contentWindow.document.body.innerHTML来获取后端返回的结果,进行相应的parseJSON处理,即可像处理ajax返回的json一样,处理数据。。。直接贴源代码了(ps:代码是基于jQuery库的):

/**
 * 模拟ajax无刷新文件上传
 */
var fileUpLoad = function(config) {

    var ifr = null,
        fm = null,
        defConfig = {
            submitBtn: $('#J_submit'), //提交按钮
            complete: function(response) {}, //上传成功后回调
            beforeUpLoad: function() {}, //点击提交未上传时回调
            afterUpLoad: function() {} //点击提交上传后回调
        };

    //静态变量
    var IFRAME_NAME = 'fileUpLoadIframe';

    //配置
    config = $.extend(defConfig, config);

    //绑定submit事件
    config.submitBtn.bind('click', function(e){
        e.preventDefault();

        //点击提交前触发事件, 函数返回false可阻止提交表单,用于file为空判断
        if (config.beforeUpLoad.call(this) === false) {
            return;
        }

        //生成一个隐藏iframe,并设置form的target为该iframe,模拟ajax效果
        ifr = $('<iframe name="'+ IFRAME_NAME +'" id="'+ IFRAME_NAME +'" style="display:none;"></iframe>');
        fm = this.form;

        ifr.appendTo($('body'));
        fm.target = IFRAME_NAME; //target目标设为ifr

        //上传完毕iframe onload事件
        ifr.load(function(){
            var response = this.contentWindow.document.body.innerHTML;

            config.complete.call(this, response);
            ifr.remove();
            ifr = null; //清除引用
        });

        fm.submit(); //提交表单

        //点击提交后触发事件
        config.afterUpLoad.call(this);

    });

};

[继续阅读全文...]

正则表达式的技巧总结

展开/收缩

正则表达式在现在web的应用当中,如表单验证,url解析等,应用非常方便,比起普通的字符串解析性能上也高出不少。
这里就做一些关于正则表达式通用技巧的个人小总结,正则的入门可以参考以下网址内容
http://www.regexlab.com/zh/regref.htm
http://w3school.com.cn/js/jsref_obj_regexp.asp

1. 一些常用的元字符.
\w : 查找单词字符,包含字母数字及下划线,相当于[A-Za-z0-9_];
\d : 查找数字,相当于[0-9]
\s : 查找空白字符
\n : 查找换行符
. : 点号代表除换行符及行结束符外所有字符

2. 验证完整字符串,这在表单验证中常用到,例子如下:

var str = '18636200607';
var str2 = '10010';
var reg = /^\d{11}$/;
console.log(reg.test(str)); // return true;
console.log(reg.test(str2)); // return false;

这里的头尾的^$即是限定匹配的必须是整个字符串,而不是其中一部分,这对于表单验证里验证完整的合法输入很有用。
[继续阅读全文...]

>>
后台管理 github RSS 微博 简历
RSS订阅