Fork me on GitHub

Web前端教程3-JavaScript教程

1. JavaScript介绍

前端三大块

  1. HTML: 页面结构
  2. CSS: 页面表现,元素大小,颜色,位置,隐藏或者显示,部分动画效果
  3. JavaScript: 页面行为,部分动画效果,页面和用户的交互(一般不用JS,而是用JQuery)

其他插件:

  1. Ajax: 读取数据,无需刷新

1.1. JS嵌入页面的方式

<script type="text/javascript" src="../js/setting.js"></script>

2. JS基本语法

2.1. 变量类型

JS是一种弱类型语言,它的变量类型由它的值来决定

  • 5种基本数据类型:number, strign ,boolean, undefined, null
  • 1中复合类型: object

定义变量如下:

var a = 123;
var d;  //这个是undefined

2.2. 获取元素方法

方法1:(不推荐)

/* title是属性 */
/* 问题是:这个语句是按照上下顺序执行的 */
document.getElementById('div1').title="我看到了!";
<div di="div1" class='div1' title='这是div元素哦'>这是一个div元素</div>

方法2:

/* 当整个文档加载完之后,再执行这个语句 */
window.onload = function(){
  document.getElementById('div1').title="我看到了!";
}

2.3. 操作元素属性

可以参考任何标签的属性,包括linkdeng

操作方法主要分为两种:

  1. .的操作
  2. []操作

属性的写法

  1. htm属性和js属性要一直
  2. class属性写成className
  3. style属性里面的属性,有横杠的改成驼峰式font-size改成oA.style.fontSize

操作方法1的写法

<script type="text/javascript">
  window.onload = function(){
    /* 写属性 */
    document.getElementById('div1').href="www.baidu.com";
    /* 没有title属性会自动添加 */
    var oA = document.getElementById('div1');
    oA.title="666";

    /* 读属性 */
    alert(oA.id);

  }
</script>
.....
<div id="div1">这是一个div元素</div>

操作方法2的写法

<script type="text/javascript">
window.onload = function(){

  var oA = document.getElementById('div1');

  var attr ='color';
  /* 三种方法完全一致 */
  oA.style.color='red';
  oA.style[attr]='red';
  oA['style'][attr]='red';
}
</script>
.....
<div id="div1">这是一个div元素</div>

2.4. innerHTML的使用

<script type="text/javascript">
window.onload = function(){

  var oA = document.getElementById('div1');

  /* 用处1:可以读取这个标签包裹的元素 */
  /* 输出:这是一个div元素 */
  alert(oA.innerHTML)

  /* 用处2:可以塞文字 */
  oA.innerHTML = "666";
}
</script>
.....
<div id="div1">这是一个div元素</div>

3. JS函数

3.1. 函数的定义

<script type="text/javascript">
  // 定义函数
  function func_name(){
    Operations;
  }
  // 调用函数1:直接调用
  // 调用函数2:在控件中调用
  func_name();
</script>
...
<input type="button", name="", onclick="func_name()">

技巧:统一js代码再同一块中:实现JS和HTML分离

<script type="text/javascript">
window.onload = function(){
  var oBtn01 = document.getElementById('btn01');
  var oBtn02 = document.getElementById('btn02');

  /* 注意不要写括号 */
  oBtn01.skin01;
}

function skin01(){
  var oLink = document.getElementById('link1')
  oLink.href = '1.css'
}
</script>
...
<input type="button", name="", value='皮肤01' id="btn01">
<input type="button", name="", value='皮肤02' id='btn02'>

3.2. 变量和函数预解析

JS解析过长分为两个阶段,先是编译阶段,然后执行阶段,在编译阶段会将Function定义的函数提前,并且将var定义的变量声明提前(赋值不提前),将它复制为underfined

  • 方便JS的读写
<script type="text/javascript">
  // 变量的预解析
  alert(a);  //a的声明提前,因为没有赋值所以弹出undefined,a的值未定义

  alert(c);  //会报错,c没有声明

  var a = 10;
  // 函数的预解析
  my_akert();  // 函数的预解析,这个弹出hello

  function my_akert(){
    alert('hello')!
  }
</script>

3.3. 匿名函数

没有函数名的函数

<script type="text/javascript">
  window.onload = function (){
    var oDiv = document.getElementById('div1');

    oDiv.onclick = function (){
    alert('hello');
    }
  }
</script>

3.4.函数的参数

传入多个参数

<script type="text/javascript">
  window.onload = function (){

    var oDiv = document.getElementById('div1');

    function changestyle(styl,val){
      oDiv.style[styl] = val;
    }

    changestyle('color', gold);
    changestyle('backgound', red);
    changestyle('width', 300px);
  }
</script>
.....
<div id="div1">这是一个div元素</div>

返回值

实现两个输入框,值进行相加的操作

<script type="text/javascript">
window.onload = function (){

  var oInput01 = document.getElementById('input01');
  var oInput02 = document.getElementById('input02');
  var oBtn = document.getElementById('btn');


  oBtn.onclick = function (){
    var val01 = oInput01.value;
    var val02 = oInput02.value;
    var rs = add(val01,val02);
    alert(rs)
  }

  function add(a,b){
    var c = parseInt(a) + parseInt(b)
    return c;
  }

}
</script>
.....
<input type="text" name="" value="" id="input01">
<input type="text" name="" value="" id="input02">
<input type="button" name="" value="相加" id="btn">
<input type="text" id="input01">
<input type="text" id="input02">
<input type="button" value="相加" id='btn'>

return关键字

  • 返回结果
  • 结束运行,return后面的语句都不会执行
  • 阻止默认行为

4. 条件循环

运算符

  1. 算术运算符: +,-,*,/, %
  2. 条件运算符: ==, >=,<=, !=, &&(and), ||(or), |(not)
  • if-else
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      .box{
        width: 300px;
        height: 300px;
        backgound:gold;
      }
    </style>
    <script type="text/javascript">
      window.onload = function(){
        var a1 = document.getElementById('box');
        var btn = document.getElementById('btn');
        var a = 100;

        // 单条件语句
        btn.onclick = function(){
          if (a1.style.display == "none"){
            a1.style.display == "block";
          }
          else{
            a1.style.display == "none";
          }
        }

        // 多条件语句--建议用switch-case写
        if (a>50){
          a = 50;
        } else if (a>30){
          a=30;
        } else {
          a=0;
        }

      }
    </script>
  </head>
  <body>
    <div id="div1">这是一个div元素</div>
    <input type="button" name="" value="相加" id="btn">
    <div class="box" id="box"></div>
  </body>
</html>
  • switch-case
var a ==6;
switch(a){
  case 1:
    alert('1');
    break;
  case 2:
    alert('2');
    break;
  default:
    alert('0000');
    break;
}
  • for,while
for(var i=0;i<len;i++){
  operations;
}

5.JS中的数组

5.1. 创建数组的方式

/* 定义方法1: 面向对象法 */
var aRr01 = new Array(1,2,3,4,'abc');
/* 定义方法2:建议使用  */
var aRr02 = [1,2,3,4,'abc'];

/* 获取数组长度 */
var alen = aRr02.length;
/* 也可以设置长度 */
aRr02.length = 10;

/* 获取某个元素,从0开始的角标 */
var aval = aRr02[2];

/* 定义多维数组 */
var aRr03 = [[1,2,3],[4,5,6],['a','b','c']];

var aval02 = aRr03[1][2];

5.2. 数组方法

var aRr01 = [1,2,3,4];

// 数组连接字符串
var sTr01 = aRr01.join('-'); //输出1-2-3-4
var sTr02 = aRr01.join('');//输出1234

aRr01.push(5); //从尾部增加了一个成员:1,2,3,4,5
aRr01.pop(); //从尾部删除了一个成员 1,2,3,4

aRr01.unshift(0);  //从头部增加了一个成员
aRr01.shift();  //从头部删除了一个成员

aRr01.reverse(); // 将元素倒装,4,3,2,1

aRr01.indexOf(2); // 只返回元素2第一次出现的index值

aRr01.splice(2,1,7,8,9); // 从第2个元素开始,删除1个元素,然后在此位置增加7,8,9

5.3. 遍历数组

  • for循环
  • foreach方法
window.onload = function (){

  for(var i=0;i<aLi.length;i++){
    aLi[i].style.backgound='gold';
  }

  var arr = [5,7,9];
  // 函数由我们创建,不由我们调用,数组有几个元素,就会执行几次
  // 每次执行时,以实参形式传递进来
  // 浏览器在回调函数中传递三个参数
  //    1. value--当前正在遍历的元素: 5,7,9
  //    2. index--当前正在遍历的元素索引: 0,1,2
  //    3. arr ---当前正在遍历的数组
  arr.foreach(function(value, index, arr){
        console.log("value=" + value + ", index = " + index + ", array = " + arr);
    });
}

5.4. 获取元素的第二种方法

通过document.getElementByTagName获取的是一个选择集,不是数组,但是可以通过下标方式操作选择集中的dom元素

window.onload = function (){

  /* 选择特定的li元素 */
  var oList = document.getElementById('list01');
  /* aLi是一个选择集,而不是数组,获取文档中所有的li元素 */
  var aLi = oList.getElementByTagName('li');

  for(var i=0;i<aLi.length;i++){
    aLi[i].style.backgound='gold';
  }

}
<ul id='list01'>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>

<ul id='list02'>
  <li>5</li>
  <li>6</li>
</ul>

5.4. 数组去重

var aList = [1,2,3,3,4,5,2,3,1,5,4,3,2,2,1];

var aList2=[];

for(vari=0;i<aList.length;i++){
  if(aList.indexOf(aList[i]==i)){
    aList2.push(aList[i]);
  }
}

5.6. 实例: 计算器

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>测试</title>
    <script type="text/javascript">
      window.onload = function(){
        var a1 = document.getElementById('input01');
        var a2 = document.getElementById('input02');
        var op = document.getElementById('fuhao');
        var btn = document.getElementById('btn');

        btn.onclick = function(){
          var v1 = a1.value;
          var v2 = a2.value;
          var fuhao = op.value;

          // 判断输入框是否为空
          if (v1 == '' || v2 == ''){
            alert('不能为空');
            return;
          }
          // 判断输入为数字
          if(isNaN(v1) || isNaN(v2)){
            alert('请输入数字');
            return;
          }

          switch(fuhao){
            case '0':
              alert(parseFloat(v1) + parseFloat(v2));
              break;
            case '1':
              alert(parseFloat(v1) - parseFloat(v2));
              break;
            case '2':
              alert(parseFloat(v1) * parseFloat(v2));
              break;
            case '3':
              alert(parseFloat(v1) / parseFloat(v2));
              break;
          }

        }

      }

    </script>
  </head>
  <body>
    <h1>计算器</h1>
    <input type="text" name="" value="" id="input01">
    <select class="" name="" id="fuhao">
      <option value="0">+</option>
      <option value="1">-</option>
      <option value="2">*</option>
      <option value="3">/</option>
    </select>
    <input type="text" name="" value="" id="input02">
    <input type="button" name="" value="计算" id="btn">
  </body>
</html>

6. JS的字符串

JS的组成

  • ECMAscript javascript的语法(变量,函数,循环语句的语法)
  • DOM文档对象模型,操纵html和css
  • BOM浏览器对象模型,操作浏览器的方法

6.1. 字符串的处理方法

  1. 字符串合并+
  2. parseInt()将数字字符串转化为整数
  3. parseFloat()将数字字符串转化为小数
  4. split('')把一个字符串分割成字符串组成的数组
  5. charAt(index)获取字符串中的某个字符
  6. indexOf(value)查找字符串是否含有某字符
  7. substring(start,end)截取字符串用法
  8. str.split('').reverse().join('');字符串反转
  9. toUpperCase()字符串转大写
  10. toLowerCase()字符串转小写

7. 定时器

属于BOM,浏览器的用处

定时器的作用

  1. 制作动画
  2. 异步操作
  3. 函数缓冲和节流

用处1:异步操作

/* 定时器:
setTimeout      只执行一次定时器
clearTimeout    关闭只执行一次的定时器
setInterval     反复执行的定时器
clearInterval   关闭反复执行的定时器 */


/* 等1000毫秒才弹出来 */
setTimeout(myalert, 1000);

function myalert(){
  alert('Hello');
}

同时我们可以自定义弹框

<style type="text/css">

  .pop_con{
    display: none;
  }
  .pop{
    width:400px;
    height: 300px;
    background-color: #fff;
    border: 1px solid #000;
    position: fixed;
    left: 50%;
    top:50%;
    margin-left: -200px;
    margin-top: -150px;
    /* z-index用于设置成层级 */
    z-index=9999;
  }

  .mask{
    position: fixed;
    width: 100%;
    height: 100%;
    background-color: #fff;
    left: 0;
    top: 0;
    /* 设置透明 */
    opacity: 0.3;
    filter:alpha(opacity=30);
    z-index=9990;
  }
</style>


<div class="pop_con" id="pop">
  <div class="pop">
    <h3>提示信息</h3>
    <a href="#" id="shutoff">关闭</a>
  </div>

  <div class="mask"></div>
</div>
window.onload = function (){
  var oPop = document.getElementById('pop');
  var oShut = document.getElementById('shutoff');

  setTimeout(showpop,40000);

  function showpop(){
    oPop.style.display:block;
  }

  oShut.onclick = function(){
    oPop.style.display = 'none';
  }
}

关闭定时器

// 执行一次的定时器
var timer = setTimeout(function(){
  alert('hello');
},4000);

// 刚执行就关闭
clearTimeout(timer);

var timer2 = setInterval(function(){
  alert('hello');
},2000);

clearInterval(timer2);

7.1. 动画

<style type="text/css">
  .box{
    width:100px;
    height:100px;
    background-color: gold;
    position: fixed;
    left: 20px;
    top: 20px;
  }
</style>

<script type="text/javascript">
  window.onload = function(){
    var oBox = document.getElementById('box');

    var left = 20;

    var timer = setInterval(function(){
      left++;
      oBox.style.left = left + 'px';

      if(left>700){
        clearInterval(timer);
      }
    },30);
  }
</script>


<div class="box" id="box"></div>

7.2. 制作时钟

    <script type="text/javascript">
      window.onload = function(){
        var oDiv1 = document.getElementById('div1');

        function timego()){
        var now = new Date();
        var year = now.getFullYear();
        var month = now.getMonth()+1;
        var date = now.getDate();
        var week = now.getDay();
        var hour = now.getHours();
        var minute = now.getMinutes();
        var second = now.getSeconds();

        oDiv1.innerHTML = '当前时间是' + year + '年' + month + '月' + date + '日' +
        toweek(week) + hour + ':' + minute + ':'+ second;

      }

      timego();

      setInterval(timego,1000);


      }

      function toweek(num){
        switch(num){
          case 0:
              return '星期天';
              break;
          case 1:
              return '星期一';
              break;
          case 2:
              return '星期二';
              break;
          case 3:
              return '星期三';
              break;
          case 4:
              return '星期四';
              break;
          case 5:
              return '星期五';
              break;
          case 6:
              return '星期六';
              break;
        }
      }

    </script>
  </head>
  <body>
    <div id="div1"></div>
  </body>
</html>

结果是

当前时间是2019年3月12日星期二11:53:34

7.3. 制作倒计时

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>测试</title>
    <script type="text/javascript">
      window.onload = function(){
        var oDiv = document.getElementById('div1');

        function timeleft(){
        var now = new Date();
        var future = new Date(2019,10,30,24,0,0); // 实体从服务器获取
        var left = parseInt((future-now)/1000); //转为秒
        var day = parseInt(left / 86400);
        var hour = parseInt((left%86400)/3600);
        var mintue = parseInt(((left%86400)%3600)/60);
        var second = left%60;

        if (left<=0){
          window.location.href = "http://www.baidu.com";
        }

        oDiv.innerHTML = '距离2019年11月30日晚上24点还有--' + day + '天' + hour +
        '时' + mintue + '分' + second + '秒';

      }

      timeleft();
      setInterval(timeleft,1000);

      }

    </script>
  </head>
  <body>
    <div class="" id="div1">

    </div>
  </body>
</html>

8. 变量作用域

  • 全局变量-函数外部顶一顶额变量,函数内部外部都可以访问,它的值可以共享,可以随意改它的值
  • 局部变量-函数内部定义的变量,函数内部可以访问,外部无法访问,内部访问变量时,先在内部查找是否有这个变量,有的话就用内部的,没有的话就去外部找

9. 封闭函数

函数变量化

这种方式只能在函数定义后面调用

var myalert = funtion(){
  alert('hello');
}

myalert();
/*
封闭函数的定义 (function(){...})();
1. 省去函数名
2. 局部变量不会影响其他变量(相同名字) */

var str = "abc";

(function (){
  var str = '欢迎访问我的主页';

  var myfunc = function(){
    ...;
  }

  myfunc;

  alert(str);
})();

10. 闭包

函数嵌套,函数里面再定义函数,内部函数可以引用外部函数的参数和变量,变量存在闭包里面不会被回收

<script type="text/javascript">
  function aa(b){
    var a=12;
    function bb(){
      alert(a);
      alert(b);
    }

    return bb;

  }

  var cc = aa(24);  // cc=bb

  cc();

</script>
  • 同时闭包也可以改成封闭函数
<script type="text/javascript">

var cc = (function(b){
            var a=12;
            function bb(){
              alert(a);
              alert(b);
              }

              return bb;
            })(24);

</script>

10.1. 闭包的作用

  • 可以在循环中存索引值
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>测试</title>
    <script type="text/javascript">
      window.onload = function(){
        var aLi = document.getElementsByTagName('li');

        for(var i=0;i<aLi.length;i++){
          // 一般循环无法保存i,此时的i是4
          // 通过闭包存i
          (function(i){
            aLi[i].onclick = function(){

            alert(i);
          }
          })(i);
        }
      }
    </script>
  </head>
  <body>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
  </body>
</html>

  • 私有变量计数器,外部无法访问,避免全局变量的污染

11. 内置对象

对象 方法 说明
document document.referrer 获取上一个跳转页面的地址
locaiton window.location.href
window.location.search
window.location.hash
获取或者重定url地址
获取地址参数部分
获取页面锚点或者哈希值
Math Math.random
Math.floor
Math.ceil
获取0-1的随机数
向下取整
向上取整
<script type="text/javascript">

  var data = window.location.search;
  // 在网址输入“..../?a=123” 的时候输出 “?a=123”
  alert(data);

  var hash = window.location.hash;
  // 在网址输入“....#=123” 的时候输出 “#=123”
  alert(hash);

</script>

12. 面向对象

12.1. JS面向对象

将相关的变量和函数组合成一个整体,这个整体叫做对象,对象中的变量叫做属性,变量中的函数叫做方法, js对象类似字典

但是JS没有类,类是通过函数实现的

  • 内建对象
  • 宿主对象
  • 自定义对象

12.2. 自定义对象:创建对象的方法

  • 单体:
<script type="text/javascript">

  var Tom = {
    name: 'tom',
    age: 18,
    showname: function(){
      alert('my name is ' + this.name);
    },
    showage: function(){
      alert('my age is ' + this.age);
    }
  }

  alert(Tom.name);
  Tom.showname();

</script>
  • 工厂模式(少用)

通过一个函数创建对象

<script type="text/javascript">

  function Person(name, age){

    var o = new Object(); // 创建空对象
    o.name = name;
    o.age = age;
    o.showname = function(){
      alert('my name is ' + this.name);
    };
    o.showage = function(){
      alert('my age is ' + this.age);
    }

    return o;

  }

  var tom = Person('tom',18);
  tom.showname();

</script>

使用工厂方式创建的对象,使用的都是object,导致无法区分多种不同类型的对象

  • 构造函数: 类型python类

构造函数就是用一般函数创建的,区别是加了new

构造函数的执行流程:

  1. 一旦调用构造函数,马上创建一个新的对象
  2. 将新建的对象设置为函数中的this
  3. 逐行执行函数的代码
  4. 将新建的对象作为返回值返回

使用同一个构造函数的对象,称为同一类对象,也称为该类的实例

<script type="text/javascript">

  function Person(name, age){

    this.name = name; // this为新建的对象,tom, jack,向新建对象添加属性
    this.age = age;

    this.showname = function(){  // 为对象添加方法
      alert('my name is ' + this.name);
    };
    this.showage = function(){
      alert('my age is ' + this.age);
    }

  }

  var tom = new Person('tom',18);
  var jack = new Person('jack',20);
  tom.showname();

  console.log(tom instanceof Person); // true
  console.log(tom instanceof Object); //
  alert(tom.showname == jack.showname); // false, 浪费资源

</script>

问题: 每一个对象的方法都有一个新的方法,浪费资源

  • 原型模式:比构造函数更高效

我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype, 这个属性对应原型对象

  • 当函数以普通函数调用时,prototype没用
  • 当函数以构造函数调用时,它所创建的对象都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过__proto__访问
  • 当调用属性和方法时,首先在本身寻找,有就用,没有就去prototype原型寻找,没有就去原型对象的原型去找,直到找到Object原型
<script type="text/javascript">

  function Person(name, age){

    this.name = name;
    this.age = age;
  }

  // prototype上绑定的方法可以被所有person对象公用
  // prototype为原型对象,所有同一个类的实例都可以访问到这个原型对象,
  // 可以将共有的内容设置到这个原型对象中
  Person.prototype.showname = function(){
    alert('my name is ' + this.name);
  }

  Person.prototype.showage = function(){
    alert('my age is ' + this.age);
  }

  // toString是在打印对象的时候自动的内容,我们可以重写这个方法让它打印更详细的信息
  // console.log(tom);   person[name=“tom”, age=20]
  Person.prototype.toString = function(){
    return "person[name = " + this.name + ", age=" + this.age + "]";
  }

  var tom = new Person('tom',18);
  var jack = new Person('jack',20);

  console.log(tom.__proto__ == Person.prototype);  // true
  console.log(tom.hasOwnProperty("name")); // false,只有本身有属性才会true,这个方法在原型里
  alert(tom.showname == jack.showname); // true, 更加高效

</script>
  • 继承
<script type="text/javascript">

  // 定义父类
  function Fclass(name, age){

    this.name = name;
    this.age = age;
  }

  Fclass.prototype.showname = function(){
    alert('my name is ' + this.name);
  }

  Fclass.prototype.showage = function(){
    alert('my age is ' + this.age);
  }

  // 定义子类,继承父类
  function Sclass(name, age, job){
    // 继承属性:call或者apply
    // call:改变当前函数执行的this
    // apply和call的用法一样,只是语法不同: Fclass.apply(this, [name, age]);
    Fclass.call(this, name, age);
    this.job = job;
  }

  // 继承方法: prototype
  Sclass.prototype = new Fclass();

  Sclass.showjob = function(){
    alert('my job is ' + this.job);
  }

  var tom = new Sclass('tom',20,'engineer');
  tom.showage();

</script>

12.3. 自定义对象:this的用法

  • this就是object.window,指向的是一个对象,称为函数执行的上下文对象
  • 根据函数调用方式的不同,this会指向不同的对象
    • 以函数形式调用时,this为window
    • 以方法形式调用时,this为调用方法的对象,比如
    <script type="text/javascript">

      var name ="全局";

      function fun(){
        // console.log(this.name);  // 这种方式永远是"全局"
        console.log(this.name);    // 随着调用的对象不同而变化
      }

      var obj = {
        name: "sun",
        sayName: fun
      };

     var obj2 = {
        name: "kkk",
        sayName: fun
      };

      console.log(obj.sayName == fun); // true,同一个函数
      fun();          // 以函数调用的时候,this指向对象(上下文),为Object.window
      obj.sayName();  // 以方法调用的时候,this为Object.object(“sun”)
      obj2.sayName();  // 以方法调用的时候,this为Object.object(“kkk”)
    </script>

结果是

true
全局
sun
kkk

12.4. 宿主对象:Array:见5

13. 垃圾回收

  • 就像人生活的时间长了,程序运行过程中也会产生垃圾,垃圾过多后,会导致程序运行速度过慢,需要垃圾回收机制
  • 在JS中有自动垃圾回收机制,不需要也不能进行垃圾回收的操作


  • 手动回收的方法:设置为null
var a = new Obect();

a = null;

14.DOM

14.1. DOM简介

  • DOM: Document Object Model文档对象模型
    • 文档: 一个HTML网页文档
    • 对象: 网页的每个部分都转为对象,比如body, head, h1..都转为对象(就可以通过面向对象对他进行操作)
    • 模型: 用来表示对象之间的关系,方便获取对象

14.2. 节点

  • 节点是构成网页的基本节点,比如body, head, h1..

  • 节点的类型不同,属性和方法也不同

    • 文档节点: 整个HTML文档
    • 元素节点: HTML的HTML标签
    • 属性节点: 元素的属性
    • 文本节点: HTML标签中的文本内容
  • 节点的属性

节点 节点名称 节点类型 节点值
文档节点 #document 9 null
元素节点 标签名 1 null
属性节点 属性名 2 属性值
文本节点 #text 3 文本内容
  • 浏览器已经为我们提供了文档节点对象,这个对象时window属性,可以在网页中直接使用,文档节点(document)代表的是整个网页
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>测试</title>
    <script type="text/javascript">
      // 获取button对象
      var btn = document.getElementById("btn");
      // 修改button的属性
      btn.innerHTML = "你好啊";

    </script>
  </head>
  <body>
    <button id='btn'>我是按钮</button>
  </body>
</html>

14.3. 事件

  • 事件就是文档或者浏览器窗口中发生的一些特定的交互瞬间
  • JS和HTML之间的交互式通过事件实现的
  • 对于WEB应用来说,有下面这些代表性的事件: 点击,移动,按键等
<script type="text/javascript">
  window.onload = function(){
      var btn = document.getElementById("btn");
      console.log(btn);
      btn.onclick = function(){
        alert('hello');
      }
  }
</script>
....
<input type="button" name="" value="我是按钮" id="btn">

14.4. 文档加载

也就是说需要使用window.onload = function(){}

14.5. DOM查询

获取元素节点

  • 通过document对象调用
方法 说明
getElmentById() 通过唯一id获取元素节点对象,返回对象
getElementsByTagName() 通过标签名获取一组元素节点对象,返回数组
getElementByName() 通过name获取一组节点对象,返回数组

属性的写法

  1. htm属性和js属性要一直
  2. class属性写成className
  3. style属性里面的属性,有横杠的改成驼峰式font-size改成oA.style.fontSize
  • 通过元素节点调用
方法 说明
getElmentsByTagName() 获取当前节点的指定标签名后代节点
属性 说明
childNodes 当前节点的所有子节点(会获取所有的各种节点,包括空白)
firstChild 当前节点的第一个子节点(包括其他节点,空白等)
firstElementChild 当前节点的第一个子元素(IE8以上)
lastChild 当前节点的最后一个子节点
childern 当前节点的所有子元素(推荐)
parentNode 当前节点的父节点
previousSibling 当前节点的前一个兄弟节点(包括其他节点,空白等)
previousElementSibling 前节点的前一个兄弟元素(IE8以上)
nextSibling 当前节点的后一个兄弟节点
<script type="text/JavaScript">
  var btn = document.getElmentById("btn");
  btn.onclick = function(){
    // 获取id为city的元素
    var city = document.getElmentById("city");
    // 查找city下 的所有li节点
    var lis = city.getElementsByTagName("li");

    for(var i=0;i<lis.length;i++){
      alert(lis[i].innerHTML);
    }
  }
</script>

其他查询方法

// 获取`body`标签
var body = document.body;
// 获取`html`标签
var html = document.documentElement;
// 获取页面所有元素, body,html, head, script,...
var all = document.all;
var all = document.getElementsByTagName("*");
// 获取class内容>IE9
var box1 = document.getElementByClassName("box1");
// 获取含有class=“box1”的div
// querySelector: 根据CSS选择器来选择--只返回一个元素
var box1_div = document.querySelector(".box1 div");
// 返回符合条件的所有box
var box1_div = document.querySelectorAll(".box1");

14.6. DOM增删改

方法 说明
appendChild() 添加新的子节点到指定节点
removeChild() 删除子节点
replaceChild() 替换子节点
insertBefore() 在指定的子节点前面插入新的子节点
createAttribute() 创建属性节点
createElement() 创建元素节点
createTextNode() 创建文本节点
getAttribute() 返回指定的属性值
setAttribute() 设置属性值为指定的值

实例: 设计一个增加删除表格

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>表格</title>

    <script type="text/javascript">

      function delA(){
            // 点击后删除超链接所在行
            // 获取当前tr
            var tr= this.parentNode.parentNode;
            // 获取要删除的员工名称
            var emp = tr.getElementsByTagName("td")[0].innerHTML;
            // 确认是否删除
            if(confirm("真的删除" + emp + "?")){
              // 删除tr
              tr.parentNode.removeChild(tr);
            }

            return false;  // 让a不要跳转
      }

      window.onload = function(){
        // 实现删除功能
        var allA = document.getElementsByTagName("a");
        for (var i=0; i<allA.length; i++){
          // for循环会在页面加载完成时,立即执行,而相应函数只是在点击的时候执行,此时for循环已经完成
          // 此时的i为3
          // console(i) = 3;
          // 不加括号,对象赋值给this
          allA[i].onclick = delA;
        }

        // 实现添加功能
        var name = document.getElementById("empName");
        var age = document.getElementById("empAge");
        var btn = document.getElementById("addEmpButton");


        btn.onclick = function(){
          // 创建tr
          var tr = document.createElement("tr");

          console.log(name.value);
          // 设置tr内容
          tr.innerHTML = "<td>" + name.value + "</td>" +
                         "<td>" + age.value + "</td>" +
                         "<td><a href='javascript:;'>Delete</a></td>";

          var a = tr.getElementsByTagName("a")[0];
          a.onclick = delA;
          // 获取table
          var employee_table = document.getElementById("employee_table");
          // 获取table的tbody
          var tbody = employee_table.getElementsByTagName("tbody")[0];
          // 将tr添加到tbody中
          tbody.appendChild(tr);
        }



      }

    </script>

  </head>
  <body>
    <table id="employee_table">
      <tbody>
      <tr>
        <th>Name</th>
        <th>Age</th>
        <th>&nbsp;</th>
      </tr>
      <tr>
        <td>Tom</td>
        <td>23</td>
        <td><a href="javascript: ;">Delete</a></td>
      </tr>
      <tr>
        <td>Jerry</td>
        <td>12</td>
        <td><a href="deleteEmp?id=002">Delete</a></td>
      </tr>
      </tbody>
    </table>

    <hr />

    <div class="" id="formDiv">
      <h4>添加新成员</h4>

      <table>
        <tr>
          <td class="word">name: </td>
          <td class="inp">
            <input type="text" name="empName" id="empName"/>
          </td>
        </tr>
        <tr>
          <td class="word">age: </td>
          <td class="inp">
            <input type="text" name="age" id="empAge"/>
          </td>
        </tr>
        <tr>
          <td colspan="2" align="center">
            <button id="addEmpButton" value="abc">Submit</button>
          </td>
        </tr>
      </table>
    </div>
  </body>
</html>

14.7. DOM操作CSS

  • 修改样式: 元素.style.样式名 = 样式值
  • 读取样式(适用于内联样式): 元素.style.样式名
  • 读取样式(当前正在显示的样式):
    • 只能用于IE: 元素.currentStyle.样式
    • 其他浏览器: css对象 = getComputedStyle(元素名,伪元素(null)), css对象封装了样式信息,css.width
<script type="text/javascript">
  window.onload = function(){
      var box1 = document.getElementById("box1");
      var box2 = document.getElementById("box1");
      var btn01 = document.getElementById("btn");

      /*
      * 功能: 修改元素CSS样式
      * 通过JS修改元素的CSS样式
      * 语法: 元素.style.样式名 = 样式值
      *    注意: 如果CSS中含有-, 应该换成驼峰状
      * 其实设置的是内联样式(优先级高),所以会立即显示
      */
      btn01.onclick = function(){
        box1.style.width = "300px";
        box1.style.backgroundColor = "yellow";
      };

      // 获取样式表样式(当前显示样式)

      btn02.onclick = function(){
        var ar = getComputedStyle(box1);
        alert(ar.width);
      }
  };

</script>

15. DOM事件

15.1. 事件的基本使用

  • 当事件的事件句柄(Event Handlers)被触发时(e.g, onmousemove), 浏览器会自动将一个事件对象(event)作为实参传递给响应函数
  • 这个事件对象包含了很多信息(鼠标 / 键盘属性),比兔坐标,鼠标滚轮方向,按键,等等...
<script type="text/javascript">
  window.onload = function(){

    // 当事件的相应函数被触发时(onmousemove), 浏览器会自动将一个事件对象(event)作为实参传递给响应函数
    // 这个事件对象包含了很多信息,比兔坐标,鼠标滚轮方向,按键,等等...

    // 为了处理不同浏览器兼容问题
    event = event || window.event;

    btn.onmousemove = function(event){
      var x = window.event.clientX;
      var y = window.event.clientY;
    }

  }
</script>

15.2. 事件冒泡

  • 事件冒泡: 事件的向上传导,当后代元素上的事件被触发的时候,其祖先元素的相同事件也会被触发
  • 大部分有用,但是可以取消
<script type="text/javascript">
  window.onload = function(){
    var s1 = document.getElementById("s1");
    var box1 = document.getElementById("box1");

    s1.onclick = function(event){
      alert("我是span");

      // 取消事件冒泡
      event = event | window.event;
      event.cancelBubble = true;
    }

    box1.onclick = function(){
      alert("我是box1");
    }

    document.onclick = function(){
      alert("我是document");
    }
  };

</script>
  • 当点击s1的时候,会同时触发s1, box, docuemnt的onclick事件

15.3. 事件委派

  • 将事件统一绑定给元素的共同祖先元素,这样后代元素上的事件触发的时候,会一直冒泡到祖先元素
  • 事件委派: 利用了冒泡,通过委派可以减少事件胖丁的次数,提高程序的高效性
<script type="text/javascript">

  window.onload = function(){
    var lis = document.getElementsByTagName("li");
    var ul = document.getElementById("ul");
    var btn = document.getElementById("btn");

    // 问题1: 新加入的超链接没有绑定事件
    btn.onclick = function(){
      var li = document.createElement("li");
      li.innerHTML = "<a href='javascript:;'>链接新来的</a>";
      ul.appendChild(li);
    };

    // 问题2: 只能为已经有的每一个超链接绑定事件,新的超链接需要重新绑定,不推荐
    // 解决方法: 将其绑定给元素的共同的祖先元素
    /*
    * for(var i=0;i<lis.length;i++){
    *  lis[i].onclick = function(){
    *    alert("666");
    *  }
    * };
    */

    // 因为这是一个冒泡,点击a,冒泡到ul---新添加的都有了
    ul.onclick = function(event){
      // 只有点击的是link的class时
      if (event.target == "link") {
        alert("我是ul的单击函数");
      }
    }
  };

</script>

15.4. 事件绑定

  • addEventListener
    • 参数1: 事件字符串
    • 参数2: 回调函数,当事件触发的时候该函数执行
    • 参数3: 是否铺货期间触发函数,一般为false
  • 按照顺序执行
<script type="text/javascript">

  window.onload = function(){

    btn01. addEventListener("listener", function()[
      alert(1);
    ], false);

    btn01. addEventListener("listener", function()[
      alert(2);
    ], false);
  };

</script>
  • 解决兼容性:
<script type="text/javascript">

  window.onload = function(){
    function bind(obj, eventStr, callback){

      if (obj.addEventListener) {
          // 大部分浏览器兼容的方式
          obj.addEventListener(eventStr, callback, false);
      } else {
          // IE8及以下
          obj.attachEvent("on" + eventStr, callback);
      }
    }
  };

</script>

16. 应用: 轮播图

posted @ 2019-04-28 09:22  Bricker666  阅读(524)  评论(0编辑  收藏  举报