使用Simple Inheritance来创建自己的类

最近一直再研究类的写法。因为经常做一些可复用,可扩展的方法。之前一直使用别人包装好的组件,比如玉伯开发的Alare组件,用的很舒服啊~~
但是不是什么项目都要使用那么复杂的组件吧,如果用JQ自己写一个呢,JQ好像还没有类的包装,可能以后会有吧。研究了半天发现了一个好东西,就是John Resig写的 Simple JavaScript Inheritance。
真是完美的解决了我的需求,而且代码也很少,下面就放上我使用的代码示例

(function() {
	/*
	 * Simple Inheritance
	 */
	var initializing = false;
	var fnTest = /xyz/.test(function() {
		xyz;
	}) ? /\b_super\b/ : /.*/;
	this.Class = function() {};
	Class.extend = function(prop) {
		var _super = this.prototype;
		initializing = true;
		var prototype = new this();
		initializing = false;
		for (var name in prop) {
			prototype[name] = typeof prop[name] == "function" &&
				typeof _super[name] == "function" && fnTest.test(prop[name]) ?
				(function(name, fn) {
				return function() {
					var tmp = this._super;
					this._super = _super[name];
					var ret = fn.apply(this, arguments);
					this._super = tmp;
					return ret;
				};
			})(name, prop[name]) :
				prop[name];
		}

		function Class() {
			if (!initializing && this.init)
				this.init.apply(this, arguments);
		}
		Class.prototype = prototype;
		Class.constructor = Class;
		Class.extend = arguments.callee;
		return Class;
	};
})();

$(function() { 
	
	//定义一个Box的类
	var Box = Class.extend({
		init: function(opts) {
			opts = $.extend({
				"element": 'box'
			}, opts || {});
			this.opts = opts;
			this.element = $(opts.element);
			this.render();
		},
		render: function() {
			var elEl = this.element;
			elEl.html(this.opts.name + ',' + this.opts.age);
			this.show();
		},
		show: function() {
			var elEl = this.element;
			elEl.show();
		}
	});

	//实例1 - 直接用new来实例化Box
	var mybox = new Box({
		element: '.mybox',
		name: '张三',
		age: 15
	});

	//实例2 - 先扩展,再用new来实例化Box
	var mybox2 = Box.extend({
		init: function(opts) {
			this.opts = opts;
			this.element = $(opts.element);
			this.render();
			this.event();
		},
		hide: function() {
			var elEl = this.element;
			elEl.hide();
		},
		event: function() {
			var elEl = this.element;
			var that = this;
			elEl.on('click', function() {
				that.hide();
			})
		}
	});
	new mybox2({
		element: '.mybox2',
		name: '李四',
		age: 55
	});

})

判断文本是否含有超链接的正则

提示:你可以先修改部分代码再运行。

JS判断表单里输入的全是空格和删除连续的空格

今天做回复框输入限制时的2个需求:
1、文字内容不能全都是空格,用这个正则 /^\s*$/
2、删除连续的空格,是这个正则 /\s+/g
下面是常见的需求代码

提示:你可以先修改部分代码再运行。

jQuery获取页面宽度,滚动条高度,元素高度等等。。。

jquery 获取滚动条高度
获取浏览器显示区域的高度 :
$(window).height();
获取浏览器显示区域的宽度 :

$(window).width();
获取页面的文档高度 :
$(document).height();
获取页面的文档宽度 :$(document).width();

获取滚动条到顶部的垂直高度 :

$(document).scrollTop();
获取滚动条到左边的垂直宽度 :

$(document).scrollLeft();

计算元素位置和偏移量:

$(id).offset();

offset方法是一个很有用的方法,它返回包装集中第一个元素的偏移信息。默认情况下是相对body的偏移信息。结果包含 top和left两个属性。

offset(options, results)
options.relativeTo  指定相对计
算偏移位置的祖先元素。这个元素应该是relative或absolute定位。省略则相对body。
options.scroll  是否把
滚动条计算在内,默认TRUE
options.padding  是否把padding计算在内,默认false
options.margin
  是否把margin计算在内,默认true
options.border  是否把边框计算在内,默认true

小技巧—判断图片是否加载失败,URL是否有效等等的方法。

为了良好的用户体验,一般情况如果网页上面某个图片的地址失效了,会使用一个图片失效的默认图片取代,或者链接地址失效的时候加一个删除线等等……

实现的方法是使用jQuery的ajax方法

$(function() {
	$.ajax({
		url: './images/img2.jpg',
		type: 'get',
		complete: function(response) {
			console.info(response)
			if (response.status == 200) {//地址加载成功
				alert('有效');
			} else {
				alert('无效');
			}
		}
	});
})

JS判断字符串字节长度(数字英文长度记为1,中文记为2)

你早晚会用到的,用CSS来控制文字长度毕竟不是什么需求都能满足,现在后台也不管字符长度截取了,只能用JS来截取字符串了。

[js]/**
* 返回字符的字节长度(汉字算2个字节)
* @param {string}
* @returns {number}
*/

var getByteLen = function (val) {
var len = 0;
for (var i = 0; i < val.length; i++) {
if (val[i].match(/[^\x00-\xff]/ig) != null) //全角
len += 2;
else
len += 1;
};
return len;
}
var sAbc = ‘1a啊啊22飞3地方a’;
var ol = getByteLen(sAbc);
alert(‘直接用length取得的字节长度:’ + sAbc.length);
alert(‘通过getByteLen()方法取得的字节长度:’ + ol);
[/js]

通过上面的方法就可以继续写一个截取指定长度的新字符串了,截取掉的部分用…补全:

[js]/**
* 返回字符的字节长度(汉字算2个字节)
* @param {string}{number}
* @returns {string} +’…’
*/

var cutStrForNum = function (str, num) {
var len = 0;
for (var i = 0; i < str.length; i++) {
if (str[i].match(/[^\x00-\xff]/ig) != null) //全角
len += 2;
else
len += 1;
}
if (len >= num) {
newStr = str.substring(0, num) + "…";
}
return newStr;
}
var sAbc = ‘1a啊啊22飞3地方a’;
alert(cutStrForNum(sAbc, 3));[/js]

jQuery对象和DOM对象的相互转换

在讨论jQuery对象和DOM对象的相互交换之前,先约定好定义变量的风格。如果获取的对象是jQuery对象,那么在变量前加上$,例如:

var $variable = jQuery对象;

如果获取的是DOM对象,则定义如下:

var variable = DOM对象;

1.jQuery对象转成DOM对象

jQuery对象不能使用DOM中的方法,但是如果对jQuery对象所提供的方法不熟悉,或者jQuery没有封装想要的方法,不得不实用DOM对象的时候,有以下两种处理方法。jQuery提供了两种方法将一个jQuery对象转换成DOm对象,即[index]和get(index).

(1)jQuery对象是一个数组对象,可以通过[index]的方法得到相应的DOM对象。

jQuery代码如下:

[js]var $cr = $("#cr"); //jQuery对象
var cr = $cr[0] //DOM对象
alert(cr.checked) //检测这个checkbox是否选中了[/js]

(2)另一种方法是jQuery本身提供的,通过get(index)方法得到相应的DOM对象。

jQuery代码如下:

[js]var $cr = $("#cr");
var cr = $cr.get(0);
alert(cr.checked)[/js]

2.DOM对象转换成jQuery对象

对于一个DOM对象,只需要用$()把DOM对象包装起来,就可以获得一个jQuery对象了,方式为$(DOM对象)。

jQuery代码如下:

[js]var cr = document.getElementByID("cr"); //DOM对象
var $cr = $(cr);[/js]

转换后,可以任意使用jQuery中的方法。

通过以上方法,可以任意地相互转换jQuery对象和DOM对象。

最后强调,DOM对象才能使用DOM中的方法,jQuery对象不可以使用DOM中的方法,但jQuery对象提供了一套更加完善的工具用于操作DOM

jQuery的on()方法支持的所有事件

自从jQuery添加了on()和off()方法之后,基本跟事件有关的操作我不会再使用其他诸如$(‘xxx’).click(function(){});之类的了。
不过jQuery的api里面没有说on里面到底可以绑定多少个事件,今天看jQuery1.8.3的源码无意间发现了这些,很开心~
下面就把on里面支持的事件列出来,共享给大家:

blur
focus
focusin
focusout
load
resize
scroll
unload
click
dblclick
mousedown
mouseup
mousemove
mouseover
mouseout
mouseenter
mouseleave
change
select
submit
keydown
keypress
keyup
error
contextmenu

JS主流的“类”的写法

js其实没有类的概念,不过业界人士一般都使用构造函数来写JS的“类”(潜规则)。
[js]/**
* 定义一个MyClass的类(首字母大写)
* @param opts
* @constructor
**/
var MyClass = function(opts) {
opts = $.extend({
"element": null, //容器
"listPath": "/attach_html/getAttachImgFilesOfIReceive" //路径地址
}, opts);

this.opts = opts; //定义属性
this.init(); //执行初始化方法
};
//方法放在原型下面,私有方法命名加下划线
$.extend(MyClass.prototype, {
//初始化
"init": function() {
var that = this;
var opts = this.opts;
var elEl = this.element;
console.info(opts);
},
// 私有方法
"_private": function() {
//do….
}
});

/********************/
var itemEl = $(‘.itme’);
// 实例化
var newClass = new Classes({
"element": itemEl, //容器
"name": ‘liuxiaofan’
});[/js]

JS中substr和substring的用法和区别

substr 和 substring都是JS 截取字符串函数,两者用法很相近,下面是两者的语法很示例:

substr 方法

返回一个从指定位置开始的指定长度的子字符串。

stringvar.substr(start [, length ])

参数
stringvar
必选项。要提取子字符串的字符串文字或 String 对象。
start
必选项。所需的子字符串的起始位置。字符串中的第一个字符的索引为 0。
length
可选项。在返回的子字符串中应包括的字符个数。

说明
如果 length 为 0 或负数,将返回一个空字符串。如果没有指定该参数,则子字符串将延续到 stringvar 的最后。

示例代码

[js]function SubstrDemo(){
var s, ss; // 声明变量。
var s = "The rain in Spain falls mainly in the plain.";
ss = s.substr(12, 5); // 获取子字符串。
return(ss); // 返回 "Spain"。
}[/js]

substring 方法

返回位于 String 对象中指定位置的子字符串。

strVariable.substring(start, end)

“String Literal”.substring(start, end)

参数
start
指明子字符串的起始位置,该索引从 0 开始起算。
end
指明子字符串的结束位置,该索引从 0 开始起算。

说明
substring 方法将返回一个包含从 start 到最后(不包含 end )的子字符串的字符串。
substring 方法使用 start 和 end 两者中的较小值作为子字符串的起始点。例如, strvar.substring(0, 3) 和 strvar.substring(3, 0) 将返回相同的子字符串。
如果 start 或 end 为 NaN 或者负数,那么将其替换为0。
子字符串的长度等于 start 和 end 之差的绝对值。例如,在 strvar.substring(0, 3) 和 strvar.substring(3, 0) 返回的子字符串的的长度是 3。

示例代码

[js]function SubstringDemo(){
var ss; // 声明变量。
var s = "The rain in Spain falls mainly in the plain..";
ss = s.substring(12, 17); // 取子字符串。
return(ss); // 返回子字符串。
}[/js]

截止字符串最后一位字符的方法

[js]var str="aaaaaaaaaaaaaaaaaa|";
var texts=str.substr(0, str.length-1);
alert(texts);[/js]

【注】:应用substr和substring两个函数截取带有空格的字符串后的长度是每个空格算一个字符长度。例如:

var a = “I am shi huan!”; a.substring(0, 5).length的值是5,而不是4,

但alert(a.substring(0, 5));的值却是I am ,这样在做alert(“I am” == a.substring(0, 5));的时

候就是false了,alert(“I am” == a.substring(0, 4));才是true。

如何让错误的js代码不打断后面的代码继续执行

一个js文件中如果有一行代码报错了,那么它后面的代码也就被打断了不会继续执行,所以我们经常看到网页显示一半就不显示了,因为代码被错误打断了。
如果想后面的代码不被错误打断怎么办?
使用Try…Catch 语句
try…catch 可以测试代码中的错误。try 部分包含需要运行的代码,而 catch 部分包含错误发生时运行的代码。
语法:

try
{
//在此运行代码
}
catch(err)
{
//在此处理错误
}

例子:

提示:你可以先修改部分代码再运行。

跳转到指定元素的位置组件(源生)

/**
 * 跳转到指定元素的位置
 * 使用方法
 * scroller(el, duration)
 * el : 目标锚点 ID
 * duration : 持续时间,以毫秒为单位,越小越快
 */
var flutil = {
    intval: function(v) {
        v = parseInt(v);
        return isNaN(v) ? 0 : v;
    },
    getPos: function(e) { // 获取元素信息 
        var l = 0;
        var t = 0;
        var w = this.intval(e.style.width);
        var h = this.intval(e.style.height);
        var wb = e.offsetWidth;
        var hb = e.offsetHeight;
        while (e.offsetParent) {
            l += e.offsetLeft + (e.currentStyle ? this.intval(e.currentStyle.borderLeftWidth) : 0);
            t += e.offsetTop + (e.currentStyle ? this.intval(e.currentStyle.borderTopWidth) : 0);
            e = e.offsetParent;
        }
        l += e.offsetLeft + (e.currentStyle ? this.intval(e.currentStyle.borderLeftWidth) : 0);
        t += e.offsetTop + (e.currentStyle ? this.intval(e.currentStyle.borderTopWidth) : 0);
        return {
            x: l,
            y: t,
            w: w,
            h: h,
            wb: wb,
            hb: hb
        };
    },
    getScroll: function() { // 获取滚动条信息 
        var t, l, w, h;
        if (document.documentElement &amp;&amp; document.documentElement.scrollTop) {
            t = document.documentElement.scrollTop;
            l = document.documentElement.scrollLeft;
            w = document.documentElement.scrollWidth;
            h = document.documentElement.scrollHeight;
        } else if (document.body) {
            t = document.body.scrollTop;
            l = document.body.scrollLeft;
            w = document.body.scrollWidth;
            h = document.body.scrollHeight;
        }
        return {
            t: t,
            l: l,
            w: w,
            h: h
        };
    },
    scroller: function(el, duration) { // 锚点(Anchor)间平滑跳转 
        if (typeof el != 'object') {
            el = document.getElementById(el);
        }
        if (!el) return;
        var z = this;
        z.el = el;
        z.p = this.getPos(el);
        z.s = this.getScroll();
        z.clear = function() {
            window.clearInterval(z.timer);
            z.timer = null
        };
        z.t = (new Date).getTime();
        z.step = function() {
            var t = (new Date).getTime();
            var p = (t - z.t) / duration;
            if (t &gt;= duration + z.t) {
                z.clear();
                window.setTimeout(function() {
                    z.scroll(z.p.y, z.p.x)
                }, 13);
            } else {
                st = ((-Math.cos(p * Math.PI) / 2) + 0.5) * (z.p.y - z.s.t) + z.s.t;
                sl = ((-Math.cos(p * Math.PI) / 2) + 0.5) * (z.p.x - z.s.l) + z.s.l;
                z.scroll(st, sl);
            }
        };
        z.scroll = function(t, l) {
            window.scrollTo(l, t)
        };
        z.timer = window.setInterval(function() {
            z.step();
        }, 13);
    }
}

复选框被选中的个数大于某值时Callback组件

/**
 * 判断多选框如果大于限制的选中数量的值则执行Callback函数
 * 使用方法如下
 * checkboxIsoverstep(defEl, voteCountNum, function() {
 *      alert('最多选' + voteCountNum + '项');
 *  });
 * checkboxsWarpEl : checkbox的父级元素
 * num : 限制的选中数量
 */
checkboxIsoverstep: function(checkboxsWarpEl, num, callBack) {
    var checkboxEl = $('input[type=checkbox]', checkboxsWarpEl);
    checkboxEl.on('click', function() {
        var checkedsLen = $(':checked', checkboxsWarpEl).length;
        if (checkedsLen &gt; num) {
            $(this).prop('checked', false);
            callBack()
        }
    });
}

JavaScript. The core.

原文地址:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
翻译备注:因为有些英文翻译成中文会更加难懂,所以一些术语或者必要的地方,都是中文在前,后面紧随中括号中的英文。希望能让大家更好的读懂。
全文分为10个主要部分

  1. An object
  2. A prototype chain
  3. Constructor
  4. Execution context stack
  5. Execution context
  6. Variable object
  7. Activation object
  8. Scope chain
  9. Closures
  10. This value
  11. Conclusion

本篇是ECMA-262-3 in detail系列的概述。每个章节都有一个更详细的内容链接,如果你觉得某个章节解释的不够过瘾,可以继续读一下每个章节对应的详细内容链接。
适合的读者:有经验的开发员,专业前端人员。

Read More

手机平板等移动端适配跳转URL的javascript

&lt;script type=&quot;text/javascript&quot;&gt;
if(/AppleWebKit.*mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|ZTE/.test(navigator.userAgent))){
    if(window.location.href.indexOf(&quot;?mobile&quot;)&lt;0){
        try{
            if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)){
                window.location.href=&quot;手机页面&quot;;
            }else if(/iPad/i.test(navigator.userAgent)){
                window.location.href=&quot;平板页面&quot;;
            }else{
                window.location.href=&quot;其他移动端页面&quot;
            }
        }catch(e){}
    }
}
&lt;/script&gt;

悟透 JavaScript

今天看到微博上面有人转发这本教程,大概看了一下作者写得真不错,因为内容并不是很多,所以我大概排版一下直接发到博客里面,用30-60分钟看完它估计你会有收获的。

原著:李战(leadzen)
http://www.cndev.org
http://www.cnblogs.com/leadzen

引子
编程世界里只存在两种基本元素,一个是数据,一个是代码。编程世界就是在数据和代码千丝万缕的纠缠中呈现出无限的生机和活力。数据天生就是文静的,总想保持自己固有的本色;而代码却天生活泼,总想改变这个世界。你看,数据代码间的关系与物质能量间的关系有着惊人的相似。数据也是有惯性的,如果没有代码来施加外力,她总保持自己原来的状态。而代码就象能量,他存在的唯一目的,就是要努力改变数据原来的状态。在代码改变数据的同时,也会因为数据的抗拒而反过来影响或改变代码原有的趋势。甚至在某些情况下,数据可以转变为代码,而代码却又有可能被转变为数据,或许还存在一个类似E=MC2形式的数码转换方程呢。然而,就是在数据和代码间这种即矛盾又统一的运转中,总能体现出计算机世界的规律,这些规律正是我们编写的程序逻辑。

不过,由于不同程序员有着不同的世界观,这些数据和代码看起来也就不尽相同。于是,不同世界观的程序员们运用各自的方法论,推动着编程世界的进化和发展。众所周知,当今最流行的编程思想莫过于面向对象编程的思想。为什么面向对象的思想能迅速风靡编程世界呢?因为面向对象的思想首次把数据和代码结合成统一体,并以一个简单的对象概念呈现给编程者。这一下子就将原来那些杂乱的算法与子程序,以及纠缠不清的复杂数据结构,划分成清晰而有序的对象结构,从而理清了数据与代码在我们心中那团乱麻般的结。我们又可以有一个更清晰的思维,在另一个思想高度上去探索更加浩瀚的编程世界了。

在五祖弘忍讲授完《对象真经》之后的一天,他对众弟子们说:“经已讲完,想必尔等应该有所感悟,请各自写个偈子来看”。大弟子神秀是被大家公认为悟性最高的师兄,他的偈子写道:“身是对象树,心如类般明。朝朝勤拂拭,莫让惹尘埃!”。此偈一出,立即引起师兄弟们的轰动,大家都说写得太好了。只有火头僧慧能看后,轻轻地叹了口气,又随手在墙上写道:“对象本无根,类型亦无形。本来无一物,何处惹尘埃?”。然后摇了摇头,扬长而去。大家看了慧能的偈子都说:“写的什么乱七八糟的啊,看不懂”。师父弘忍看了神秀的诗偈也点头称赞,再看慧能的诗偈之后默然摇头。就在当天夜里,弘忍却悄悄把慧能叫到自己的禅房,将珍藏多年的软件真经传授于他,然后让他趁着月色连夜逃走…

后来,慧能果然不负师父厚望,在南方开创了禅宗另一个广阔的天空。而慧能当年带走的软件真经中就有一本是《JavaScript 真经》!

Read More