您的位置:首页 > Web前端 > JavaScript

积累的一些常用javascript函数

2012-12-21 15:09 633 查看
1、检测浏览器中是否安装某插件

检测浏览器中是否安装了特定的插件是一种常见的检测,对于非ie浏览器,可以使用plugins数组来达到这个目的。该数组中每一项都包含以下属性:

name:插件的名称

description:插件的描述

filename:插件的文件名

length:插件所处理的MIME的类型数量。

一般来说,name属性会包含检测插件必须的所有信息,在检测ie下和非ie下检测的方式不同:

在非IE下:

function hasPlugin(name){
name=name.toLowerCase();
for(var i=0;i<navigator.plugins.length;i++){
if(navigator.plugins[i].name.toLowerCase().indexOf(name)>-1){
return true;
}
}
return false;
}
alert(hasPlugin("Flash"));
alert(hasPlugin("QuickTime"));


  

在IE下:

function hasIEPlugin(name){
try{
new ActiveXObject(name);
return true;
}
catch(ex){
return false;
}
}
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash"));
alert(hasPlugin("QuickTime.QuickTime"));


  

鉴于检测这个两种插件的方法差别太大,因此典型的做法是针对每个插件分别写检测函数,而不是使用前面介绍的通用检测方法。

function hasFlash(){
var result=hasPlugin("Flash");
if(!result){
result =hasIEPlugin("ShockwaveFlash.ShockwaveFlash");
}
return result;
}
//检测Flash
alert(hasFlash());


  

上面这个函数先尝试使用不针对ie的插件检测方法,如果返回了false,再针对ie进行插件检测,用过ie也返回false,则整个方法返回false。只要有一次检测返回true,整个方法都会返回true。

plugins集合一个名为refresh()的方法,用于刷新plugins以反映最新安装的插件。这个方法接收一个参数:true/false

true:则会重新加载包含插件的所有页面。

否则:只更新plugins集合,不重新加载页面。

navigator.plugins.refresh('true');
navigator.plugins.refresh();


2、 将毫秒值转换成几年几月几日几时的格式

function timeFmat(ms) {
var s = new Date();
s.setTime(ms);
return (s.getFullYear() + "-" + (s.getMonth() + 1) + "-" + s.getDate() + " "+s.getHours() + ":"+s.getMinutes());
}
alert(timeFmat(100000000000000000000));


3、new Image()打点

var img = new Image();
var rnd_id = "_img_" + Math.random();

window[rnd_id] = img; // 全局变量引用

img.onload = img.onerror = function () {
window[rnd_id] = null; // 删除全局变量引用
}
img.src = "http://log.mysite.com/1.gif?a=1&b=2&c=xxx";


4、兼容所有浏览器的js关闭当前网页代码

想做一个关闭当前网页的效果。没想到水还挺深的。还有各浏览器兼容问题。
于是记录在这里:

<script type="text/javascript">
function CloseWebPage() {
if (navigator.userAgent.indexOf("MSIE") > 0) {
if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
window.opener = null; window.close();
}
else {
window.open('', '_top'); window.top.close();
}
}
else if (navigator.userAgent.indexOf("Firefox") > 0) {
window.location.href = 'about:blank '; //火狐默认状态非window.open的页面window.close是无效的
//window.history.go(-2);
}
else {
window.opener = null;
window.open('', '_self', '');
window.close();
}
}
</script>


  

另:判断各浏览器js代码:

<script language="JavaScript">
<!--
function getOs()
{
var OsObject = "";
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE";
}
if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){
return "Firefox";
}
if(isSafari=navigator.userAgent.indexOf("Safari")>0) {
return "Safari";
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){
return "Camino";
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){
return "Gecko";
}

}
alert("您的浏览器类型为:"+getOs());
-->
</script>


5、js实现Trim()

W3C那帮人的脑袋被驴踢了,直到javascript1.8.1才支持trim函数(与trimLeft,trimRight),可惜现在只有firefox3.5支持。由于去除字符串两边的空白实在太常用,各大类库都有它的影子。加之,外国人都很有研究精神,搞鼓了相当多实现。

实现1
String.prototype.trim = function() {
return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
看起来不怎么样,动用了两次正则替换,实际速度非常惊人,主要得益于浏览器的内部优化。一个著名的例子字符串拼接,直接相加比用Array做成的StringBuffer还快。base2类库使用这种实现。

实现2
String.prototype.trim = function() {
return this.replace(/^\s+/, '').replace(/\s+$/, '');
}
和实现1很相似,但稍慢一点,主要原因是它最先是假设至少存在一个空白符。Prototype.js使用这种实现,不过其名字为strip,因为Prototype的方法都是力求与Ruby同名。

实现3
String.prototype.trim = function() {
return  this.substring(Math.max(this.search(/\S/), 0),this.search(/\S\s*$/) + 1);
}
以截取方式取得空白部分(当然允许中间存在空白符),总共调用了四个原生方法。设计得非常巧妙,substring以两个数字作为参数。Math.max以两个数字作参数,search则返回一个数字。速度比上面两个慢一点,但比下面大多数都快。

实现4
String.prototype.trim = function() {
return  this.replace(/^\s+|\s+$/g, '');
}
这个可以称得上实现2的简化版,就是利用候选操作符连接两个正则。但这样做就失去了浏览器优化的机会,比不上实现3。由于看来很优雅,许多类库都使用它,如JQuery与mootools

实现5
String.prototype.trim = function() {
var str = this;
str = str.match(/\S+(?:\s+\S+)*/);
return str ? str[0] : '';
}
match是返回一个数组,因此原字符串符合要求的部分就成为它的元素。为了防止字符串中间的空白符被排除,我们需要动用到非捕获性分组(?:exp)。由于数组可能为空,我们在后面还要做进一步的判定。好像浏览器在处理分组上比较无力,一个字慢。所以不要迷信正则,虽然它基本上是万能的。

实现6
String.prototype.trim = function() {
return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, '$1');
}
把符合要求的部分提供出来,放到一个空字符串中。不过效率很差,尤其是在IE6中。

实现7
String.prototype.trim = function() {
return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, '$1');
}
和实现6很相似,但用了非捕获分组进行了优点,性能效之有一点点提升。

实现8
String.prototype.trim = function() {
return this.replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1');
}
沿着上面两个的思路进行改进,动用了非捕获分组与字符集合,用?顶替了*,效果非常惊人。尤其在IE6中,可以用疯狂来形容这次性能的提升,直接秒杀火狐。

实现9
String.prototype.trim = function() {
return this.replace(/^\s*([\S\s]*?)\s*$/, '$1');
}
这次是用懒惰匹配顶替非捕获分组,在火狐中得到改善,IE没有上次那么疯狂。

实现10
String.prototype.trim = function() {
var str = this,
whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
for (var i = 0,len = str.length; i < len; i++) {
if (whitespace.indexOf(str.charAt(i)) === -1) {
str = str.substring(i);
break;
}
}
for (i = str.length - 1; i >= 0; i--) {
if (whitespace.indexOf(str.charAt(i)) === -1) {
str = str.substring(0, i + 1);
break;
}
}
return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}
我只想说,搞出这个的人已经不是用牛来形容,已是神一样的级别。它先是把可能的空白符全部列出来,在第一次遍历中砍掉前面的空白,第二次砍掉后面的空白。全过程只用了indexOf与substring这个专门为处理字符串而生的原生方法,没有使用到正则。速度快得惊人,估计直逼上内部的二进制实现,并且在IE与火狐(其他浏览器当然也毫无疑问)都有良好的表现。速度都是零毫秒级别的。

实现11
String.prototype.trim = function() {
var str = this,
str = str.replace(/^\s+/, '');
for (var i = str.length - 1; i >= 0; i--) {
if (/\S/.test(str.charAt(i))) {
str = str.substring(0, i + 1);
break;
}
}
return str;
}
实现10已经告诉我们普通的原生字符串截取方法是远胜于正则替换,虽然是复杂一点。但只要正则不过于复杂,我们就可以利用浏览器对正则的优化,改善程序执行效率,如实现8在IE的表现。我想通常不会有人在项目中应用实现10,因为那个whitespace 实现太长太难记了(当然如果你在打造一个类库,它绝对是首先)。实现11可谓其改进版,前面部分的空白由正则替换负责砍掉,后面用原生方法处理,效果不逊于原版,但速度都是非常逆天。

实现12
String.prototype.trim = function() {
var str = this,
str = str.replace(/^\s\s*/, ''),
ws = /\s/,
i = str.length;
while (ws.test(str.charAt(--i)));
return str.slice(0, i + 1);
}
实现10与实现11在写法上更好的改进版,注意说的不是性能速度,而是易记与使用上。和它的两个前辈都是零毫秒级别的,以后就用这个来工作与吓人。

下面是老外给出的比较结果,执行背景是对Magna Carta 这文章(超过27,600字符)进行trim操作。

实现	Firefox 2	IE 6
trim1	15ms	< 0.5ms
trim2	31ms	< 0.5ms
trim3	46ms	31ms
trim4	47ms	46ms
trim5	156ms	1656ms
trim6	172ms	2406ms
trim7	172ms	1640ms
trim8	281ms	< 0.5ms
trim9	125ms	78ms
trim10	< 0.5ms	< 0.5ms
trim11	< 0.5ms	< 0.5ms
trim12	< 0.5ms	< 0.5ms
原文链接:http://blog.stevenlevithan.com/archives/faster-trim-javascript


6、设为收藏,设为首页

//设为收藏
function AddFavorite(sTitle) {
sURL = location.href;

try {
window.external.addFavorite(sURL, sTitle);
} catch (e) {
try {
window.sidebar.addPanel(sTitle, sURL, "");
} catch (e) {
alert("加入收藏失败,请使用Ctrl+D进行添加");
}
}
}

//设为首页
function SetHome(obj, vrl) {
try {
obj.style.behavior = 'url(#default#homepage)';
obj.setHomePage(vrl);
} catch (e) {
if (window.netscape) {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
} catch (e) {
alert("此操作被浏览器拒绝!\n请在浏览器地址栏输入\"about:config\"并回车\n然后将 [signed.applets.codebase_principal_support]的值设置为'true',双击即可。");
}
var prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref('browser.startup.homepage', vrl);
}
}
} 


7、javascript删除数组元素并且数组长度减小

/**
* 通过值删除数组元素
*
* @param mixed value 元素值
* @returns array
*/
Array.prototype.deleteValue = function(value){
var i = 0;
for(i in this){
if(this[i] == value) break;
}
return this.slice(0, i).concat(this.slice(parseInt(i, 10) + 1));
}
//示例
var test = new Array(1,5,3,4,2);
//输出5
console.log(test.length);
//删除值为4的元素
test = test.deleteValue(4);
//输出[1, 5, 3, 2]
console.log(test);
//输出4
console.log(test.length);
/**
* 通过索引删除数组元素
*
* @param int index 元素索引
* @returns array
*/
Array.prototype.deleteIndex = function(index){
return this.slice(0, index).concat(this.slice(parseInt(index, 10) + 1));
}
//示例
var test = new Array(1,5,3,4,2);
//输出5
console.log(test.length);
//删除索引为1的元素
test = test.deleteIndex(1);
//输出[1, 3, 4, 2]
console.log(test);
//输出4
console.log(test.length);


8、javascript获取光标位置以及设置光标位置

function getCursortPosition (ctrl) {//获取光标位置函数
var CaretPos = 0;	// IE Support
if (document.selection) {
ctrl.focus ();
var Sel = document.selection.createRange ();
Sel.moveStart ('character', -ctrl.value.length);
CaretPos = Sel.text.length;
}
// Firefox support
else if (ctrl.selectionStart || ctrl.selectionStart == '0')
CaretPos = ctrl.selectionStart;
return (CaretPos);
}


PS:参数ctrl为input或者textarea对象

function setCaretPosition(ctrl, pos){//设置光标位置函数
if(ctrl.setSelectionRange)
{
ctrl.focus();
ctrl.setSelectionRange(pos,pos);
}
else if (ctrl.createTextRange) {
var range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}
PS:参数ctrl为input或者textarea对象,pos为光标要移动到的位置。


9、javascript获取隐藏dom的宽高

一个隐藏的DOM是获取不到宽高的,如果想要获取,采用下面的方法:
首先clone一个DOM,设置position:absolute,然后设置top为一个比较大的负值,然后使其显示出来,最后获取到了DOM的宽高后,将其remove。

具体代码如下:

function getCss(elem, css){
if (window.getComputedStyle) {
return window.getComputedStyle(elem, null)[css];
}else if (elem.currentStyle) {
return elem.currentStyle[css];
}else {
return elem.style[css];
}
}
function getWH(dom){
var get = function(elem){
var wh = {};
'Width Height'.replace(/[^ ]+/g, function(i){
var a = i.toLowerCase();
wh[a] = elem['offset' + i] || elem['client' + i];
});
return wh;
};
if (getCss(dom, 'display') === 'none') {
var nDom = dom.cloneNode(true);
nDom.style.position = 'absolute';
nDom.style.top = '-3000px';
nDom.style.display = 'block';
document.getElementsByTagName('body')[0].appendChild(nDom);
var wh = get(nDom);
nDom.parentNode.removeChild(nDom);
return wh;
}
return get(dom);
}
//test
console.log(getWH(document.getElementById('content')));
var domA = document.createElement("a"), _ostyle = "position:absolute;z-index:999999;width:92px;height:22px;position:absolute;display:none;";
domA.setAttribute("style", _ostyle);
domA.style.cssText = _ostyle;
domA.setAttribute("href", "javascript:void(0);");
document.getElementsByTagName('body')[0].appendChild(o);
console.log(getWH(domA));


10、文字跟随鼠标波浪漂移的特效

CSS代码如下:

<style type="text/css">
body{
background-color:#004593;
}
.follow_mouse{
color:#fff000;
font-family:"微软雅黑",'宋体';
position:absolute;
font-size:14px;
}
</style>


JAVASCRIPT代码如下:

<script language="javascript">
(function(window, document){
var x,y;//鼠标当前在页面上的位置
var step = 15;//字符显示间距,为了好看,step=0则字符显示没有间距
var message = "恭喜,您又学习到一个小技术,感谢您的关注!";//跟随鼠标要显示的字符串
message = message.split("");//将字符串分割为字符数组
//可以在数组中加入自己喜欢的东东
message.push("<img width='20' height='20' src='http://images.gifmania.hk/Gifs-Halloween/Gifs-Halloween-Pumpkins/Gifs-Halloween-Pumpkins-Kids/halloween-pumpkins-children5.gif' />");
var xpos = new Array();//存储每个字符的x位置的数组
for(i=0; i<message.length; i++){
xpos[i] = -50;
}
var ypos = new Array();//存储每个字符的y位置的数组
for(i=0; i<message.length; i++){
ypos[i] = -50;
}
//动态生成显示每个字符span标记
for(i=0; i<message.length; i++){
//使用span来标记字符,是为了方便使用CSS,并可以自由的绝对定位
document.write("<span id='span" + i +"' class='follow_mouse'>");
document.write(message[i]);
document.write("</span>");
}
if (document.layers){
document.captureEvents(Event.MOUSEMOVE);
}
//从事件得到鼠标光标在页面上的位置
var handlerMM = function(e){
e = (e || window.event);
if(window.navigator.userAgent.indexOf('MSIE 6.0')!=-1){
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
else{
x = e.clientX;
y = e.clientY;
}
}
//重定位每个字符的位置
var makesnake = function(){
//第一个字符的坐标位置紧跟鼠标光标
xpos[0] = x + step;
ypos[0] = y;
for(var i=message.length-1; i>=1; i--) {
//从尾向头确定字符的位置,每个字符为前一个字符"历史"水平坐标+step间隔
//这样随着光标移动事件,就能得到一个动态的波浪状的显示效果
xpos[i] = xpos[i-1] + step;
//垂直坐标为前一字符的历史"垂直"坐标,后一个字符跟踪前一个字符运动
ypos[i] = ypos[i-1];
}
//上面的算法将保证,如果鼠标光标移动到新位置,则连续调用makenake将会使这些字符一个接一个的移动的新位置
// 该算法显示字符串就有点象人类的游行队伍一样
for(var i=0; i<=message.length-1; i++) {
var thisspan = document.getElementById("span" + i).style;
thisspan.left = xpos[i] + 'px';
thisspan.top = ypos[i] + 'px';
}
//设置10毫秒的定时器来连续调用makesnake(),时刻刷新显示字符串的位置。
var timer = setTimeout(makesnake, 50);
}
document.onmousemove = handlerMM;
window.onload = makesnake;
})(window, document);
</script>


11、获取数组中最大最小值方法

function getMaximin (arr,maximin) {
if (maximin == "max") {
return Math.max.apply(Math, arr);
}else if (maximin == "min") {
return Math.min.apply(Math, arr);
}
}
var a = [3,2,4,2,10]
var b = [12,4,45,786,9,78]
alert("aMax:" + getMaximin(a,"max") + "---aMin:" + getMaximin(a,"min") + "---bMax:" + getMaximin(b,"max") + "---bMin:" + getMaximin(b,"min"))
//aMax:10---aMin:2---bMax:786---bMin:4


12、javascript获取网页的大小

一、网页的大小和浏览器窗口的大小

一张网页的全部面积,就是它的大小。通常情况下,网页的大小由内容和CSS样式表决定。

浏览器窗口的大小,则是指在浏览器窗口中看到的那部分网页面积,又叫做viewport(视口)。

很显然,如果网页的内容能够在浏览器窗口中全部显示(也就是不出现滚动条),那么网页的大小和浏览器窗口的大小是相等的。

二、获取网页的大小

网页上的每个元素,都有clientHeight和clientWidth属性。这两个属性指元素的内容部分再加上padding的所占据的视觉面积,不包括border和滚动条占用的空间,因此,document元素的clientHeight和clientWidth属性,就代表了网页的大小。

网页上的每个元素还有scrollHeight和scrollWidth属性,指包含滚动条在内的该元素的视觉面积。那么,document对象的scrollHeight和scrollWidth属性就是网页的大小,意思就是滚动条滚过的所有长度和宽度。

如果网页内容能够在浏览器窗口中全部显示,不出现滚动条,那么网页的clientWidth和scrollWidth应该相等。但是实际上,不同浏览器有不同的处理,这两个值未必相等。所以,我们需要取它们之中较大的那个值。

获取网页大小的方法如下:

function getPagearea(){
if (document.compatMode == "BackCompat"){
        return {
width: Math.max(document.body.scrollWidth, document.body.clientWidth),
height: Math.max(document.body.scrollHeight, document.body.clientHeight)
}
} else {
return {
width: Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth),
height: Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight)
}
}
}


函数使用注意问题:

1、这个函数必须在页面加载完成后才能运行,否则document对象还没生成,浏览器会报错。

2、大多数情况下,都是document.documentElement.clientWidth返回正确值。但是,在IE6的quirks模式中,document.body.clientWidth返回正确的值,因此函数中加入了对文档模式的判断。

3、clientWidth和clientHeight都是只读属性,不能对它们赋值。

13、一个不错的JavaScript解析浏览器路径方法

<script>
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'
</script>
JavaScript中有时需要用到当前的请求路径等涉及到url的情况,正常情况下我们可以使用location对象来获取我们需要的信息,本文从另外一个途径来解决这个问题,而且更加巧妙


14、js操作select option

1、获取选中select的value和text,html代码如下:

<select id="mySelect">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

则可通过以下script代码s来获取选中的value和text

$("#mySelect").val(); //获取选中记录的value值
$("#mySelect option:selected").text(); //获取选中记录的text值

2、运用new Option("文本","值")方法添加选项option

var obj = document.getElementById("mySelect");
obj.add(new Option("4","4"));

3、删除所有选项option

var obj = document.getElementById("mySelect");
obj.options.length = 0;

4、删除选中选项option

var obj = document.getElementById("mySelect");
var index = obj.selectedIndex;
obj.options.remove(index);

5、修改选中选项option

var obj = document.getElementById("mySelect");
var index = obj.selectedIndex;
obj.options[index] = new Option("three",3); //更改对应的值
obj.options[index].selected = true; //保持选中状态

6、删除select

var obj = document.getElementById("mySelect");
obj.parentNode.removeChild(obj); //移除当前对象

7、select选择的响应事件

$("#mySelect").change(function(){
//添加所需要执行的操作代码
})

15、document.getElementsByClassName的理想实现

var getElementsByClassName = function (searchClass, node,tag) {
if(document.getElementsByClassName){
var nodes =  (node || document).getElementsByClassName(searchClass),result = [];
for(var i=0 ;node = nodes[i++];){
if(tag !== "*" && node.tagName === tag.toUpperCase()){
result.push(node)
}
}
return result
}else{
node = node || document;
tag = tag || "*";
var classes = searchClass.split(" "),
elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag),
patterns = [],
current,
match;
var i = classes.length;
while(--i >= 0){
patterns.push(new RegExp("(^|\\s)" + classes[i] + "(\\s|$)"));
}
var j = elements.length;
while(--j >= 0){
current = elements[j];
match = false;
for(var k=0, kl=patterns.length; k<kl; k++){
match = patterns[k].test(current.className);
if (!match)  break;
}
if (match)  result.push(current);
}
return result;
}
}


16、javascript判断数据类型

今天在封装MTJS的时候出现了一个问题,用于检查数据类型的typeof在检查数组和对象的时候出来的都是“object”;例如

alert(typeof []);
alert(typeof {});


赶紧问朋友,朋友推荐我使用 pjhome的方法,原来这个方法EXT框架上也有的:

function getType(o) {
var _t;
return ((_t = typeof(o)) == "object" ? o==null && "null" || Object.prototype.toString.call(o).slice(8,-1):_t).toLowerCase();}

alert(getType("abc")); //string
alert(getType(true)); //boolean
alert(getType(123)); //number
alert(getType([])); //array
alert(getType({})); //object
alert(getType(function(){})); //function
alert(getType(new Date)); //date
alert(getType(new RegExp)); //regexp
alert(getType(Math)); //math
alert(getType(null)); //null


  

很好很强大,这里Object.prototype.toString.call(o)的意思是借用Object原型的toString方法返回对象的字符串表示,就是0调用toString()方法,返回的格式是[Object array],再使用slice(8,-1)就能把“array”获取出来。(感谢rock,子房做的解释)

在自己搜索的时候还发现了另一种判断数据类型的方法,就是constructor(构造函数):


例如:

alert([].constructor==Array);
alert({}.constructor==Object);
alert("123".constructor==String);
alert((55).constructor==Number);
alert(true.constructor==Boolean);


17、如何将一个字符串反转

var testString = "123456";
testString=testString.split("").reverse().join("");
alert(testString);


如果不用reverse()的话还有一种实现字符串反转方式:


function reverse(str)
{
var a=str.split('');
var result=new Array();
while(a.length) {
result.push(a.pop());
}
return result.join('');
}


18、请编写一个JavaScript函数 parseQueryString,它的用途是把URL参数解析为一个对象,如: var url = ”http://www.taobao.com/index.php?key0=0&key1=1& key2=2…..”

function parseQueryString(url) {
var pos;
var obj = {};
if ((pos = url.indexOf("?")) != -1) {
var param = url.substring(pos+1, url.length - 1)
var paramArr = param.split('&');
var keyValue = [];
for (var i = 0, l = paramArr.length; i < l; i++) {
keyValue = paramArr[i].split('=');
obj[keyValue[0]] = keyValue[1];
}
}
return obj;
}

var paramMap = parseQueryString(url);


19、正则表达式获取页面url参数值

function getURLParam(name) {
var value = location.search.match(new RegExp("[?&]" + name + "=([^&]*)(&?)","i"));
return value ? decodeURIComponent(value[1]) : value;
}


20、Javascript图片等比例缩放

function resizeImg(img, oAW, oAH) {
var oimgW = img.width,
oimgH = img.height,
oimg = img,
oY = (oimgH / oimgW).toFixed(2),
oX = (oimgW / oimgH).toFixed(2);
if (oimgW <= oAW && oimgH <= oAH) { //图片高和宽比指定的宽高都小
oimg.style.height = oimgH + 'px';
oimg.style.width = oimgW + 'px';
} else if (oimgW >= oAW && oimgH >= oAH) { //图片高和宽比指定的宽高都大
if (oY * oAW >= oAH) { //图片高比宽大
oimg.style.height = oAH + 'px';
oimg.style.width = oX * oAH + 'px';
} else { //图片高比宽小
oimg.style.height = oY * oAH + 'px';
oimg.style.width = oAW + 'px';
}
} else if (oimgW > oAW && oimgH < oAH) { //图片宽比指定宽大,高比指定的小
oimg.style.height = oY * oAW + 'px';
oimg.style.width = oAW + 'px';
} else if (oimgW < oAW && oimgH > oAH) { //图片宽比指定宽小,高比指定的大
oimg.style.height = oAH + 'px';
oimg.style.width = oX * oAH + 'px';
}
};
function resizeImgMid(img,oAW,oAH){
var oimgW = img.width,
oimgH =  img.height,
oimg = img,
oY = (oimgH/oimgW).toFixed(2),
oX = (oimgW/oimgH).toFixed(2);
if(oimgW <= oAW&&oimgH <= oAH){//图片高和宽比指定的宽高都小
oimg.style.height = oimgH+'px';
oimg.style.width = oimgW+'px';
oimg.style.marginLeft = 1/2*(oAW-oimgW)+'px';
oimg.style.marginTop = 1/2*(oAH-oimgH)+'px';
} else if(oimgW >= oAW&&oimgH >= oAH){//图片高和宽比指定的宽高都大
if(oY*oAW>=oAH){ //图片高比宽大
oimg.style.height = oAH+'px';
oimg.style.width = oX*oAH+'px';
oimg.style.marginLeft = 1/2*(oAW-oX*oAH)+'px';
oimg.style.marginTop = 0;
}else{ //图片高比宽小
oimg.style.height = oY*oAH+'px';
oimg.style.width = oAW+'px';
oimg.style.marginLeft = 0;
oimg.style.marginTop = 1/2*(oAH-oY*oAW)+'px';
}
}else if(oimgW>oAW &&oimgH < oAH){//图片宽比指定宽大,高比指定的小
oimg.style.height = oY*oAW+'px';
oimg.style.width = oAW+'px';
oimg.style.marginLeft = 0;
oimg.style.marginTop = 1/2*(oAH-oY*oAW)+'px';
}else if(oimgW<oAW &&oimgH > oAH){//图片宽比指定宽小,高比指定的大
oimg.style.height = oAH+'px';
oimg.style.width = oX*oAH+'px';
oimg.style.marginLeft = 1/2*(oAW-oX*oAH)+'px';
oimg.style.marginTop = 0;
}
}
//替换图片资源不存在的图片地址
function imgonerror(img){
var noneImg = "http://****.com/mmtTrade/images/nopic.jpg";
img.src = noneImg;
img.onerror == null;
}


21、javascript 截取中英文字符串

/**
* 统计字符串长度,中文2的长度
* @returns
*/
String.prototype.len = function() {
return this.replace(/[^\x00-\xff]/g, "**").length;
};
/**
* 字符串截取
* @param len
* @returns
*/
String.prototype.cutStr = function(n) {
var r = /[^\x00-\xff]/g;
if (this.replace(r, "**").length <= n) return this;
var m = Math.floor(n/2);
for (var i=m; i<this.length; i++) {
if (this.substr(0, i).replace(r,"**").length >= n) {
return this.substr(0,i) + "...";
}
return this;
}
};


22、查找字符串中出现次数最多的最长子串

原题描述:找出一个字符串中连续出现最多的最长子串。比如 abcdfeatecabcdlkxabcd 出现最多的是abcd。

String.prototype.mostLongest = function() {
var str = this, strLenth = str.length, longStr = [], maxNum = 1, maxLength = strLenth, arr = [], count = function(
num) {
for ( var i = strLenth - num + 1; i > -1 ; i--) {
var temp = str.substr(i, num);
arr[temp] = ~~arr[temp] + 1;
if (arr[temp] > maxNum) {
maxNum = arr[temp];
longStr = [];
longStr.push(temp);
maxLength = num;
} else if (arr[temp] == maxNum) {
if (num > maxLength) {
maxNum = arr[temp];
longStr = [];
longStr.push(temp);
maxLength = num;
}else if(num === maxLength){
longStr.push(temp);
}
}
}
num > 2 && count(num - 1);
};
count(strLenth);

return longStr;
}


23、JS获取MAC地址

function MacInfo() {
var locator = new ActiveXObject("WbemScripting.SWbemLocator");
var service = locator.ConnectServer(".");
var properties = service.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled =True");
var e = new Enumerator(properties);
{
var p = e.item();
var mac = p.MACAddress;
document.getElementById("<%=hd_macAddress.ClientID %>").value = unescape(mac);
}
}


24、实现string的substring方法

方法一:用charAt取出截取部分

String.prototype.mysubstring=function(beginIndex,endIndex){
var str=this,
newArr=[];
if(!endIndex){
endIndex=str.length;
}
for(var i=beginIndex;i<endIndex;i++){
newArr.push(str.charAt(i));
}
return newArr.join("");
}

//test
"Hello world!".mysubstring(3);//"lo world!"
"Hello world!".mysubstring(3,7);//"lo w"


方法二:把字符串转换成数组然后取出需要部分

String.prototype.mysubstring=function(beginIndex,endIndex){
var str=this,
strArr=str.split("");
if(!endIndex){
endIndex=str.length;
}
return strArr.slice(beginIndex,endIndex).join("");
}

//test
console.log("Hello world!".mysubstring(3));//"lo world!"
console.log("Hello world!".mysubstring(3,7));//"lo w"


String.prototype.mysubstring=function(beginIndex,endIndex){
var str=this,
beginArr=[],
endArr=[];
if(!endIndex){
endIndex=str.length;
}
for(var i=0;i<beginIndex;i++){
beginArr.push(str.charAt(i));
}
for(var i=endIndex;i<str.length;i++){
endArr.push(str.charAt(i));
}
return str.replace(beginArr.join(""),"").replace(endArr.join(""),"");
}

//test
console.log("Hello world!".mysubstring(3));//"lo world!"
console.log("Hello world!".mysubstring(3,7));//"lo w"


25、篇历DOM树

方法一:用nextSibling和childNodes

function traversalByNextSibling(obj){
var ch=obj.firstChild,
result=[];
do{
result.push(ch.nodeName);
if(ch.childNodes.length){
result.push.apply(result,traversalByNextSibling(ch));
}
}while(ch=ch.nextSibling);
return result;
}


方法二:用childNodes

function traversalByChildNodes(obj){
var ch=obj.childNodes,
result=[];
for(var i=0,j=ch.length;i<j;i++){
result.push(ch[i].nodeName);
if(ch[i].childNodes.length){
[].push.apply(result,traversalByChildNodes(ch[i]));
}
}
return result;
}


测试:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<style type="text/css">

</style>
</head>
<body>
<div id="test">Test</div>
<div>Hello World</div>
<p>PTest</p>
<script>
console.log(traversalByNextSibling(document));
//IE6-8: #comment,HTML,HEAD,TITLE,META,STYLE,BODY,DIV,#text,DIV,#text,P,#text,SCRIPT
//other:["html", "HTML", "HEAD", "#text", "META", "#text", "TITLE", "#text", "#text", "STYLE", "#text", "#text", "#text", "BODY", "#text", "DIV", "#text", "#text", "DIV", "#text", "#text", "P", "#text", "#text", "SCRIPT", "#text"]

console.log(traversalByChildNodes(document));
//IE6-8: #comment,HTML,HEAD,TITLE,META,STYLE,BODY,DIV,#text,DIV,#text,P,#text,SCRIPT
//otehr:["html", "HTML", "HEAD", "#text", "META", "#text", "TITLE", "#text", "#text", "STYLE", "#text", "#text", "#text", "BODY", "#text", "DIV", "#text", "#text", "DIV", "#text", "#text", "P", "#text", "#text", "SCRIPT", "#text"]
</script>
</body>
</html>


在IE6-8中把换行去掉了,在其他浏览器中把换行作为一个文本节点,所以会有很多#text,但IE6-8中出现了#comment我现在也没明白为什么。

26、js数组去重

自己写的js数组去重的拓展方法:

Array.prototype.delRepeat=function(){
var newArray=new Array();
var len=this.length;
for (var i=0;i<len ;i++){
for(var j=i+1;j<len;j++){
if(this[i]===this[j]){
j=++i;
}
}
newArray.push(this[i]);
}
return newArray;
}


在网上又看到有人用以下四种算法来实现这个目的:


Array.prototype.unique1 = function () {
var n = []; //一个新的临时数组
for (var i = 0; i < this.length; i++) //遍历当前数组
{
//如果当前数组的第i已经保存进了临时数组,那么跳过,
//否则把当前项push到临时数组里面
if (n.indexOf(this[i]) == -1) n.push(this[i]);
}
return n;
}


Array.prototype.unique2 = function()
{
var n = {},r=[]; //n为hash表,r为临时数组
for(var i = 0; i < this.length; i++) //遍历当前数组
{
if (!n[this[i]]) //如果hash表中没有当前项
{
n[this[i]] = true; //存入hash表
r.push(this[i]); //把当前数组的当前项push到临时数组里面
}
}
return r;
}


Array.prototype.unique3 = function()
{
var n = [this[0]]; //结果数组
for(var i = 1; i < this.length; i++) //从第二项开始遍历
{
//如果当前数组的第i项在当前数组中第一次出现的位置不是i,
//那么表示第i项是重复的,忽略掉。否则存入结果数组
if (this.indexOf(this[i]) == i) n.push(this[i]);
}
return n;
}


其中第1种和第3种方法都用到了数组的indexOf方法。此方法的目的是寻找存入参数在数组中第一次出现的位置。很显然,js引擎在实现这个方法的时候会遍历数组直到找到目标为止。所以此函数会浪费掉很多时间。 而第2中方法用的是hash表。把已经出现过的通过下标的形式存入一个object内。下标的引用要比用indexOf搜索数组快的多。

为了判断这三种方法的效率如何,我做了一个测试程序,生成一个10000长度的随机数组成的数组,然后分别用几个方法来测试执行时间。 结果表明第二种方法远远快于其他两种方法。 但是内存占用方面应该第二种方法比较多,因为多了一个hash表。这就是所谓的空间换时间。 就是这个 测试页面,你也可以去看看。

第四种方法:

Array.prototype.unique4 = function()
{
this.sort();
var re=[this[0]];
for(var i = 1; i < this.length; i++)
{
if( this[i] !== re[re.length-1])
{
re.push(this[i]);
}
}
return re;
}


这个方法的思路是先把数组排序,然后比较相邻的两个值。 排序的时候用的JS原生的sort方法,JS引擎内部应该是用的快速排序吧。 最终测试的结果是此方法运行时间平均是第二种方法的三倍左右,不过比第一种和第三种方法快了不少。

27、JS判断鼠标从什么方向进入一个容器

偶然将想到的一个如何判断鼠标从哪个方向进入一个容器的问题。首先想到的是给容器的四个边添加几个块,然后看鼠标进入的时候哪个块先监听到鼠标事件。不过这样麻烦太多了。google了一下找到了一个不错的解决方法,是基于jquery的,原文地址

说实话,其中的var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;这句用到的数学知识我是真没有看明白,原文中有一些英文注释我就不一一说明了。代码部分不是很多,我直接写了个示例。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>判断鼠标进入方向</title>
</head>
<body>
<style>
html,body{margin:0;padding:0;}
#wrap{width:300px;height:300px;background:#33aa00;margin:50px;display:inline-block;font-size:50px;text-align:center;line-height:300px;}
</style>
<div id="wrap">
方向反馈
</div>
<script type="text/javascript" src="http://www.niumowang.org/wp-content/themes/pizi/jquery-1.6.4.min.js"></script>
<script>
$("#wrap").bind("mouseenter mouseleave",
function(e) {
var w = $(this).width();
var h = $(this).height();
var x = (e.pageX - this.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);
var y = (e.pageY - this.offsetTop - (h / 2)) * (h > w ? (w / h) : 1);
var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
var eventType = e.type;
var dirName = new Array('上方','右侧','下方','左侧');
if(e.type == 'mouseenter'){
$(this).html(dirName[direction]+'进入');
}else{
$(this).html(dirName[direction]+'离开');
}
});
</script>
</body>
</html>


鼠标移动到上面,可以看到效果。其中返回的direction的值为“0,1,2,3”分别对应着“上,右,下,左”
所以结果值可以switch循环

switch (direction) {
case 0:
$(this).html('上方进入');
break;
case 1:
$(this).html('右侧进入');
break;
case 2:
$(this).html('下方进入');
break;
case 3:
$(this).html('左侧进入');
break;
}


原文代码是基于jquery的,后面我写了个原生的js效果,代码没有封装,给需要的朋友。由于firefox等浏览器不支持mouseenter,mouseleave事件,所以我暂时用mouseover,mouseout代替了,如果大家需要解决冒泡问题的话,还是自行搜索兼容性解决方法吧。

var wrap = document.getElementById('wrap');
var hoverDir = function(e){
var w=wrap.offsetWidth;
var h=wrap.offsetHeight;
var x=(e.clientX - wrap.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);
var y=(e.clientY - wrap.offsetTop - (h / 2)) * (h > w ? (w / h) : 1);
var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
var eventType = e.type;
var dirName = new Array('上方','右侧','下方','左侧');
if(e.type == 'mouseover' || e.type == 'mouseenter'){
wrap.innerHTML=dirName[direction]+'进入';
}else{
wrap.innerHTML=dirName[direction]+'离开';
}
}
if(window.addEventListener){
wrap.addEventListener('mouseover',hoverDir,false);
wrap.addEventListener('mouseout',hoverDir,false);
}else if(window.attachEvent){
wrap.attachEvent('onmouseenter',hoverDir);
wrap.attachEvent('onmouseleave',hoverDir);
}


28、js判断flash是否安装及其版本

<script type="text/javascript">
function flashChecker(){
var hasFlash = 0; //是否安装了flash
var flashVersion = 0; //flash版本
var isIE = /*@cc_on!@*/0; //是否IE浏览器
if(isIE){
var swf = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
if(swf){
hasFlash = 1;
VSwf = swf.GetVariable('$version');
flashVersion = parseInt(VSwf.split(' ')[1].split(',')[0]);
}
}
else{
if (navigator.plugins && navigator.plugins.length > 0){
var swf = navigator.plugins['Shockwave Flash'];
if (swf){
hasFlash = 1;
var words = swf.description.split(' ');
for (var i = 0; i < words.length; ++i)
{
if (isNaN(parseInt(words[i]))) continue;
flashVersion = parseInt(words[i]);
}
}
}
}
return {f:hasFlash,v:flashVersion};
}
var fls = flashChecker();
if(fls.f){
document.write('安装了flash,当前flash版本为: '+fls.v+'.x');
}
else{
document.write('没有安装flash');
}
</script>


29、判断iframe框架是否加载完成的方法

理论上来说框架里面加载的是一个完成的html文档,其判断的方法和平常html文件加载应该一致。最近在一个项目中用到了iframe框架,需要判断框架中的文档是否加载完毕,加载完后再进行下一步的操作,这里找到了几个方法来实现判断:

var iframe = document.createElement("iframe");
iframe.src = "http://www.cnblogs.com/lifeil/";

if (!/*@cc_on!@*/0) { //if not IE
iframe.onload = function(){
alert("框架加载完毕.");
};
} else {
iframe.onreadystatechange = function(){
if (iframe.readyState == "complete"){
alert("框架加载完毕.");
}
};
}

document.body.appendChild(iframe);


后来有个牛人找到了如下更完美的处理方法:

var iframe = document.createElement("iframe");
iframe.src = "http://www.cnblogs.com/lifeil/";

if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
alert("Local iframe is now loaded.");
});
} else {
iframe.onload = function(){
alert("Local iframe is now loaded.");
};
}

document.body.appendChild(iframe);


相比较值钱的方法可以发现,这个方法使用了onload方法来判断,这种方法判断框架是否加载完毕比之前的readystatechange 事件更加稳定。在IE浏览器中,需要通过attachEvent方法来注册onload事件。这样就可以完美的判断框架是否加载完毕了。

PS:这里说的IE浏览器中onload方法是隐形的是指,动态创建的iframe需要通过attachEvent来绑定事件,而已经存在写在html文档里面的IE中也支持iframe.onload事件.

30、将js对象转成字符串

function obj2str(obj){
var S = [];
var J = "";
if (Object.prototype.toString.apply(obj) === '[object Array]') {
for (var i = obj; i < obj.length; i++)
S.push(this.jsonToString(obj[i]));
J = '[' + S.join(',') + ']';
}
else if (Object.prototype.toString.apply(obj) === '[object Date]') {
J = "new Date(" + obj.getTime() + ")";
}
else if (Object.prototype.toString.apply(obj) === '[object RegExp]' || Object.prototype.toString.apply(obj) === '[object Function]') {
J = obj.toString();
}
else if (Object.prototype.toString.apply(obj) === '[object Object]') {
for (var i in obj) {
var obj2={};
obj2[i] = typeof (obj[i]) == 'string' ? '"' + obj[i] + '"' : (typeof (obj[i]) === 'object' ? this.jsonToString(obj[i]) : obj[i]);
S.push(i + ':' + obj2[i]);
}
J = '{' + S.join(',') + '}';
}
return J;
}


31、从身份证中获取出生日期

function getBirth(value) {
if(!value) {
return "";
}
var year = "1900";
var month = "1";
var day = "1";
if (value.length == 15) {
year = "19" + value.substr(6, 2);
month = value.substr(8, 2);
day = value.substr(10, 2);
}
else if (value.length == 18) {
year = value.substr(6, 4);
month = value.substr(10, 2);
day = value.substr(12, 2);
}
else {
return "";
}
newDate = new Date(year, month - 1, day);
if (newDate.toString() == "NaN") {
return "";
}
else {
return year + "-" + month + "-" + day;
}
}


32、从身份证中获取出性别

function getSex(value) {
if (!value)
{ return "未知";
}
else if (value.length == 15) {
return parseInt(value.substr(14, 1),10)%2?"男":"女";
}
else if (value.length == 18) {
return parseInt(value.substr(17, 1),10)%2?"男":"女";
}
else {
return "未知";
}
}


33、关闭当前页面

function  closewin(){
window.opener=null;
window.open('','_self');
window.close();
//因为火狐的安全性设置,不允许脚本关闭页面,所以,无效,需要用户进行设置,其他浏览器均执行
}


34、

//动态载入flash文件 *.swf – addSWF()
/*
用于页面动态添加swf文件。主要是解决浏览器载入插件的差异问题。
调用如下:
addSWF(containerElement, swfid, url, flashvars, width, height):void
containerElement – 是容器对象,如果添加到body里,则为:document.body
swfid – 添加好的flash插件id
url – swf文件的绝对地址
flashvars – 浏览器加载swf文件的初始化参数,格式为:a=4&b=6
width 和 height – swf显示的尺寸,像素单位,如果有一个填写0,则不显示。*/
addSWF:function (box,swfId,url,flashvars,width,height){
var fp = d.createElement('embed');
if(!width || !height)
{
fp.style.visibility = 'hidden';
fp.width = 0;
fp.height = 0;
}
else
{
fp.width = width;
fp.height = height;
}
fp.type = 'application/x-shockwave-flash';
fp.id = swfId;
fp.setAttribute('name',swfId);
fp.setAttribute('allowScriptAccess','always');
fp.setAttribute('flashvars',flashvars);
fp.src = url;
box.appendChild(fp);
},
// 获得载入flash文件对象 – getSWFObject(name)
/*    和加载swf文件组合使用。当添加的flash文件需要被页面js调用的时候,用此方法获得者个插件的对象,参数是添加时候填入的id。如:
var swf = getSWFObject(‘idname’);
swf.play();*/
getSWFObject:function (name){
return document.embeds[name];
},
//addCss添加一个css文件到head区末端,调用方式:addCss(‘url string’):void
addCss:function (url){
if(!url) return;
var link = d.createElement('link');
link.href = url;
link.type = 'text/css';
link.rel = 'stylesheet';
d.getElementsByTagName('head')[0].appendChild(link);
},
/*  addScript and addScriptList
addScript添加一个js文件到head区末端,调用方式:
addScript(“url string”, callback):void
addScriptList,批量添加一组js文件到head区域末端,调用方式:
addScriptList([‘a.js’, ‘b.js’], callback):void
本方法的回调在所有js文件全部加载完成后出发。*/
addScript:function (url,fn){
if(!url) return;
var s = d.createElement('script');
var ieVersion = /(6.0)|(7.0)|(8.0)/;
if( ieVersion.test(hc.b.MSIE) )
{
s.onreadystatechange = function()
{
if( (this.readyState==='loaded'||this.readyState==='complete')&&fn ) fn();
}
}
else s.onload = function(){ if(fn) fn() };
s.type = 'text/javascript';
s.src = url;
s.setAttribute('charset','utf-8');
d.getElementsByTagName('head')[0].appendChild(s);
},
addScriptList:function (urls,fn){
var sarr = [];
var len = urls.length;
function pul()
{
//console.log(sarr)
sarr.push(1);
if( sarr.length === len && fn ) fn();
}
for(var i=0;i<len;i++)
{
this.addScript(urls[i],pul);
}
},
/*clickRecorder:此法方是一个使用频率很高的业务性api,用来发送点击检测键值,发送的是一个字符串,如:clickRecorder(‘webim=open’):void*/
clickRecorder:function (key){
var url = 'http://log.info.hc360.com/click.htm';
var r = new Date().getTime() + '_' +  Math.random()*Math.pow(10,18);
new Image().src = url + '?' + key + '&r=' + r;
},
//浏览器检测,并且把检测结果放在b{}对象下
/*b是一个Object类型,有如下值:
1)“浏览名称”:“版本号”,如 “Chrome”: “24.5”.
2)“name”:”浏览器名称”
3)“version”:”浏览器版本号”
4)“cover”:””,这个值只在使用了chrome内核的二次开发浏览器中出现,如搜狗,360急速等。
5)1,2,3貌似重复,这里主要是为了提供一种简单的用法,如:HC.b.MSIE === ‘6.0’。*/
getBrowser:function (){
var bs = {}, u = window.navigator.userAgent;
var msie = /(MSIE) ([\d.]+)/,
chrome = /(Chrome)\/([\d.]+)/,
firefox = /(Firefox)\/([\d.]+)/,
safari = /(Safari)\/([\d.]+)/,
opera = /(Opera)\/([\d.]+)/;
var b = u.match(msie)||u.match(chrome)||u.match(firefox)||u.match(safari)||u.match(opera);
if(b[1]==='Opera') b[2] = u.match(/(Version)\/([\d.]+)/)[2];
var cover = u.match(/(QQBrowser)|(Maxthon)|(360EE)|(360SE)|(SE 2.X MetaSr 1.0)/);
bs[b[1]] = b[2];
bs['name'] = b[1];
bs['version'] = b[2];
if(cover && cover[0]) bs['cover'] = cover[0];
return bs;
}


35、javascript简单实现checkbox的全选与反选

$.fn.checkbox = function(){
var t = this;
/*
* 切换全选/反选
* @example $("#checkAll").checkbox().toggle($("input[name='selectAll']"));
*/
this.toggle = function(el){
$(el).click(function(){
$(t).attr('checked', false);
});
$(this).click(function(){
$(el).attr('checked', $(this).attr('checked') == true ? true : false);
});
};
/*
* 全选
*/
this.check = function(el){
$(el).attr('checked', true);
};
/*
* 反选
*/
this.uncheck = function(el){
$(el).attr('checked', false);
};
return t;
};


36、利用XMLHttpRequest对象



//创建XMLHttpRequest对象
var xhr=window.XMLHttpRequest?new XMLHttpRequest?new ActiveXObject('Microsoft.XMLHTTP');
//打开open有五个参数,发送类型、url、isAsy是否异步、username、password
xhr.open('GET','test.jsp?a=1&b=2',true);
//如果是POST方式还需要设置http的请求头
xhr.setRequestHeader('Content-Type',"text/html");
//发送数据
xhr.send();
//注册回调事件,不同相应状态进行处理
xhr.onreadystatechange=function(){
//请求完成
if(xhr.readyState==4&xhr.status==200){
//处理返回数据
var respondText=xhr.respondText;
alert(respondText);
}
}


参考:http://www.cnblogs.com/moltboy/archive/2013/05/14/3078967.html

37、javascript实现jsonp

function jsonp(url,data,callback){
//创建全局函数callbackname处理返回的数据,拼接url
var callbackname='callbackname'+Math.floor(Math.random()*1E10)+'_'+new Date().getTime();
if(!url){
url +="?jsoncallback="+callbackname;
if(data){
for(param in data){
url +="&"+param+"="+data[param];
}
}
}
window[callbackname]=function(data){
if(typeof(callback)==="function"){
callback(data);
}
window.callbackname=null;
}
//addScript
var s=document.createElement('script');
if(s.onreadystatechange){
s.onreadystatechange=function(){
if(s.readyState=='loaded'||s.readyState=='complete'){
callback();
}
}

}
else{
s.onload=function(){
callback();
}
}
s.type='text/javascript';
s.src=url;
s.setAttribute('charset','utf-8');
document.getElementsByTagName('head')[0].appendChild(s);
}


38、编写一个方法 求一个字符串的字节长度

假设:

一个英文字符占用一个字节,一个中文字符占用两个字节

function getBytes(str){
var len=str.length;
var bytes=len;
for(var i=0;i<len;i++){
if(str.charCodeAt(i)>255){
bytes++;
}
return bytes;
}
}
alert(getBytes("测试aadd地方法"));


39、鼠标单击Button1后将Button1移动到Button2的后面<div> <input type=”button” id =”button1″ value=”1″ onclick=”???”> <input type=”button” id =”button2″ value=”2″ /”> </div>

<div>
<input type="button" id ="button1" value="1" onclick="moveBtn(this);">
<input type="button" id ="button2" value="2" />
</div>
<script type="text/javascript">
function moveBtn(obj) {
var clone = obj.cloneNode(true);
var parent = obj.parentNode;
parent.appendChild(clone);
parent.removeChild(obj);
}
</script>


40、JavaScript有哪几种数据类型

简单:Number,Boolean,String,Null,Undefined

复合:Object,Array,Function

41、JavaScript中如何对一个对象进行深度clone

function cloneObject(o) {
if(!o || 'object' !== typeof o) {
return o;
}
var c = 'function' === typeof o.pop ? [] : {};
var p, v;
for(p in o) {
if(o.hasOwnProperty(p)) {
v = o[p];
if(v && 'object' === typeof v) {
c[p] = Ext.ux.clone(v);
}
else {
c[p] = v;
}
}
}
return c;
};


42、如何控制alert中的换行

\n alert(“p\np”);


43、请实现,鼠标点击页面中的任意标签,alert该标签的名称.(注意兼容性)

document.onclick = function(evt){
var e = window.event || evt;
var tag = e["target"] || e["srcElement"];
alert(tag.tagName);
};


44、编写一个JavaScript函数 parseQueryString,它的用途是把URL参数解析为一个对象

function parseQueryString(url){
var params = {};
var arr = url.split("?");
if (arr.length <= 1)
return params;
arr = arr[1].split("&");
for(var i=0, l=arr.length; i<l; i++){
var a = arr[i].split("=");
params[a[0]] = a[1];
}
return params;
}
var url = "http://witmax.cn/index.php?key0=0&key1=1&key2=2";
var ps = parseQueryString(url);
alert(ps["key1"]);


45、定义一个对象o,o中有两个方法,getO()和setO(str),str是字符串。默认情况下调用getO() ,输出结果是"aaa",当setO("bbb")后,再次调用getO(),得到结果“bbb”

window.o = {

str : "aaa",
getO : function() {
return this.str;
},
setO : function(str) {
this.str = str;
}
};


46、<ul id="test"><li>a</li><li>b</li><li>c</li></ul>

1) len的数值
2)不用innerHTML清空ul
3)向UL新添加一个li节点,文本为“HELLO WORLD”
4)向次新节点添加自定义属性“index” ,值是new

window.onload=function(){
var list = document.getElementById("test");
var len  = list.children.length;
var elem = document.getElementsByTagName("li");

alert( len );

while( len ){

list.removeChild( elem[0] );
len--;
}

var newLi=document.createElement("li");
newLi.innerHTML = "HELLO WORLD";
list.appendChild(newLi);

newLi.setAttribute("index","new");

}


47、写一个获取非行间样式的函数

function getStyle(obj,attr,value){
if(!value)
{
if(obj.currentStyle)

{
return obj.currentStyle(attr)
}
else
{
obj.getComputedStyle(attr,false)
}

}
else
{

obj.style[attr]=value

}
}


另一个获取当前元素样式:

function getStyle(oElm, strCssRule){
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle){
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle){
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
}


var elementFontSize = getStyle(document.getElementById("container"), "font-size");


48、JavaScript中如何对一个对象进行深复制

http://segmentfault.com/q/1010000000148290

49、JS正则表达式验证账号、手机号、电话和邮箱

验证帐号是否合法
验证规则:字母、数字、下划线组成,字母开头,4-16位。

function
checkUser(str){
var
re = /^[a-zA-z]\w{3,15}$/;
if(re.test(str)){
alert("正确");
}else{
alert("错误");
}
}
checkUser("jihua_cnblogs");//调用


验证手机号码
验证规则:11位数字,以1开头。

function
checkMobile(str) {
var
re = /^1\d{10}$/
if (re.test(str)) {
alert("正确");
} else {
alert("错误");
}
}
checkMobile('13800138000'); //调用
checkMobile('139888888889');//错误示例


验证电话号码
验证规则:区号+号码,区号以0开头,3位或4位
号码由7位或8位数字组成
区号与号码之间可以无连接符,也可以“-”连接
如01088888888,010-88888888,0955-7777777

function
checkPhone(str){
var
re = /^0\d{2,3}-?\d{7,8}$/;
if(re.test(str)){
alert("正确");
}else{
alert("错误");
}
}
checkPhone("09557777777");//调用


验证邮箱
验证规则:姑且把邮箱地址分成“第一部分@第二部分”这样
第一部分:由字母、数字、下划线、短线“-”、点号“.”组成,
第二部分:为一个域名,域名由字母、数字、短线“-”、域名后缀组成,
而域名后缀一般为.xxx或.xxx.xx,一区的域名后缀一般为2-4位,如cn,com,net,现在域名有的也会大于4位

function
checkEmail(str){
var
re = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/
if(re.test(str)){
alert("正确");
}else{
alert("错误");
}
}
checkEmail("contact@cnblogs.com");//调用


检查 email 地址的正则表达式

function IsMatchingAddress(str){
var myRegExp = /[a-z0-9-]{1,30}@[a-z0-9-]{1,65}.[a-z]{3}/ ;
return myRegExp.test(str)
}


function IsMatchingAddress(str){
var myRegExp = /[a-z0-9-.]{1,30}@[a-z0-9-]{1,65}.(com|net|org|info|biz|([a-z]{2,3}.[a-z]{2}))/ ;
return myRegExp.test(str)
}


或者

/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/


删除javascript中注释语句的正则表达式

function removeJsComments(code)
{
return code.replace(/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g, '\n').replace(/(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/g, '\n');
}


多行注释:

/(?:^|\n|\r)\s*\/\*[\s\S]*?\*\/\s*(?:\r|\n|$)/g


单行注释:

/(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/g


50、JavaScript 正则表达式 验证整数、小数、实数、有效位小数最简单

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 验证数字最简单正则表达式大全 </title>
</head>
<body>
<h3>输入完按回车后即可验证!(自认为最简单!)</h3>
正整数:    <input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^\d+$/.test(this.value));" />
<br>
负整数:    <input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-\d+$/.test(this.value));" />
<br>
整 数:    <input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-?\d+$/.test(this.value));" />
<br>
正小数:    <input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^\d+\.\d+$/.test(this.value));" />
<br>
负小数:    <input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-\d+\.\d+$/.test(this.value));" />
<br>
小 数:    <input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-?\d+\.\d+$/.test(this.value));" />
<br>
实 数:    <input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-?\d+\.?\d*$/.test(this.value));" />
<br>
保留1位小数:<input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-?\d+\.?\d{0,1}$/.test(this.value));" />
<br>
保留2位小数:<input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-?\d+\.?\d{0,2}$/.test(this.value));" />
<br>
保留3位小数:<input type="text" size="20" onkeydown="if(event.keyCode == 13) alert(/^-?\d+\.?\d{0,3}$/.test(this.value));" />
<br>
</body>
</html>


51、请举例使用callee属性实现函数的递归使用

var sum=function(num){
if(num<=1){
return num;
}
else{
return arguments.callee(num-1)*num;
}
}
console.log("5!=="+sum(5));


52、javascript闭包

var oLis=document.getElementsByTagName('p');
for(var i=0;i<oLis.length;i++){
(function(i){
oLis[i].onclick=function(){
console.log(i);//这次就依次弹出0,1,2,3了
};
})(i);

}


53、快速排序

function quickSort(arr){
if(arr.length <= 1) return arr;//判断是否有效数组
var cut = Math.floor(arr.length/2);//取中间下标
var left = [],right = [];
var num = arr.splice(cut,1)[0];//取基准值
for(var i = 0;i < arr.length;i ++){
if(arr[i] < num){
left.push(arr[i]);//小的放左边
}else {
right.push(arr[i]);//大的放右边
}
}
return quickSort(left).concat(num,quickSort(right));//递归
}


54、http://www.css88.com/archives/5180 

55、js实现类似于add(1)(2)(3)调用方式的方法

function add(x) {
var sum = x;
var tmp = function (y) {
sum = sum + y;
return tmp;
};
tmp.toString = function () {
return sum;
};
return tmp;
}
console.log(add(1)(2)(3));  //6
console.log(add(1)(2)(3)(4));   //10


首先要一个数记住每次的计算值,所以使用了闭包,在tmp中记住了x的值,第一次调用add(),初始化了tmp,并将x保存在tmp的作用链中,然后返回tmp保证了第二次调用的是tmp函数,后面的计算都是在调用tmp, 因为tmp也是返回的自己,保证了第二次之后的调用也是调用tmp,而在tmp中将传入的参数与保存在作用链中x相加并付给sum,这样就保证了计算;

但是在计算完成后还是返回了tmp这个函数,这样就获取不到计算的结果了,我们需要的结果是一个计算的数字那么怎么办呢,首先要知道JavaScript中,打印和相加计算,会分别调用toString或valueOf函数,所以我们重写tmp的toString和valueOf方法,返回sum的值;

56、用JS实现一个数组合并的方法(要求去重)。

//如果用jQuery
var a =  [1, 2, 3, 4, 5];
var b =  [2, 4, 6, 7, 8];
$.merge(a,b);
console.log($.unique(a));

// 原生方法第一种   但是不能去
var mergeTo = [4,5,6],
mergeFrom = [7,8,9];

mergeTo = mergeTo.concat(mergeFrom);
mergeTo; // is: [4, 5, 6, 7, 8, 9]

or
var a = [1,2], b = [3,4], c = a.concat(b);

// 第二种
var mergeTo = [4,5,6],
var mergeFrom = [7,8,9];

Array.prototype.push.apply(mergeTo, mergeFrom);

mergeTo; // is: [4, 5, 6, 7, 8, 9]


57、用JS写一个实现继承的方法。

function A(name){
this.name=name;
}
A.prototype.getName=function(){
alert(this.name);
}

function B(){
}
B.prototype=new A("jack");
B.prptotype.constructor=B;
var b=new B();


function  Person(name,age,love){
this.name=name;
this.age=age;
this.love=love;
this.say=function say(){
alert("姓名:"+name);
}
}

//call方式
function student(name,age){
Person.call(this,name,age);
}

//apply方式
function teacher(name,love){
Person.apply(this,[name,love]);
//Person.apply(this,arguments); //跟上句一样的效果,arguments
}

//call与aplly的异同:
//1,第一个参数this都一样,指当前对象
//2,第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以)

var per=new Person("武凤楼",25,"魏荧屏"); //输出:“武凤楼”
per.say();
var stu=new student("曹玉",18);//输出:“曹玉”
stu.say();
var tea=new teacher("秦杰",16);//输出:“秦杰”
tea.say();


58、

<script>
var str=" 1852145998 020-888-999845 测试 021  -  85421987, 19865754";
var reg=/(1\d+)|(0\d{2}(\s*-\s*\d+)+)/g;
alert(str.match(reg));
</script>


59、用js实现一个电话号码提取的方法。
例如:" 1852145998 020-888-999845 测试 021 - 85421987, 19865754"
得到的结果应该是[1852145998, 020-888-999845 , 021 - 85421987, 19865754]

<script>
var str=" 1852145998 020-888-999845 测试 021  -  85421987, 19865754";
var reg=/(1\d+)|(0\d{2}(\s*-\s*\d+)+)/g;
alert(str.match(reg));
</script>


60、ajax

function ajax(url, fnSucc, fnFaild){
//1.创建对象
var oAjax = null;
if(window.XMLHttpRequest){
oAjax = new XMLHttpRequest();
}else{
oAjax = new ActiveXObject("Microsoft.XMLHTTP");
}

//2.连接服务器
oAjax.open('GET', url, true);   //open(方法, url, 是否异步)

//3.发送请求
oAjax.send();

//4.接收返回
oAjax.onreadystatechange = function(){  //OnReadyStateChange事件
if(oAjax.readyState == 4){  //4为完成
if(oAjax.status == 200){    //200为成功
fnSucc(oAjax.responseText)
}else{
if(fnFaild){
fnFaild();
}
}
}
};
}


61、js实现类似于add(1)(2)(3)调用方式的方法

var add = function(a){
return function(b){
return function(c){
return a+b+c;
};
};
};
add(1)(2)(3); //6


62、数组相等判断

javascript是不能直接比较两个数组是否相等的。例如:

var a = [1,2,3];
var b = [1,2,3];

alert(a == b); // false

结果是 false. 证明两个数组不能直接比较相等,数组是对象,对象是引用类型。

解决方法一:

先排序,再利用toString方法,比较。例如:

var a = [1,2,3];
var b = [1,2,3];
alert(a.sort().toString() == b.sort().toString());

结果为true

解决方法二:

直接toString() 比较也是可以的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: