纯干货!Web前端教程之JavaScript篇!详细知识点路线图+视频教程

点击原文获取资源:https://zhuanlan.zhihu.com/p/70515753


JavaScript 是属于 HTML 和 Web 的编程语言。

编程令计算机完成您需要它们做的工作。

JavaScript 很容易学习。

本教程涵盖 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. 内置对象

对象方法说明documentdocument.referrer获取上一个跳转页面的地址locaitonwindow.location.href

window.location.search

window.location.hash获取或者重定url地址

获取地址参数部分

获取页面锚点或者哈希值MathMath.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标签中的文本内容

 

  • 节点的属性

节点节点名称节点类型节点值文档节点#document9null元素节点标签名1null属性节点属性名2属性值文本节点#text3文本内容

  • 浏览器已经为我们提供了文档节点对象,这个对象时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. 应用: 轮播图


视频教程+学习路线图

学习路线图

------------------------课程介绍------------------------ 第1章 HTML、CSS、布局 第2章 JavaScript 介绍 第3章 作业讲解、编程的选择结构和函数返回值和库、css初步、函数参数 第4章 数组和字符串、作业讲解、debug大法 第5章 作业讲解、如何方便地用测试写代码、break&continue;语句、object、读文档、递归 第6章 网页中引入JavaScript代码、DOM、事件 第7章 数据类型、多行字符串和转义符号、高阶函数、匿名函数 第8章 事件委托、时间操作、标签的可编辑属性、(本地存储) 和 JSON 格式 第9章 作业选讲、抽象化, 如何封装功能, 如何组织代码结构、变量命名的方法 第10章 HTTP 协议 和 AJAX、DOM 事件机制, 事件冒泡和事件捕获 第11章 面向对象、ajax、作业和代码思路 第12章 找工作基础、ajax作业、api封装 第13章 jQuery 常见用法、课程重点、常用组件例如弹窗的制作 第14章 作业讲解 第15章 log的要素、git和github、js的一些高级内容 bind apply call、前端CSS框架Bootstrap和Pure 第16章 JS的历史现状和未来、什么是ES6有什么新东西、CSS最基础的套路 第17章 前端工程师 第1章 网址组成、端口、HTTP协议、web服务器 第2章 作业讲解、服务器框架、html和getpost传递参数 第3章 基本框架、框架解释、model解释 第4章 cookie讲解、session讲解、作业讲解和调试技巧 第5章 todo程序、todo的更新和删除、带用户功能的todo程序 第6章 jinja模板套路、类和其他、作业讲解 第7章 摘要算法、加盐保护密码-数据库索引原理、微博程序 第8章 传统数据库、sql注入和mongo安装使用、mongo日常使用 第9章 前端基础、dom和事件、js todo 第10章 ajax 第11章 css 第12章 linux基础 第13章 flask框架 第14章 使用sshkey连接linux服务器、rsa原理和git软件使用、使用git软件同步本地和服务器代码 第15章 flask的session和cookie、flask留言板&web;后端栈、flask博客套路 第16章 抓包&爬虫基础、爬虫精讲、编码&API; 第17章 数据结构基础和算法分析原理、链表队列栈和四大结构、平衡二叉搜索树和哈希表 第18章 bbs基础、bbs标题和回复、bbs其他 第19章 web安全和应对、服务器的配置文件处理、开发论坛的板块功能 第20章 论坛收尾、迁移mongo、性能 第21章 操作系统、python高级 第22章 python高级技巧、rpc实现和vagrant 第23章 架构、分布式、性能、聊天室项目 第24章 简历和工作、工作后的计划、学习的计划
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值