js集锦(上)

此部分介绍了。。。

由于鼠标从子元素移动到父元素上时,会触发子元素的移出事件,通过冒泡也会触发父元素移出事件。此时,有两种方法解决该问题。一种是在子元素移出事件中阻止冒泡,另一种是在父元素移出事件设置target判断条件。当target为父元素本身时才执行

透明度

透明度是一个比较特殊的样式,因为IE8-浏览器不支持opacity,只能通过滤镜的方式写成filter:alpha(opacity=透明值)但是,由于IE浏览器获取计算样式时,可以获得自定义样式,所以虽然opacity属性在IE8-浏览器无法生效,但是可以获得它的值如果透明度做运动的话,则需要对运动函数进行重新封装
[注意]由于透明度涉及小数计算,如0.07*100=> 7.000000000000001,所以需要用Math.round()去掉尾巴

history.go();

计算样式的兼容函数getCSS()

function getCSS(obj,style){
   if(window.getComputedStyle){
     return getComputedStyle(obj)[style];
   }
   return obj.currentStyle[style];
 }

使用style可以获取行内嵌的样式,却不能得到内联或者链接的样式。但是通过获取或者设置计算后的样式来解决这个问题。之所以可以实现是因为不管你在哪里设置的样式,最终都会驻留在浏览器的计算样式里。
DOM2 级样式,window 对象下提供了getComputedStyle()方法。接受两个参数,需要计算的样式元素,第二个伪类(:hover),如果没有没有伪类,就填null。
PS:IE 不支持这个DOM2 级的方法,但有个类似的属性可以使用currentStyle 属性。

var box = document.getElementByIdx_x_x_x('box');
var style = window.getComputedStyle ?window.getComputedStyle(box, null) : null || box.currentStyle;//兼容方法
alert(style .color); //颜色在不同的浏览器会有rgb()格式
alert(style .border); //不同浏览器不同的结果
alert(style .fontFamily); //计算显示复合的样式值
alert(box.style.fontFamily); //空

还有一个问题就是:通过计算获取元素的大小,无关你是否是行内、内联或者链接,它经过计算后得到的结果返回出来。如果本身设置大小,它会返回元素的大小,如果本身没有设置,非IE浏览器会返回默认的大小,IE 浏览器返回auto。
注意:border 属性是一个综合属性,所以他在Chrome 显示了,Firefox 为空,IE 为undefined。
所谓综合性属性,就是XHTML 课程里所的简写形式,所以,DOM 在获取CSS 的时候,最
好采用完整写法兼容性最好,比如:border-top-color 之类的。
多值
如果一个元素有多个值同时运动时,像下面这样直接调用move()函数是有问题的

move(test,'opacity',0.1,-0.05);
move(test,'left',-100,-1);

因为函数里面定时器的变量timer是一个公共变量,当一个运动停止时,会清除定时器。这时另一个运动即使没有完成,定时器已经停止了,就无法继续运动了所以,合适的做法是在参数对象obj下面设置一个自定义属性timers,timers为一个空对象,然后将定时器返回值储存在timers对象下的attr属性中,此时两个定时器不会相互干扰

  <style>
     #test{width: 100px;height: 100px;background-color: lightblue;text-align:center;position:absolute;top: 0;left:    -100px;opacity:1;} 
     #test-in{width: 30px;height: 60px;background-color: orange;margin-left: 100px;position:relative;top: 20px;}
 </style>
 <div id="test">
   <div id="test-in">分享到</div>
 </div> 
<script>

 test.onmouseover = function(){
    move(test,'opacity',0.1,-0.05);
    move(test,'left',0,10);
 }
 test.onmouseout = function(){
    move(test,'opacity',1,0.05);
    move(test,'left',-100,-10);
 }
 function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
 }   
 function move(obj,attr,target,speed){
    if(!obj.timers){
        obj.timers = {};
    }
    clearInterval(obj.timers[attr]);
    var cur;
    obj.timers[attr] = setInterval(function(){
        if(attr == 'opacity'){
            cur = Math.round(getCSS(obj,attr)*100);
            if((cur - target*100)*speed < 0){
                obj.style.opacity = (cur + speed*100)/100;
                obj.style.filter = 'alpha(opacity=' + (cur + speed*100) + ')';
            }else{
                obj.style.opacity = target;
                obj.filter = 'alpha(opacity=' + target + ')';
                clearInterval(obj.timers[attr]);
                obj.timers[attr] = 0;
            }
        }else{
            cur = parseInt(getCSS(obj,attr));
            if((cur - target)*speed < 0){
                obj.style[attr] = cur + speed + 'px';
            }else{
                obj.style[attr] = target + 'px';
                clearInterval(obj.timers[attr]);
                obj.timers[attr] = 0;
            }    
        }        
    },30);        
 }    
</script>

多物体
  如果在页面中有多个元素利用运动函数进行运动。由于定时器返回值在不同元素不同属性中都不会受影响。
所以,上面的运动函数可以直接使用

<style> 
  div{height: 100px;width: 100px;position: absolute;left: 0;} 
  #test1{background-color: pink;top: 40px;}  
  #test2{background-color: lightblue;top: 150px;} 
 </style> 
 <div id="test1">元素一</div> 
 <div id="test2">元素二</div> 
 <button id="btn">开始运动</button>  
 <button id="reset">还原</button>    
  <script> 
 reset.onclick = function(){history.go();}
 btn.onclick = function(){
    move(test1,'width',300,10);
    move(test1,'left',100,10);
    move(test2,'width',500,20);
    move(test2,'left',200,10);
 }

 function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
 }   

 function move(obj,attr,target,speed){
    if(!obj.timers){
        obj.timers = {};
    }
    clearInterval(obj.timers[attr]);
    var cur;
    obj.timers[attr] = setInterval(function(){
        if(attr == 'opacity'){
            cur = Math.round(getCSS(obj,attr)*100);
            if((cur - target*100)*speed < 0){
                obj.style.opacity = (cur + speed*100)/100;
                obj.style.filter = 'alpha(opacity=' + (cur + speed*100) + ')';
            }else{
                obj.style.opacity = target;
                obj.filter = 'alpha(opacity=' + target + ')';
                clearInterval(obj.timers[attr]);
                obj.timers[attr] = 0;
            }
        }else{
            cur = parseInt(getCSS(obj,attr));
            if((cur - target)*speed < 0){
                obj.style[attr] = cur + speed + 'px';
            }else{
                obj.style[attr] = target + 'px';
                clearInterval(obj.timers[attr]);
                obj.timers[attr] = 0;
            }    
        }        
    },30);        
 }    
</script>

回调
  物体的多个属性可能不是同时运动,可能是一个属性运动完成之后,另一个属性再运动。如果要完成这种需求,就需要用到回调函数在运动函数中,定时器停止时,再调用运动函数,就可以接续运动效果

<style>
 div{height: 100px;width: 100px;position: absolute;left: 0;}
 #test{background-color: pink;top: 40px;}
</style>
 <div id="test">元素</div>
 <button id="btn">开始运动</button>
 <button id="reset">还原</button> 
 <script>
 reset.onclick = function(){history.go();}
 btn.onclick = function(){
    move(test,'left',100,20,function(){
        move(test,'width',300,10)
    });
 }
 function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
 }   
 function move(obj,attr,target,speed,fn){
    if(!obj.timers){obj.timers = {};}
    clearInterval(obj.timers[attr]);
    var cur;
    obj.timers[attr] = setInterval(function(){
        if(attr == 'opacity'){
            cur = Math.round(getCSS(obj,attr)*100);
            if((cur - target*100)*speed < 0){
                obj.style.opacity = (cur + speed*100)/100;
                obj.style.filter = 'alpha(opacity=' + (cur + speed*100) + ')';
            }else{
                obj.style.opacity = target;
                obj.filter = 'alpha(opacity=' + target + ')';
                clearInterval(obj.timers[attr]);
                obj.timers[attr] = 0;
                fn && fn.call(obj);
            }
        }else{
            cur = parseInt(getCSS(obj,attr));
            if((cur - target)*speed < 0){
                obj.style[attr] = cur + speed + 'px';
            }else{
                obj.style[attr] = target + 'px';
                clearInterval(obj.timers[attr]);
                obj.timers[attr] = 0;
                fn && fn.call(obj);
            }    
        }        
    },30);        
 }    
</script>

函数完善
【速度参数】
上面封装的函数中,传递速度参数时,需要在速度参数前添加正负号作为方向标识。实际上,这步可以写在函数的程序内,而只传递正的速度参数即可

speed = parseInt(getCSS(obj,attr)) < target ? speed : -speed;

【拉回操作】
  还有一个可以升级的地方,就是拉回操作。通过判断元素是否到达目标点,如果超过目标点后,将元素拉回到目标点位置

cur = parseInt(getCSS(obj,attr));
  if((cur - target)*speed < 0){
     obj.style[attr] = cur + speed + 'px';
  }else{
     obj.style[attr] = target + 'px';
     clearInterval(obj.timers[attr]);
     obj.timers[attr] = 0;
     fn && fn.call(obj);
  } 

更合理的操作,应该是元素肯定不能超过目标点
所以应该把判断条件用来处理speed,当speed是一个合适的值时,再赋值给obj.style[attr],可更改如下

 cur = parseInt(getCSS(obj,attr));
//若速度设置值使得元素超过目标点时,将速度设置值更改为目标点值 - 当前值
 if((cur +speed - target)*speed > 0){
    speed = target - cur; 
 }
//将合适的speed值赋值给元素的样式
obj.style[attr] = cur + speed + 'px';

//当元素到达目标点后,停止定时器
if(speed == target - cur){
  clearInterval(obj.timers[attr]);
  obj.timers[attr] = 0;
  fn && fn.call(obj); 
}

【使用步长】
  其实,把元素的位移变化命名为速度并不合适,只是因为约定俗成的关系才如此起名,将其命名为步长step更为合适,定时器每运行一次,该元素前面一步
最终函数

function getCSS(obj,style){
   if(window.getComputedStyle){
       return getComputedStyle(obj)[style];
   }
   return obj.currentStyle[style];
} 
function move(obj,attr,target,step,fn){
   //如果没有建立定时器对象,则在obj下建立定时器对象
   if(!obj.timers){obj.timers = {};}
   //清除定时器
   clearInterval(obj.timers[attr]);
   //声明当前值变量cur
   var cur;
   //判断步长step的正负值
   step = parseInt(getCSS(obj,attr)) < target ? step : -step;
   //开启定时器
   obj.timers[attr] = setInterval(function(){
       //如果样式是透明度
       if(attr == 'opacity'){
           //对当前值的取值进行四舍五入,去除由于javascript小数计数中的bug存在的小尾巴
           cur = Math.round(getCSS(obj,attr)*100);
           if((cur - target*100)*step < 0){
               //设置透明度
               obj.style.opacity = (cur + step*100)/100;
               //IE兼容
               obj.style.filter = 'alpha(opacity=' + (cur + step*100) + ')';
           //透明度到达指定目标时
           }else{
               obj.style.opacity = target;
               obj.filter = 'alpha(opacity=' + target + ')';
               //清除定时器
               clearInterval(obj.timers[attr]);
               obj.timers[attr] = 0;
               //设置回调函数
               fn && fn.call(obj);
           }
       //当样式不是透明度时
       }else{
           //获取样式当前值并赋值给cur
           cur = parseFloat(getCSS(obj,attr));
           ////若步长设置值使得元素超过目标点时,将步长设置值更改为目标点值 - 当前值
           if((cur + step - target)*step > 0){
               step = target - cur;
           }
           //将合适的步长值赋值给元素的样式
           obj.style[attr] = cur + step + 'px';
           //当元素到达目标点后,停止定时器
           if(step == target - cur){
               clearInterval(obj.timers[attr]);
               obj.timers[attr] = 0;
               fn && fn.call(obj);    
           }
       }        
   },30);        
}

【实例】
  下面以一个实例来说明move函数的应用,点击document即可查看效果

<!DOCTYPE html>
 <html lang="en">
  <head>
   <meta charset="UTF-8">
   <title>Document</title>
   <style>
    div{
     width: 50px;
     height: 50px;
     position: absolute;
     top: 0;
     background-color:lightblue;
    }
    div:nth-child(odd){
      background-color:pink;
    }
   </style>
  </head>
 <body>
 <script src="move.js"></script>
 <script>
   var str = '';
   var len = 10;
   var timer;
   var num = 0;
   for(var i = 0; i < len; i++){
      str+= '<div style="left:'+60*i+'px;"></div>';
    }
   document.body.innerHTML = str;
   document.onclick = function(){
     var aDiv = document.getElementsByTagName('div');
     if(timer) return;
     timer = setInterval(function(){
       move(aDiv[num++],'top', 200,10,function(){
          var _this = this;
          setTimeout(function(){
            move(_this,'top', 0,10);
          },1000)
     });
     if(num == len){
       clearInterval(timer);
       num = 0;
       setTimeout(function(){
        timer = 0;
        },2000);
       }
    },100);
   }
</script> 
</body>
</html>

XML代表可扩展标记语言,是一种比较灵活的数据格式,很多应用程序存储数据都喜欢用到它,结构像HTML,也包含元素,标签以及属性,模型都一样。它的一大优势在于它是一种可扩展的格式,你并不会受制于某种预设的数据结构;并且它还符合DOM标准,使用AJAX调用获取到的数据就像解析HTML一样,通过相应的DOM方法和属性解析它:
但是XML的一个严重的缺陷在于它不能用于跨域名的Aiax调用,也就是说每一个Ajax调用的XML数据都必须和执行调用的脚本处于同一域名内,否则请求会失败。
HTML存储也相似,它与Ajax结合起来最简单。采用这种方式的数据格式的重要因素是速度,HTML代码段无需在客户端解析就能直接将其输出到DOM之中,所以我们不需要再额外的编写JavaScript代码解析HTML。
说说它的缺点,它存储的数据可能和HTML代码混合在一起,所以说可维护性降低。另外在编写处理代码时,开发者可能需要在服务器端做一些精细的控制手段。
以下是使用JavaScript进行数据存储的手段,循序渐进…

变量

JavaScript最为基础的数据存储方式,它接受字符串、数值、布尔等。最核心的内容是它的作用域问题。
于变量相关的性能问题:
变量在声明完之后,就会被缓存到JavaScript文件中,于是在作用域内就可以反复的使用它们了,获取变量的开销微乎其微,只要数据的使用次数大于1,就应该将其存入变量。
数组
数组跟普通数组、关联数组和多维数组,它们都是元素列表,这种形式是各种数据存储中非常灵活的一种。掌握了数组最基本的形式,也会对其他复杂形式的运用大有脾益。数组元素的访问合一处是常见的基本交互代码。鉴于数组这种数据存储类型的重要性,JavaScript为数组交互操作提供了大量的专属方法:
.join() 方法 可以指定某个字符作为数组内每个元素的连接符;slice() 方法可以输出数组中某个范围内的元素;shift()和unshift() 方法 分别用于在数组头部移除或新增元素;pop() 方法用于移除并返回数组中的最后一个元素;concat() 方法用于将多个数组拼接成一个数组,按参数的先后而定;sort()方法可以按照字母表顺序或自定义顺序来排列数组的元素.

对象

在数据变得更加复杂、更加难以管理的情况下,我就会选择将数组转换为对象。因为对象的存储方式更加易读。
对象对效率的影响
上面的代码只有一层,然而它是可以无限嵌套的。对象能更好的组织代码,提高模块化的程度。不过与此同时,还是需要考虑性能和可维护性的权衡问题,因为它需要寻找这三者中的一个。如果是运用面向对象编程技术,嵌套达到3层及以上,就会引发性能问题;但是在服务器端运用时就不是这样了,所以前端开发者要决定什么时候使用面向对象编程技术。

JSON

JSON是一种易于同jacascript 集成的数据格式,它通常是在用JavaScript调用外部服务器时使用的。JSON数据存放于独立的文件中,而且通常位于另一台完全不同的服务器上。它现在是最常见的一种调用API服务时所使用的数据格式,人们之所以选中它,是因为此格式非常易于阅读。起初,JSON格式是作为一种XML格式的替代方案而出现的,但很快它就在数据交换领域占据了主流的地位。它是一种轻量级的数据格式,易于通过远程Ajax调用进行跨域名访问。尽管JavaScript对JSON格式的解析提供了原生的支持,但它还是一种独立于平台的格式,客户端与服务器端在数据交换时都可以使用。
由于JSON格式具备跨域名访问的能力,所以为了防止一切恶意行为,我们务必只使用从可信的数据源中获取JSON
JSON最常见的用途就是配合API调用,在于API为基础的网络程序开发环境中,使用何种后端语言进行开发,数据格式都无需改变.
事件就是文档或浏览器窗口中发生的一些特定的交互瞬间,而事件流(又叫事件传播)描述的是从页面中接收事件的顺序。
IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
[注意]所有现代浏览器都支持事件冒泡,但在具体实现在还是有一些差别。IE9、Firefox、Chrome、Safari将事件一直冒泡到window对象

事件捕获

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前就捕获它
[注意]IE9、Firefox、Chrome、Safari等现代浏览器都支持事件捕获,但是从window对象开始捕获
addEventListener()方法中的第三个参数设置为true时,即为事件捕获阶段

事件流

事件流又称为事件传播,DOM2级事件规定的事件流包括三个阶段:事件捕获阶段(capture phase)、处于目标阶段(target phase)和事件冒泡阶段(bubbling phase)
首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件,最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应
事件处理程序又叫事件侦听器,实际上就是事件的绑定函数。事件发生时会执行函数中相应代码。事件处理程序有HTML事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序和IE事件处理程序四类
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象,但支持方式不同。
事件流
eventPhase
  eventPhase属性返回一个整数值,表示事件目前所处的事件流阶段
  0表示事件没有发生,1表示捕获阶段,2表示目标阶段,3表示冒泡阶段
  [注意]IE8-浏览器不支持

如何判断是手机还是电脑访问网站:

现在由于手机功能的强大,使用手机上网的用户越来越多,那么就需要判断用户是用何种客户端登陆的网站,如果使用的是电脑则使用电脑版本的网页,如果使用的手机则使用手机版本的网页,下面是一段能够判断是手机还是电脑的代码:

function check() { 
 var userAgentInfo=navigator.userAgent; 
 var Agents =new Array("Android","iPhone","SymbianOS","Windows Phone","iPad","iPod"); 
 var flag=true; 
 for(var v=0;v<Agents.length;v++) { 
    if(userAgentInfo.indexOf(Agents[v])>0) { 
      flag=false; 
      break; 
    } 
  } 
  return flag; 
 }

在以上代码中,如果如果flag返回值为true则说明是电脑客户端,如果是false,则说明使用的是移动客户端,代码比较简单这里就不多介绍了,直接套用就可以了.
javascript实现的验证码代码实例
代码:

<!DOCTYPE html>
 <html>
  <head>
   <meta charset="gbk">
   <meta name="author" content="http://www.108js.com/" />
   <title>javascript实现的验证码代码实例</title>
  </head>
  <style type="text/css">
   .code 
   {
    background:url(code_bg.jpg);
    font-family:Arial;
    font-style:italic;
    color:blue;
    font-size:30px;
    border:0;
    padding:2px 3px;
    letter-spacing:3px;
    font-weight:bolder;
    float:left;
    cursor:pointer;
    width:150px;
    height:60px;
    line-height:60px;
    text-align:center;
    vertical-align:middle;
   }
  a 
  {
   text-decoration:none;
   font-size:12px;
   color:#288bc4;
  }
  a:hover 
  {
   text-decoration:underline;
 }
 </style>
 <script type="text/javascript">
 var code;
 function createCode() 
 {
   code = "";
   var codeLength = 6; //验证码的长度
   var checkCode = document.getElementById("checkCode");
   var codeChars = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
            's','t','u','v','w','x','y','z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 
            'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
             //所有候选组成验证码的字符,当然也可以用中文的
  for(var i = 0; i < codeLength; i++) 
  {
    var charNum = Math.floor(Math.random() * 52);
    code += codeChars[charNum];
  }
  if(checkCode) 
  {
    checkCode.className = "code";
    checkCode.innerHTML = code;
  }
 }
 function validateCode() 
 {
   var inputCode=document.getElementById("inputCode").value;
   if(inputCode.length <= 0) 
   { 
     alert("请输入验证码!");
   }
   else if(inputCode.toUpperCase() != code.toUpperCase()) 
   { 
     alert("验证码输入有误!");
     createCode();
   }
   else 
   {
    alert("验证码正确!");
  }        
 }    
 </script>
 <body onload="createCode()">
  <form id="form1" runat="server" onsubmit="validateCode()">
   <div>
    <table border="0" cellspacing="5" cellpadding="5" >
     <tr>
      <td></td>
      <td><div class="code" id="checkCode" onclick="createCode()" ></div></td>
      <td><a href="#" onclick="createCode()">看不清换一张</a></td>
     </tr>
     <tr>
       <td>验证码:</td>
       <td><input style="float:left;" type="text" id="inputCode" /></td>
       <td>请输入验证码</td>
     </tr>
     <tr>
       <td></td>
       <td><input id="Button1" onclick="validateCode();" type="button" value="确定" /></td>
       <td></td>
     </tr>
    </table>
   </div>
  </form>
 </body>
</html>

js拖拽DIV到页面任何位置
js拖拽到页面任何位置

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
   #main{width:100px;height:100px;background:#ffccff;position:absolute;}
 </style>
 <script>
  /*1:拖拽的时候有文字选中会有问题;
          原因:这是浏览器的默认拖拽文字的行为
          解决方案:标准浏览器下:阻止默认行为,在onmousedown结尾加上return false即可
                    ie8及其以下版本:设置全局捕获,方法如下设置全局捕获setCapture最后释放releaseCapture*/
       window.onload = function(){
           var oDiv = document.getElementById("main");
           var odiv = document.getElementById("div");
           oDiv.onmousedown = function(ev){

                   var ev = ev || event;
                   var disX = ev.clientX - this.offsetLeft;
                   var disY = ev.clientY - this.offsetTop;

                   if(oDiv.setCapture){
                     oDiv.setCapture();
                   }
                document.onmousemove = function(ev){
                    //这里为什么使用document,是因为快速拖拽的话会鼠标丢失,
                    var ev = ev || event;
                    oDiv.style.left = ev.clientX - disX+"px";
                    oDiv.style.top = ev.clientY - disY+"px";
                }

                document.onmouseup = function(ev){
                    document.onmousemove = document.onmouseup = null;
                    //为何不用oDiv.onmouseup是因为被挡住之后会无视掉遮挡的元素
                    if(oDiv.releaseCapture){

                      oDiv.releaseCapture();
                    }
                }
                return false;
           }
       }
   </script>
  </head>
  <body>
    2015/11/17wf r3qr
   <div id="main"></div>
  </body>
</html>

setCapture函数的作用就是将后续的mouse事件都发送给这个对象,releaseCapture就是将鼠标事件还回去,由 document、window、object之类的自行来处理。这样就保证了在拖动的过程中,不会由于经过了其它的元素而受到干扰
另外,还有一个很重 要的事情是,在Win32上,mouse move的事件不是一个连续的,也就是说,并不是我们每次移动1px的鼠标指针,就会发生一个mousemove,windows会周期性检查mouse 的位置变化来产生mousemove的事件。
所以,如果是一个很小的页面对象,比如一个直径5px的圆点,如果没有setCapture和 releaseCapture,那么在鼠标按住之后,快速的移动鼠标,就有可能鼠标移动走了,但是小圆点还在原地,就是因为下一次的mousemove事 件已经不再发给这个圆点对象了。
web开发和windows开发最大的区别就是windows开发是有状态的,而web开发是无状态的,在windows中,一切操作都可以由程序来控制 ,除非强制执行ctrl+alt+del;但web操作就不一样了,即使执行很重要的操作,用户一点击浏览器关闭按钮,就将前面操作成果化为乌有.尽管可以在onunload事件中加些代码,让用户可以选择是否退出,但不能从根本上解决问题!
前几天,从网上看到setCapture方法,了解了一下,大体是这样的意思,当在IE文档某个区域中使用了这个方法,并且写了onclick或者 onmouse*等有关的鼠标事件方法,那么它就会监视相应的鼠标操作,即使你的鼠标移出了IE,它也一样能捕获到.如果你在某div中的 onclick事件中写了一个alert命令,这时,你点击的关闭按钮,它也一样会弹出alert窗口.releaseCapture与 setCapture方法相反,释放鼠标监控.
利用这个特性,我们可以延缓IE的关闭窗口等破坏性操作,将一些重要的操作能够在破坏性操作执行之前得到处理.
有一点遗憾:setCapture和releaseCapture 不支持键盘事件.只对onmousedown, onmouseup, onmousemove, onclick, ondblclick, onmouseover, onmouseout这样的鼠标事件起作用.
下面是一个小例子,若我们要对divMain这个div元素里面的内容进行保护:
1.对divMain执行setCapture方法:
document.getElementById(“divMain”).setCapture();
2.加入一按钮btnChange,可以进行setCapture和releaseCapture切换,定义一全局变量;
var isFreeze = true;
3.在btnChange的onclick事件中,加入下列代码:
代码如下:

function change_capture(obj) { 
isFreeze = !isFreeze; 
if(isFreeze) { 
obj.value = "releaseCapture"; 
document.getElementById("divMain").setCapture(); 
} else { 
obj.value = "setCapture"; 
alert('保存!'); //可以执行重要操作 
document.getElementById("divMain").releaseCapture(); 
} 
} 

divMain的onclick事件中,加入下列代码: 
复制代码 代码如下:

function click_func() 
{ 
if(event.srcElement.id == "divMain") 
{ 
alert("处理中..."); //常规操作 
document.getElementById("divMain").setCapture(); 
} 
else 
{ 
if(isFreeze && event.srcElement.id != "btnChange") 
{ 
alert('未执行releaseCapture,不能点击'); 
document.getElementById("divMain").setCapture(); 
} 
} 
} 

对ALT+F4进行处理,在body的onkeydown事件中加入下列代码:
代码如下:

function keydown_func() 
{ 
if (event.keyCode==115 && event.altKey) //ALT+F4 
{ 
if(isFreeze) 
{ 
alert('保存!'); //可以执行重要操作 
} 
//window.showModelessDialog("about:blank","","dialogWidth:1px;dialogheight:1px"); 
//return false; 
} 
document.getElementById("divMain").setCapture(); 
} 

完整代码如下:

<html> 
<head> 
<title> 
setCapture和releaseCapture的小应用 
</title> 
<script> 
< !-- 
var isFreeze = true; 
function click_func() { 
if (event.srcElement.id == "divMain") { 
alert("处理中..."); //常规操作 
document.getElementById("divMain").setCapture(); 
} else { 
if (isFreeze && event.srcElement.id != "btnChange") { 
alert('未执行releaseCapture,不能点击'); 
document.getElementById("divMain").setCapture(); 
} 
} 
} 
function keydown_func() { 
if (event.keyCode == 115 && event.altKey) //ALT+F4 
{ 
if (isFreeze) { 
alert('保存!'); //可以执行重要操作 
} 
//window.showModelessDialog("about:blank","","dialogWidth:1px;dialogheight:1px"); 
//return false; 
} 
document.getElementById("divMain").setCapture(); 
} 
function change_capture(obj) { 
isFreeze = !isFreeze; 
if (isFreeze) { 
obj.value = "releaseCapture"; 
document.getElementById("divMain").setCapture(); 
} else { 
obj.value = "setCapture"; 
alert('保存!'); //可以执行重要操作 
document.getElementById("divMain").releaseCapture(); 
} 
} 
//--> 
</script> 
</head> 
<body onkeydown="keydown_func();"> 
<div id="divMain" onclick="click_func();"> 
点一下IE的菜单或者按钮看看:) 又或者IE窗口外的地方 
<input type="button" value="releaseCapture" onclick="change_capture(this);" 
id="btnChange"> 
<script language="javascript"> 
document.getElementById("divMain").setCapture(); 
</script> 
</div> 
</body> 
</html> 

关于javascript中call和apply函数的应用
我们经常在javascipt中的面向对象应用中遇到call和apply函数;有时会被搞糊涂。其实它们可以改变函数或对象中的this保留字的值;this保留字的默认值就是这个类本身。举例说明:
代码如下:

<!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> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<script language="javascript"> 
test = { 
value: 'default',exec: function() { 
alert(this.value); 
} 
} 
function hhh(obj) { 
test.exec();test.exec.apply(obj); 
} 
</script> 
</head> 
<body> 
<input type="button" onclick="hhh(this);" value="test" /> 
</body> 
</html> 

运行以上的页面就很快明白了.
call和apply函数可以处理匿名函数
关于类的初始化应用如下:
代码如下:

Person = function() { 
this.Init.apply(this, arguments); 
}; 
Person.prototype = { 
first: null, 
last: null, 
Init: function(first, last) { 
this.first = first; 
this.last = last; 
}, 
fullName: function() { 
return this.first + ' ' + this.last; 
}, 
fullNameReversed: function() { 
return this.last + ', ' + this.first; 
} 
}; 
var s = new Person2('creese', 'yang'); 
alert(s.fullName()); 
alert(s.fullNameReversed()); 

call和apply函数可以赋值函数内容(带匿名参数;但不触发)
关于函数绑定事件应用如下:
代码如下:

Function.prototype.BindForEvent = function() { 
var __m = this, object = arguments[0], args = new Array(); 
for(var i = 1; i < arguments.length; i++){ 
args.push(arguments[i]); 
} 
return function(event) { 
return __m.apply(object, [( event || window.event)].concat(args)); 
} 
} 

call和apply函数关于函数绑定参数应用如下:
代码如下:

Function.prototype.Bind = function() { 
var __m = this, object = arguments[0], args = new Array(); 
for(var i = 1; i < arguments.length; i++){ 
args.push(arguments[i]); 
} 
return function() { 
return __m.apply(object, args); 
} 
} 

call和apply函数功能是一样的;就是参数格式不同;fun.call(obj, arguments);apply的arguments是数组形式;call则是单数形式。
screen对象通常包含下列属性(许多浏览器都加入了自己的属性):
1.availHeight : 窗口可以使用的屏幕的高度(以像素计)其中包括操作系统元素(如window工具栏)需要的空间。
2.availWidth : 窗口可以使用的屏幕的宽度(以像素计)。
3.colorDepth : 用户表示的颜色的位数,大多数系统采用32位的。
4.height :屏幕的高度,以像素计算。
5.width : 屏幕的宽度,以像素计算。
确定新窗口的大小时,availHeight和availWidth属性比较有用。比如可以用下面的代码填充用户的屏幕:
window.moveTo(0,0);
window.resizeTo(screen.availWidth,screen.availHeight);
另外,这些数据与站点的流量工具一起使用,可以判断用户的图形接受能力。
div应该是division的缩写吧!!!!

任选一题(5分)
a) ul、ol、dl的区别?
b) div、section、article的区别?

a: ul是无序列表,ol是有序列表,dl是定义列表有层次关系。
b: div无语义,只是用作布局。
section是有一定语义的div,表示一个专题,一般有标题,但是不可以乱用。只有内容明确需要出现在大纲中时才会使用。
artical是更特殊的section,他是一个独立完整的内容块。比如用在文章,评论等。

html5对input新增了哪些高级属性?(5分)

number ,date,color,range,email,search,tel,url

每题都需回答(15分)
a) 如何用CSS控制文本单行溢出省略?并且大致说出多行省略的思路。
b) 谈谈响应式布局?
c) CSS3有哪些高级选择器?

a:css实现单行溢出省略是利用text-overflow:ellipsis,white-space:nowrap和overflow:hidden属性实现的。
(新版主流浏览器测试通过)
b:响应式布局是为了解决现在市场上的浏览器尺寸不一的现状,让用户无论是使用移动端还是电脑端访问都有很好体验。html5也因此加入了媒体查询等一系列针对响应式布局的新元素。
c:css3有属性选择器{E[att$=’val’],E[att~=’val’],E[att^=’val’]}
伪类选择器{E:not(),E:last-child,E:only-child,E:nth-child(n),E:nth-last-child(),E:empty}
伪对象选择器{E::selection}
关系选择器{E~F}

请逐一解释他们:

Node.js、React Native、Angular.js、Grunt/Gulp、Webpack、Git、JSONP(10分)
Node.js:
Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动,非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行的数据密集型的实时应用。
React Native:
React Native 结合了Web应用和Native应用的优势,可以使用JavaScript来开发iOS和Android原生应用。在JavaScript中用 React抽象操作系统原生的UI组件,代替DOM元素来渲染等。
Angular.js: (它有坑吗????)
AngularJS诞生于2009年,由Misko Hevery等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。AngularJS有着诸多特性,最为核心的是:MVVM、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。
Grunt/Gulp:
自动构建系统,开发者可以使用它在网站开发过程中自动执行常见任务。
Webpack:
是一个模块打包工具,你可以使用WebPack管理你的模块依赖,并编绎输出模块们所需的静态文件。
Git:
Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。·
JSONP:
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端, 然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

分别说出下述输出结果(15分)
!function(){
  this.length = 10;
  var fn = function(){
    console.log(this.length);//输出多少??输出2,this指向数组arr
    console.log(this[1]);//输出多少?输出"hello layui"
  }, arr = [fn, 'hello layui'];
  fn.length = 100;
  arr[0]();
}();
封装一个cont方法,能实现如此调用:
cout(a)(b)(c)(d)(e)… 并且返回的值为参数连剩的结果,即a*b*c*d*e*…。如cout(1)(3)(7) 得到21 (15分)
init=0;  //设置一个全局变量
var muti=function(m)
{
   init=init*m;
   return muti
 }

 muti.toString=function()  //这是关键的一步
 {
     return init;
  }

  function count(m)  //最终我们要调用的函数
  {
     init=m ;// 初始化,否则init是0,那么永远乘 都是 0,也是很关键的一步
     return muti;//最终返回的是 元对象(不是实例化过后的对象哦)
  }
  alert(count(3)(4)(5))
任选一题(15分)
a) 谈谈你对模块化开发的理解?
b) 你认为什么是更科学效率的组件化?
c) ES6有哪些你觉得不错的特性?
任选一题(20分)
a) 实现一个手势滑动轮播图,可以直接用代码表述,也可以只说说思路。
b) 大致描述如何实现一个基于Express的MVC框架?
scrollWidth,clientWidth,offsetWidth的区别 http://www.108js.com/article/article2/20130.html?id=2380

(scrollHeight、offsetHeight、clientHeight 同样可按本文去理解。)
这是一个很复杂的问题,让我们想像一下:
document.documentElement.scrollWidth
document.documentElement.offsetWidth
document.documentElement.clientWidth
document.body.scrollWidth
document.body.offsetWidth
document.body.clientWidth
有 6 个属性要测,这 6 个属性要放在 4 种情况中:
没有指定 DOCTYPE,网页内容没有超过窗口宽度;
没有指定 DOCTYPE,网页内容超过窗口宽度;
指定 DOCTYPE,网页内容没有超过窗口宽度;
指定 DOCTYPE,网页内容超过窗口宽度;
然后这 4 种情况要放到几个主流浏览器中,假设只有 3 种浏览器:
IE
Firefox
Chrome
算一下,6 * 4 * 3,有 72 种情况要测试,天啊。并且不要指望 Firefox 和 Chrome 结果是一样的,不要指望 Firefox 不会出现让您费解的结果,所以这真是一件恼火的事。
从应用入手简化分析
72 种测试情况确实很恼火,但我们回过头来一想,我们到底想要什么?
我认为我们想要两个东西:
一是 scrollWidth(scrollHeight),虽然它用处不大,但应该比 offsetWidth(offsetHeight)有用得多。它表示的是文档区的宽度(高度),比如一个网页,特别是门户网站,拖很长,就要把没有显示出来的内容都计算进去。
二是视口 viewport,就是clientWidth,就是窗口中可显示内容的那块区域,就是我们常常看到页面上飞行广告,飞来飞去,碰到边边要反弹的那一块。
测试结果
结果很复杂,就不说了(请下载测试代码),这里只说实际中怎么使用:
要使用 scrollWidth,取 document.documentElement.scrollWidth 与 document.body.scrollWidth 的最大值;
要使用 clientWidth,如果 document.documentElement.clientWidth > 0,则使用 document.documentElement.clientWidth,否则使用 document.body.clientWidth。
表达式为:
var scrollWidth = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
var clientWidth = document.documentElement.clientWidth || document.body.clientWidth
Javascript引擎是单线程运行的,浏览器只有一个线程在运行JavaScript程序。因为单线程的设计,所以免去了复杂的多线程同步问题。
当设置一个定时的时候,浏览器会在设定的时间后将你指定的回调函数插入任务序列,而非立即执行。如果设定定时时间为0,表示立即插入任务序列,而不是立即执行,仍然要等队列中任务执行完毕,轮到你,你才执行。
彻底弄清offset
http://www.108js.com/article/article2/20064.html?id=719
http://www.108js.com/article/article2/20063.html?id=718
JS对用户隐藏源代码

 <html>
 <head>
  <title>例20.4 对用户隐藏源代码</title>
  <script>
<!--
   function clear(){
    Source=document.body.firstChild.data;
    //这段代码里我们看到一个新鲜的属性--data
    //它引用一个COMMENT_NODE类型的DOM对象的文本内容
    //这里用到了一个技巧,实际上我们把body的内容整个构建为一个COMMENT_NODE
    //然后用data取出内容再回写入body的innerHTML,其结果就是,在页面上
    //用鼠标右键查看源代码的时候查看不到body中的任何源代码
    document.open();
    document.close();
    document.title="";
    document.body.innerHTML=Source;
   }
-->
</script>
</head>
<body onload=clear()>
<!--
  <table border="1" cellpadding="0" cellspacing="0" width="770" height="200">
   <tr>
    <td>看看能不能看到源代码</td>
   </tr>
  </table>
-->
</body>
</html>

JS浏览器检测代码

<html>
<title>浏览器检测</title>
 <script type="text/javascript">

 function isIE(){   
  return navigator.appName.indexOf("Microsoft Internet Explorer")!=-1 && document.all;   
 }   
 function isIE6() {   
   return navigator.userAgent.split(";")[1].toLowerCase().indexOf("msie 6.0")=="-1"?false:true;   
 }   
 function isIE7(){   
   return navigator.userAgent.split(";")[1].toLowerCase().indexOf("msie 7.0")=="-1"?false:true;   
 }   

 function isIE8(){   
   return navigator.userAgent.split(";")[1].toLowerCase().indexOf("msie 8.0")=="-1"?false:true;   
 }   
 function isNN(){   
   return navigator.userAgent.indexOf("Netscape")!=-1;   
 }   
 function isOpera(){   
   return navigator.appName.indexOf("Opera")!=-1;   
 }   
  function isFF(){   
   return navigator.userAgent.indexOf("Firefox")!=-1;   
  }   
  function isChrome(){   
    return navigator.userAgent.indexOf("Chrome") > -1;     
   } 

  function showResult(){        
    if(isChrome()){
     alert("这是谷歌浏览器");    
    }

    if(isIE()){
     alert("这是IE");
    }

    if(isIE6()){
     alert("这是isIE6");
    }

    if(isIE7()){
     alert("这是isIE7");
    }

    if(isIE8()){
     alert("这是IisIE8");
     }

    if(isNN()){
     alert("这是isNN");
    }

    if(isOpera()){
     alert("这是isOpera");
     }

    if(isFF()){
     alert("这是Firefox");
    }
  }

</script>
</head>
<body>
  <center><input type="button" onclick="showResult()" name="check" value="检测"</center>
</body></html>

javaScript防盗链代码

<html>
 <head>
  <title>防止盗链</title>
  <script language="javascript" type="text/javascript">
   <!--
    //当前文档的URL
    var currentURL = document.URL;
    //上一个文档的URL
    var frontURL = document.referrer;
    //如果上一个文档的URL为空,则是直接打开当前文档,则不存在盗链的问题。否则有可能是盗链。
    if (frontURL!="")
    {
     //通过分割,将当前文档的URL各部分存放在currentURLs数组中。
     var currentURLs = currentURL.split("/");
     //通过分割,将上一个文档的URL各部分存放在frontURLs数组中。
     var frontURLs = frontURL.split("/");
     //两个数组的第3个元素都为URL的域名部分
     //比较两个数组的第3个元素,如果域名相同,则不是盗链,否则就是盗链
     if (currentURLs[2]==frontURLs[2])
     {
      document.write("不是盗链,可以显示正常文档");
     }
     else
     {
      document.write("您不是从本站中访问到该网址,请通过本部访问");
      //可以使用以下代码跳转到网站的首页
      //history.location = "http://" + currentURLs[2];
     }
    }
    else
    {
     document.write("您是直接打开该文档的,不存在盗链问题");
    }
   -->
  </script>
 </head>
 <body>
 </body>
</html>
很惭愧<br><br>只做了一点微小的工作<br>谢谢大家