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);
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都是只读属性,不能对它们赋值。
<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对象来获取我们需要的信息,本文从另外一个途径来解决这个问题,而且更加巧妙
1、获取选中select的value和text,html代码如下:
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>
则可通过以下script代码s来获取选中的value和text
$("#mySelect option:selected").text(); //获取选中记录的text值
2、运用new Option("文本","值")方法添加选项option
obj.add(new Option("4","4"));
3、删除所有选项option
obj.options.length = 0;
4、删除选中选项option
var index = obj.selectedIndex;
obj.options.remove(index);
5、修改选中选项option
var index = obj.selectedIndex;
obj.options[index] = new Option("three",3); //更改对应的值
obj.options[index].selected = true; //保持选中状态
6、删除select
obj.parentNode.removeChild(obj); //移除当前对象
7、select选择的响应事件
//添加所需要执行的操作代码
})
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
验证帐号是否合法
验证规则:字母、数字、下划线组成,字母开头,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");//调用
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() 比较也是可以的。