js 小贴士一星期合集

1.今天聊聊自定义事件

  事件大家都知道,但在很多的框架中都有自定义事件的实现,我写了个简单的,跟大家分享一下,

  

复制代码 代码如下:

  <script>

  var cusEvent = function(){

  var cache = {};

  return {

  addEvent:function(type,fn){

  cache[type]?cache[type].push(fn):(cache[type]=[fn]);

  },

  removeEvent:function(type,fn){

  if(cache[type]){

  if(fn){

  for(var i=0,ci;ci=cache[type][i];i++){

  ci===fn&&cache[type].splice(i,1);

  }

  }else{

  delete cache[type];

  }

  }

  },

  //e可以是个自定义的对象,也可以是字符串

  fire:function(e){

  if(typeof e =='string'){

  e = {type:e}

  };

  var t = cache[e.type];

  if(t){

  for(var i=0,ci;ci=t[i];i++){

  //e可以有自己的target,没有就用this代替

  ci.call(e.target||this,e)

  }

  }

  }

  }

  }()

  //使用

  cusEvent.addEvent('start',function(e){alert(e.type)})

  cusEvent.addEvent('start',function(e){alert(e.type+"1")})

  cusEvent.fire('start')

  cusEvent.removeEvent('start')

  </script>

  2. innerHTML大家都用过,肥肠好使,但在ie下有些时候却不行,比如select如果你想在select上用option就是不行的,因为select的innerHTML是只读的,当然除了这个还有像tr,table等等,我写了个小方法,来兼容innerHTML在ie下对这些元素的使用,希望给大家 点启示

  

复制代码 代码如下:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

  <html>

  <head>

  <title>Untitled</title>

  </head>

  <body>

  Hello World!

  <select id="aa"><option>sdfsdf</option><option>sdfsdf</option></select>

  <input onclick="html(document.getElementById('aa'),'<option>change1</option><option>change</option>')" type="button" value="use innerHTML"/>

  </body>

  </html>

  <script>

  var html = function(){

  var div = document.createElement('div');

  return document.all?function(pN,h){

  div.innerHTML = '<select>'+h+'</select>';

  for(var i=0,ci;ci=pN.firstChild;) pN.removeChild(ci)

  debugger;

  for(;ci=div.firstChild.firstChild;) pN.appendChild(ci);

  }:function(pN,h){

  pN.innerHTML = h;

  }

  }()

  </script>

  原理就是在ie中,我用个临时元素div来跳过innerHTML不能用的问题,可以再写点负载点,就是判断传进来的是tr,table的话用相应的元素套用,

  这个方法也可以解决select中option不好添加修改的问题

  3.

  在js中全局g-add变量是恶魔,是绝对建议不要使用的,但有的时候,可能要写个静态变量,随着函数的执行而累计比如

  

复制代码 代码如下:

  var a = 1;

  function fn(){

  alert(++a);

  }

  fn()

  fn()

  想随着函数的执行而改变

  好的写法可以这样

  

复制代码 代码如下:

  <script>

  var fn = function(){

  var a = 1;

  return function(){

  alert(++a);

  }

  }()

  fn();

  fn();

  </script>

  a作为闭包,可以被内部的function访问到,但在全局中却没有产生一个全局的a

  当然如果你想直接修改a也可以

  

复制代码 代码如下:

  <script>

  var fn = function(){

  var a = 1;

  return function(p){

  a = p===undefined?a+1:p;

  alert(a);

  }

  }()

  fn();

  fn(0);

  </script>

  4.

  传统的方式一般是用el.offsetParent,el.offsetLeft遍历去取得

  但其实又跟好的跟容易的方式那就是 getBoundingClientRect

  代码如下

  

复制代码 代码如下:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

  <html>

  <head>

  <title>Untitled</title>

  </head>

  <body>

  <div id="aa" style="position:absolute;width:200px;height:200px;left:200px;top:1000px;border:1px solid #ccc" onclick=offset(this) ></div>

  <div id="bb" style="position:absolute;width:200px;height:200px;border:1px solid red"></div>

  </body>

  </html>

  <script>

  var offset = function (o){

  var d = document,m = Math.max,bl = m(d.body.clientLeft,d.documentElement.clientLeft),st,sl,

  bt = m(d.body.clientTop,d.documentElement.clientTop),b,bb = document.getElementById('bb');

  return function(o){

  b = o.getBoundingClientRect();

  st = m(d.body.scrollTop,d.documentElement.scrollTop),sl = m(d.body.scrollLeft,d.documentElement.scrollLeft);

  bb.style.cssText +=";top:"+(b.top+st-bt)+'px;left:'+(b.left+sl-bl)+"px";

  }

  }()

  </script>

  当你点击最下边的灰色的div时,上边的红色的会跟灰色的完全重叠

  5.

  ie下的outerHTML大家都用过吧,肥肠好用,在你不仅仅只想返回某个元素下的html,还想返回这个元素的html

  但是这个属性只能用在ie下,别的浏览器没有这个属性,怎么办呢,

  js小贴士帮你解决这个问题

  

复制代码 代码如下:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

  <html>

  <head>

  <title>Untitled</title>

  </head>

  <body>

  <div >

  <div id="aa" ksjfkls="sdf" style="">

  <p>sdf</p>

  <p djkfjd="df"></p>

  </div>

  <div id="bb" sdfksf=333 >

  </div>

  </div>

  </body>

  </html>

  <script>

  var html = function(){

  var d = document,div = d.createElement('div');

  return function(id){

  var o = d.getElementById(id);

  if(o.outerHTML)

  return o.outerHTML;

  else{

  div.innerHTML = ''

  var h = '';

  div.appendChild(o.cloneNode(true));

  return div.innerHTML

  }

  }

  }()

  alert(html('aa'))

  alert(html('bb'))

  </script>