jsCoder

-----web前端攻城狮进阶中......

   :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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;
}
在网上又看到有人用以下四种算法来实现这个目的:
  1. 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;
    }
  2. 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;
    }
  3. 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() 比较也是可以的。

 

 

 

posted on 2012-12-21 15:09  jsCoder_洋洋  阅读(517)  评论(0编辑  收藏  举报