3-1a.第一部分

1.null和undefined的区别?

undefined表示变量声明但未初始化值,null用来保存对象,表示一个空对象。
任何时候都不建议设置一个变量为undefined,但是如果保存没有真正对象的变量,应该设置成null。
alert(null==undefined);  // true

2.Js原型,原型链是什么,特点?

每个对象都有一个内部属性 prototype,但是对象实例不具有该属性,我们通常称之为原型。原型的值可以是一个对象,
也可以是null。如果它的值是一个对象,则这个对象也一定有自己的原型。这样就形成了一条线性的链,我们称之为原型
链。但是对象实例不具有prototype属性,只有一个内部的不可访问的__proto__属性。__proto__是对象中一个指向
相关原型的神秘链接。    

每个对象都会在其内部有一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在
这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下
去,也就是我们平时所说的原型链的概念。

关系:instance.constructor.prototype = instance.__proto__


特点:
JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型
时,与之相关的对象也会继承这一改变。通过原型可以实现对象的属性继承!!!

对象,函数对象,原型对象:
1. 所有的对象都有__proto__属性,函数被用作构造函数来创建实例时,该属性指向该对象的原型.
2. 所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的实例对象的_proto_属性.
3. 所有的原型对象都有constructor属性,该属性指向该原型的实例的构造函数.
4. 函数对象和原型对象通过prototype和constructor属性进行相互关联.

3.ajax

ajax缓存是根据url地址来缓存的,换句话说,同样的一个url地址只缓存一次。实际应用中到底
要不要和多久一次清一下缓存,是由架构师说了算。

ajax使用:
  a.请求并显示静态文本文件。
  b.获取动态数据文件:请求js文件(放json数据的文件)
    eval使用:1、计算字符串里面的值。2.eval(它里面可以放任何一段js代码,并运行)
  c.局部刷新:请求并显示部分网页文件。
  for(i=0;i<aBtn.length;i++){
    aBtn[i].index = i;
    aBtn[i].onclick = function(){
      ajax("page"+(aBtn[i].index+1)+".txt",function(str){
        var aData = eval(str);
        oUl.innerHTML = '';
        for(i=0;i<aData.length;i++){
          var oLi = document.createElement('li');
          oLi.innerHTML = '<strong>'+aData[i].user+'</strong><i>'+aData[i].pass+'</i>';
          oUl.appendChild(oLi);
        }
      });
    }
  }
  ajax原理:
    http请求方法:
      get:更适合获取数据,如浏览帖子;
      post:更适合上传数据,如用户注册
      get,post区别:
      get把数据放在url里面,安全性低(在浏览器里鼠标悬浮历史浏览链接,浏览器下方会出现数据信息),容量小;优点便于分享,会缓存。
      post把数据放在http content里面,安全性一般,容量几乎无限

  ajax请求编写:
    1.创建ajax对象;2.连接服务器;3.发送请求;4.接收返回

js有个特性:alert(a)用一个不存在的变量会报错;alert(window.a); 用一个不存在的属性 只会undefined

    2.请求状态监控,onreadystatechange事件
      -readyState属性:请求状态
       0:未初始化,还未调用open方法;
       1:调用send方法,正在发送请求;
       2:send方法完成,已收到全部响应内容;
       3:正在解析响应内容;
       4:响应内容解析完毕,等待客户端调用
      -status属性:请求结果
      -responseText
  function ajax(url,fnSucc,fnFail){
    var oAjax = null;
    if(window.XMLHttpRequest){
      oAjax = new XMLHttpRequest();
    }else{
      oAjax = new ActiveXObject('Microsoft.XMLHTTP');//iE6及以下依赖
      插件
    }
    oAjax.open("GET",url,true);//工作在异步下
    oAjax.send();
    oAjax.onreadystatechange = function(){
        if(oAjax.readyState==4){
          if(oAjax.status==200){
            fnSucc(oAjax.responseText);
          }else{
            if(fnFail){
              fnFail();
            }
          }
        }
    }
  }
主要:XML现在已淘汰,相对于json太臃肿了.还有所有字符集要求一样。

4.js跨域问题

同源策略:同源指的是主机名、协议和端口号的都相同(哪怕不同域名指向同一个ip都不行)

解决方案:
*a.script标签:

script标签引用的文件要求返回的值,务必是var json={"Name":"zhangsan"},或
json({"Name":"zhangsan"})。

就是以jsonp形式,建立个json函数,然后传参过去调回json格式数据。
jsonp:json + padding(内填充的盒子):box(包裹着json格式的数据),那么在父域下面就可以写个同名函数,
以子域的传来的数据作为参数。
(一)
<script>
function 包裹着json格式的数据的同名函数(jsondata){
  //处理json数据
}
</script>
<script src="子域链接?子域那边规定的格式参数名=上面定义的包裹着json格式的数据的同名函数"></script>

主要:获取数据的地址后面还有一个callback参数,按惯例是用这个参数名,但是得按照提供数据的那一方
的规定格式用参数名。

这样jsonp的原理就很清楚了,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中
指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。
<script type="text/javascript">
var result = null;
function callback(data) {
    result = data;
}
window.onload = function () {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "http://example.com/data.php?callback=callback";

    var head = document.getElementsByTagName("head")[0];
    head.insertBefore(script, head.firstChild);

};
</script>
如果你的页面使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了。
(二)
<script>
$.getJSON('http://example.com/data.php?callback=?',function(jsondata){
 //处理json数据
});
</script>

原理是一样的,只不过我们不需要手动的插入script标签以及定义回掉函数。jquery会自动生成一个全局函数来
替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON
方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用
jsonp的回调函数。
(三)
 $.ajax({ 
         dataType: 'jsonp', 
         //jsonp的值自定义 
         jsonp: 'jsoncallback', 
         //返回Json类型 
         contentType: "application/json;utf-8", 
 });    

*b.location.hash + iframe 
  原理是利用location.hash来进行传值。
 假设域名a.com下的文件cs1.html要和cnblogs.com域名下的cs2.html传递信息。
  1) cs1.html首先创建自动创建一个隐藏的iframe,iframe的src指向cnblogs.com域名下的cs2.html页面
  2) cs2.html响应请求后再将通过修改cs1.html的hash值来传递数据
  3) 同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没有变化,一旦有变化则获取
  获取hash值
  注:由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于
  a.com域名下的一个代理iframe

  代码如下:
  先是a.com下的文件cs1.html文件:
  function startRequest(){
    var ifr = document.createElement('iframe');
    ifr.style.display = 'none';
    ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';
    document.body.appendChild(ifr);
  }

  function checkHash() {
    try {
          var data = location.hash ? location.hash.substring(1) : '';
          if (console.log) {
          console.log('Now the data is '+data);
          }
        } catch(e) {};
  }
  setInterval(checkHash, 2000);

cnblogs.com域名下的cs2.html:
//模拟一个简单的参数处理操作
switch(location.hash){
    case '#paramdo':
        callBack();
        break;
    case '#paramset':
        //do something……
        break;
}

function callBack(){
    try {
      parent.location.hash = 'somedata';
    } catch (e) {
      // ie、chrome的安全机制无法修改parent.location.hash,
      // 所以要利用一个中间的cnblogs域下的代理iframe
      var ifrproxy = document.createElement('iframe');
      ifrproxy.style.display = 'none';
      ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';    // 注意该文件在"a.com"域下
    document.body.appendChild(ifrproxy);
    }
}
那么a.com下的域名cs3.html
//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);

*c.window.name + iframe 
  window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都
  是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口
  载入过的所有页面中的,并不会因新页面的载入而进行重置。
  在www.a.com/a.html中:
  <script>
    window.name="jwjwj";
    setTimeout(function(){
    //3秒后载入新的页面到当前窗口
    window.location="http://www.script.a.com/b.html";
    },3000)
  </script>
  在www.script.a.com/b.html中:
  <script>
  alert(window.name);
  </script>


d.document.domain + iframe 

  只有在主域相同的时候才能使用该方法。document.domain的设置是有限制的,我们只能把document.domain
  设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 
  可以设成a.b.example.com、b.example.com 、example.com中的任意一个。

  在www.a.com/a.html中:
  <script>
  document.domain='a.com';
  function onLoad(){
    var oIframe=document.getElementById('frame');
    //获取iframe里面的window对象
    var win= oIframe.contentWindow;
    //获取window里面的document对象
    var doc=win.document;
    //获取window里面的name属性
    var name=win.name;
  }
  </script>
  <iframe src="http://www.script.a.com/b.html" id="frame" onload="onLoad()"></iframe>
  在www.script.a.com/b.html中:
  document.domain = 'a.com';  

  这样我们就可以通过js访问到iframe中的各种属性和对象了。

  不过如果你想在http://www.a.com/a.html页面中通过ajax直接请求http://www.script.a.com/b.html
  页面,即使你设置了相同的document.domain也还是不行的,所以修改document.domain的方法只适用于不同
  子域的框架间的交互。如果你想通过ajax的方法去与不同子域的页面交互,除了使用jsonp的方法外,还可以用
  一个隐藏的iframe来做一个代理。原理就是让这个iframe载入一个与你想要通过ajax获取数据的目标页面处在
  相同的域的页面,所以这个iframe中的页面是可以正常使用ajax去获取你要的数据的,然后就是通过我们刚刚讲
  得修改document.domain的方法,让我们能通过js完全控制这个iframe,这样我们就可以让iframe去发送
  ajax请求,然后收到的数据我们也可以获得了。

  使用document.domain+iframe跨域实例
  首先我们假设主页面地址为:http://www.js8.in/mywork/crossdomain/index.html,我们要加载的内容
  是位于work.2fool.cn域名下的helloworld.txt。我们需要在主页面中设置document.domain为2fool.cn,
  然后主页面添加一个iframe,src为域名work.2fool.cn下的一个url,在iframe页面中同样设置
  document.domain为2fool.cn,同时iframe中需要添加Ajax的函数,例如引入jQuery.js。

  主页index.html的主要代码如下:

  <button onclick="crossDomain();">开始跨域</button> 
  <div id="ajax"></div> 
  <iframe src="http://work.2fool.cn/crossdomain/iframe.html" id="iframe" style="display:none;"> </iframe> 
  <script type="text/javascript"> 
  document.domain = '2fool.cn'; 
  function crossDomain(){ 
    var iframe=document.getElementById('iframe').contentWindow.$;
    iframe.get("http://work.2fool.cn/crossdomain/helloworld.txt",function(data){
      document.getElementById("ajax").innerHTML=data; 
     }); 
  } 
  </script>
  iframe页面主要代码如下:
  <script type="text/javascript"
  src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
  <script type="text/javascript"> document.domain = '2fool.cn'; </script>

e.html5 postMessage
  参考:http://www.cnblogs.com/2050/p/3191744.html
f.flash  
g.服务器代理:服务器来做的,XMLHttpRequest的代理文件

5.清除浏览器缓存(?)

浏览器缓存的意义在于提高了执行效率,但是也随之而来带来了一些问题,导致服务端修改了js、css,客户端不能
更新 

方法一 生成随机数字 
代码如下:

<script type=”text/javascript“ src=”/js/test.js?+Math.random()+“></script> 
缺点,浏览器缓存失去意义,每次都动态加载。 

方法二 版本号控制,设置全局变量,每次发布前版本号加1 
代码如下:

<script type=”text/javascript“ src=”/js/test.js?v=<%=v%>“></script> 
推荐这种做法,这种做法比较简单。缺点是HTML页面不能使用,但是这种页面应该不太多 

6.事件

document本质:
  document.childNodes[0].tagName ==> !是文档头声明节点
  document.childNodes[1].tagName ==> HTML节点
  所以document是html和文档头声明的虚拟的父节点。

事件:用来获取事件相关详细信息,如鼠标位置,键盘按键。

事件流:

  事件冒泡:由具体对象开始接收,
          如自定下拉菜单需要取消冒泡:oEvent.cancelBubble=true;

document.onmousemove:无论鼠标在document上什么地方移动,事件都发生。
实例:1.跟随鼠标移动的提示框;2.一连串的div跟着鼠标(逆序for循环,最后一个跟着前
      一个div的坐标移动,第一个跟着鼠标移动)

鼠标事件:      
    onclick=onmousedown+onmouseup

键盘事件:
onpress=onkeydown+onkeyup;左键oEvent.keyCode:37,右键:39,回车:13,
ctrlKey,altKey,shiftKey
实例:1.回车或者ctrl和回车提交留言(oEvent.ctrlKey && oEvent.keyCode==13)

offsetWidth和offsetLeft都是实际宽和左边距离,offsetWidth=width+padding+border;
offsetLeft=left+margin;

默认行为/事件:
  浏览器自身自带的一些功能。
  如何阻止默认行为?return false;实例1:document.oncontextmenu:弹出右键菜单事件
  ,阻止浏览器默认菜单;实例2:只能输入数字的文本框,onkeydown,keyCode(0-9 49-57 
  退格 8)return false

拖拽:  
  onmousedown:存储距离,disX=oEvent.clientX-oDiv.offsetLeft;
  onmousemove:根据距离计算div最新的位置=oEvent.clientX-disX;这个事件不会根据鼠标
  有没有按下去才发生,只要移动就发生。所以拖拽需要做到在鼠标按下之前,不要发生跟随鼠标
  移动(放在onmousedown事件里面)。
  onmouseup:清理事件(也放在onmousedown事件里面,onmousemove=null让鼠标松开的时
  候,move不在发生,onmouseup=null不必要事件浪费。)
  注意:
  1.onmousemove和onmouseup事件的加在document上,否则,鼠标移动过快,就会出div
  ,拖拽就会停下来,而document在页面里面无限大。
  2.在低版本的FF下,空的div拖拽bug,鼠标样式会变成紧致样式(阻止默认事件:onmousedown
  下return false)
  3.防止拖到外面:
    if(oEvent.clientX-disX < 0){
      oEvent.clientX-disX = 0;
    }
    if(oEvent.clientX-disX > document.documentElement.clientWidth){
      oEvent.clientX-disX = document.documentElement.clientWidth;
    }

7.cookie

作用:给网站保存一些信息在客户端,比如自动登录,记住用户名。

和缓存的区别:缓存是那些访问的页面,html,css,js,图片等文件。并且缓存不受js控制,但可以
清理缓存,大部分是通过服务器和客户端设置来控制缓存。 而cookie是完全由js控制的。

特性:同一网站的所有网页共享一套cookie;数量一般不超过50个,大小以k为单位,数量,大小有限
,现在一般不纯粹使用cookie,多种cookie结合使用;有过期时间;ajax必须运行在服务器环境下,
cookie也是,但是只想在本地测试,特别点是可以在火狐下。

cookie使用:
  1.设置
  如果没有设置过期时间,cookie在窗口关闭后就清除,且不会覆盖。
  var oDate = new Date();
  oDate.setDate(oDate.getDate()+30);
  document.cookie="color=blue";
  document.cookie="username=wj;expires=" + oDate;
  console.log(document.cookie);//color=blue;username=wj

  封装cookie:
    function setCookie(name,value,iDate){
      var oDate = new Date();
      oDate.setDate(oDate.getDate()+30);
      document.cookie = name+'='+value+';expires='+iDate;
    }
  2.获取
    function getCookie(name){
      var arr = document.cookie.split(';');
      var i=0;
      for(i=0;i<arr.length;i++){
        var arr2 = arr[i].split('=');
        if(arr2[0] == name){
          return arr2[1];
        }
      }
      return '';
    }
  3.删除
    function removeCookie(name){
      setCookie(name,'1',-1);
    }
  4.实例:
  a.用cookie记录上一次关闭窗口前的div的位置  
    onmouseup:setCookie('x',oDiv.offsetLeft,5);
    window.onload 后 var x = getCookie('x');if(x){oDiv.style.left = x + 'px';}

  b.用cookie记录上次登录的用户名
    点击提交的时候:
        oForm.onSubmit = function(){
          setCookie('user',oUser.value,5);
        }
        oUser.getCookie('user');
        obnClear.onclick = function(){
          removeCookie('user');
          oUser.value = '';
        }

8.面向对象

什么是对象?对象是一个整体,对外提供一些操作。

什么是面向对象?比如jquery,使用对象的时候,只关注对象提供的功能,不关注其内部实现
细节。

js中的面向对象:
  面向对象编程(opp)特点:
    抽象:抓住核心问题;封装:不考虑内部实现,只关注功能使用;继承:从已有对象基
    础上,继承出新的对象(多重继承:多个父级,多态:父类和子类有相同的操作,但这
    些操作又有些不一样);
  对象组成:方法和属性(和函数,变量区别,变量没有所属关系,自由自在);  
  this定义:arr.show=function(){this}; oBtn.onclick=function(){this};
  this指的是当前方法属于谁,除了在this那个函数前面放一个new才失效。例如 function show(){this} show()//this:window;
  因为全局的变量和函数属于window对象;

创建对象:
 1.工厂模式:原料,加工,出厂
    缺点:
    1.没有new,new的话,构造函数里面有些东西可以简化;
    2.每个对象实例都有自己的函数,浪费资源,因为没一个function就会new Fuction()
    对象;
    //构造函数
    function createPer(name,sex){
      var obj = new Object();
      obj.name = name;
      obj.sex = sex;
      obj.showMess = function(){
        alert(this.name+"/"+this.sex);
      }
      return obj;
    }
   var p1 = createPer('wj','女');
   var p2 = createPer('wj2','男');
   p1.showMess();

results matching ""

    No results matching ""