Python自动化运维 - day14 - JavaScript基础

JavaScript概述

JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。

Java和JavaScript的区别

JavaScript 与 Java 是两种完全不同的语言,无论在概念上还是设计上。

  1. Java(由 Sun 发明)是更复杂的编程语言。
  2. JavaScript 由 Brendan Eich 发明。它于 1995 年出现在 Netscape 中(该浏览器已停止更新),并于 1997 年被 ECMA(一个标准协会)采纳。ECMA-262 是 JavaScript 标准的官方名称。

什么是JavaScript

JavaScript 是脚本语言

JavaScript 是一种轻量级的编程语言。

JavaScript 是可插入 HTML 页面的编程代码。

JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。

JavaScript 可以控制HTML 输出流、对事件的反应、改变 HTML 内容、改变 HTML 图像、改变 HTML 样式、验证输入等等。

JavaScript的组成

我们说的JavaScript通常由三部分组成:

  1. ECMAScript:JavaScript标准化部分,主要定义了基础的数据类型,语法,关键字等等。
  2. DOM(文档对象模型):整合JS,CSS,HTML。
  3. BOM(浏览器对象模型):整合JS 和 浏览器。

JavaScript基础

JavaScript 是一个程序语言。遵循ECMAScript标准,语法规则定义了语言结构。

JavaScript调用方式

HTML中引入JS的方式主要有两种:直接嵌入式编写、通过导入JS文件

直接嵌入式编写:

  必须位于 <script> 与 </script> 标签之间。脚本可被放置在 HTML 页面的 <body> 和 <head> 部分中。

  注意:通常的做法是把JS函数放入 <head> 部分中,或者放在页面底部。这样就可以把它们安置到同一处位置,不会干扰页面的内容。  --> 建议放在body的最后面,这样不会阻碍网页加载

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <script>
 7         alert('hello world')    # 用于弹出告警框,便于调试
 8     </script>
 9 </head>
10 <body>
11 <script>
12     alert('hello world')
13 </script>
14 
15 </body>
16 </html>
17 
18 嵌入式
嵌入式

导入式:

  在<script></script>标签内导入

  注意:外部脚本不能中不能包含 <script> 标签。

1 <script src='index.js'></script>
导入式

JavaScript的变量标识符

JS的变量

变量是用于存储信息的"容器"。

1 var x = 1;
2 var y = 2;
3 var z = x + y ;
View Code

在代数中,我们使用字母(比如 x)来保存值(比如 5)。通过上面的表达式 z=x+y,我们能够计算出 z 的值为 11。在 JavaScript 中,这些字母被称为变量。

声明一个遍变量的方式主要有三种:

  1. 使用var关键字: var x = 1;   根据值的类型,x是number类型。   局部变量
  2. 不使用var关键字: y = 1;  根据值的类型,x是number类型。    全局变量
  3. 只定义不赋值:var x  ;  那么此时该变量的类型为undefine。
1 var x = 1;
2 console.log(typeof x)  
3 y = 2;
4 console.log(typeof y)、
5 #typeof 表示查看对象的类型
6 #console.log:通了浏览器的console输出,便于调试
View Code

Tips:

  1、在一行内定义多个变量需要用逗号隔开:var a = 1, b = 2;

  2、重新声明并不会修改变量的值: var a = 1;  var a      a的值依旧为1

变量的命名

变量可以使用短名称(比如 x 和 y),也可以使用描述性更好的名称(比如 age, sum, totalvolume)。

  • 变量必须以字母开头
  • 变量也能以 $ 和 _ 符号开头(不过我们不推荐这么做)
  • 变量名称对大小写敏感(y 和 Y 是不同的变量)
1 Camel 标记法
2 首字母是小写的,接下来的字母都以大写字符开头。例如:
3 var myTestValue = 0, mySecondValue = "hi";
4 Pascal 标记法
5 首字母是大写的,接下来的字母都以大写字符开头。例如:
6 Var MyTestValue = 0, MySecondValue = "hi";
7 匈牙利类型标记法
8 在以 Pascal 标记法命名的变量前附加一个小写字母(或小写字母序列),说明该变量的类型。例如,i 表示整数,s 表示字符串,如下所示“
9 Var iMyTestValue = 0, sMySecondValue = "hi";
变量命名

标识符

  1. 由不以数字开头的字母、数字、下划线(_)、美元符号($)组成
  2. 常用于表示函数、变量等的名称
  3. 例如:_abc,$abc,abc,abc123是标识符,而1abc不是
  4. JavaScript语言中代表特定含义的词称为保留字,不允许程序再定义为标识符

JS的数据类型

数据类型主要有一下几种:字符串(String)、数字(Number)、布尔(Boolean)、数组(Array)、对象(Object)、空(Null)、未定义(Undefined)。

数字(Number)类型

JavaScript 只有一种数字类型。数字可以带小数点,也可以不带:

var a = 3.14;
var b = 10;

在JS中所有的数字类型均为number,并且都用64位浮点格式来存储。

扩展:

  NaN类型: js来做数据转换的时候,比如当字符串转换成数字失效的时候,会返回一个 NaN 的值。类型也是属于number的

  在变量前添加 + ,则表示把该变量转换为正数

1 var a = 'a456';
2 b = Number(a)
3 console.log(b)
NaN类型

字符串(String)类型

字符串是存储字符(比如 "Lee daxin")的变量。可以是引号中的任意文本。

注意:由于没有字符类型,所以在字符串中表达常用的特殊字符,但是在使用特殊字符时必须加上反斜线\;常用的转义字符 \n:换行 \':单引号 \":双引号 \\:右划线

1 var name = 'dachenzi';
2 var job = 'Linux';
View Code

布尔(Boolean)类型

布尔(逻辑)只能有两个值:true 或 false。也代表1和0,实际运算中true=1,false=0 。这点和shell是不同的。

主要用于流程控制

1 if (1) {
2         alert('True')
3 }
4 else {
5         alert("False")
6 }
View Code

数组(Array)类型

类似于其他语言的列表,但是不是一个东西。

 1 //方式1:
 2 var arr = new Array(1,2,3,4,5);
 3 
 4 //方式2:
 5 var arr = [1,2,3,4,5];
 6 
 7 //方式3:
 8 var arr = new Array();
 9 arr[0] = 1;
10 arr[1] = 2;
11 arr[2] = 3;
View Code

扩展:列表的索引为数字,而数组的索引可以为任意.

1 <script>
2     var arr = Array();
3     arr[0]= 'w';
4     arr['index']= 6;
5     arr['input'] = 'hello world';
6     console.log(arr)
7 </script>
View Code

对象(Object)

对象由花括号分隔。在括号内部,对象的属性以名称和值对的形式 (name : value) 来定义。属性由逗号分隔:

//方式1:
var person={firstname:"Bill", lastname:"Gates", id:5566};

//方式2:
var person={
firstname : "Bill",
lastname  : "Gates",
id        :  5566
};
//声明中的空格和折行无关紧要

Persion对象有三个属性:firstname、lastname 以及 id。

访问属性的两个方式:

  1. persion.firstname
  2. persion['firstname']

空(Null)类型和未定义(Undefined)类型

Undefined 这个值表示变量不含有值

  • 当声明的变量未初始化时,该变量的默认值是 undefined。
  • 当函数无明确返回值时,返回的也是值 "undefined。

另一种只有一个值的类型是 Null,它只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。可以通过将变量的值设置为 null 来清空变量的值。

尽管这两个值相等,但它们的含义不同。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。

声明变量类型

如果我们只定义变量没有进行赋值,那么默认就是undefined类型的,如果想要声明某个类型的变量:

var name=   new String;
var x=      new Number;
var y=      new Boolean;
var arr=    new Array;
var person= new Object;

运算符

算术运算符:
    +   -    *    /     %       ++        -- 

比较运算符:
    >   >=   <    <=    !=    ==    ===   !==

逻辑运算符:
     &&   ||   !

赋值运算符:
    =  +=   -=  *=   /=

字符串运算符:
    +  连接,两边操作数有一个或两个是字符串就做连接运算

运算符和其他语言概念及应用是相同的这里就不在赘述,需要说明的是===/!== 和 ++/--。

== 和 === 的区别

var a = '123';
var b = 123;
console.log(a == b);

// JS在做比较运算的时候,会把不同的数据类型进行转换,所以这里a 是等于 b的。
// 如果不希望JS完成类型转换,那么可以使用===。

扩展:python强类型语言,js属于弱类型语言。

强类型定义语言

一种总是强制类型定义的语言。Java和Python是强制类型定义的。如果你有一个整数,如果不显示地进行转换,你不能将其视为一个字符串。

弱类型定义语言

一种类型可以被忽略的语言,与强类型定义相反。JavaScript是弱类型定义的。在JavaScript中,可以将字符串'12'和整数3进行连接得到字符串'123',然后可以把它看成整数123,而不需要显示转换。

variable++和++variable的区别

假如x=2,那么x++表达式执行后的值为3,x--表达式执行后的值为1;i++相当于i=i+1,i--相当于i=i-1;
递增和递减运算符可以放在变量前也可以放在变量后:--i

//区别主要体现在赋值的时候
var a = 1;
var b = a++;
//这里b的值为1,因为是先赋值后a自加

var b = ++a;
//这里b的值为3,因为是先a自加后赋值

流程控制

 JS中主要有三种流程控制结构:

    1. 顺序结构(从上到下顺序执行)
    2. 分支结构(比如if,else;switch case)
    3. 循环结构(比如for,while)

顺序结构

即从上到下按照顺序执行:

<script>

console.log('hello')
console.log('world')

</script>

分支结构

和python不同的是,条件表达式的and/or是用  && / || 表示的

if - else结构

if (条件表达式) {
    语句1;
    ... ...  
} else {
    语句2;
    ... ...
}

注意:只要表达式成立,或者返回值是bool都可,即if(1)也是可以的,因为1的bool类型为true;

1 <script>
2 
3 if (1) {
4     console.log('true')
5 } else {
6     console.log('False')
7 }
8 
9 </scripts>
View Code

if-else if - else 结构

if (条件表达式1) {
    语句1;
    .... ....
} else if (条件表达式2) {
    语句2;
    ... ...
} else {
    语句3;
    ... ...
}
 1 <script>
 2 
 3 var a = 10;
 4 if (a > 10) {
 5     console.log('bigger than 10')
 6 } else if (a > 5) {
 7     console.log('bingger than 5')
 8 } else {
 9     console.log('smaller than 5')
10 }
11 
12 </scripts>
View Code

switch...case结构

switch  (条件表达式) {
      case 值1:语句1;break;
      case 值2:语句2;break;
      case 值3:语句3;break;
      case 值4:语句4;break;
      default:语句5;
}
 1 <script>
 2 var a  =  5 ;
 3 switch (a) {
 4     case 0:y = '星期一';break;
 5     case 1:y = '星期二';break;
 6     case 2:y = '星期三';break;
 7     case 3:y = '星期四';break;
 8     case 4:y = '星期五';break;
 9     case 5:y = '星期六';break;
10     case 6:y = '星期七';break;
11 }
12 console.log(y)
13 </script>
View Code

switch比else if结构更加简洁清晰,使程序可读性更强,效率更高。

循环结构

for循环-条件循环

for (初始化表达式;条件表达式;自增或自减) {
    执行语句1;
    执行语句2;
    ... ...
}
1 <script>
2 
3 for (var i = 0 ; i < 10; i++) {
4         console.log(i);
5 }
6 
7 </script>
View Code

for循环-递归循环

for (变量 in 属组或对象) {
    执行语句1;
    执行语句2;
}
1 <script>
2     var arr = [1,2,3,4,5]
3     for (var i in arr) {
4         console.log(i)
5     }
6 </script>
View Code

PS:for循环,循环的是对象的索引

while循环

<script>
    while (条件表达式) {
        执行语句1;
        执行语句2;
    }
</script>
1 <script>
2     var sum = 0;
3     var i = 1;
4     while ( i < 101) {
5         sum += i
6         i++
7     }
8     console.log(sum)
9 </script>
View Code

异常处理

try {
    //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行
}
catch (e) {
    // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。
    //e是一个局部变量,用来指向Error对象或者其他抛出的对象
}
finally {
     //无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。
}

 注:主动抛出异常 throw Error('xxxx')

 1 <script>
 2     try {
 3         throw Error('hello world');
 4     }
 5     catch (e) {
 6         console.log(e);
 7     }
 8     finally {
 9         console.log('一切正常')
10     }
11 </script>
View Code

JavaScript的对象

JavaScript 中的除了null和undefined以外其他的数据类型都是对象:字符串、数值、数组、函数...此外,JavaScript 允许自定义对象。

什么是对象

JavaScript 提供多个内建对象,比如 String、Date、Array 等等。对象只是带有属性和方法的特殊数据类型。

<script language="javascript">
var aa=Number.MAX_VALUE; 
//利用数字对象获取可表示最大数
var bb=new String("hello JavaScript"); 
//创建字符串对象
var cc=new Date();
//创建日期对象
var dd=new Array("星期一","星期二","星期三","星期四"); 
//数组对象
</script>

访问对象的属性

属性是与对象相关的值,获取对象属性的方法:

objectName.propertyName
1 <script>
2     var a  =  String('hello world')
3     console.log(a.length)
4 </script>
View Code

访问对象的方法

方法是能够在对象上执行的动作,通过以下方式调用对象的方法:

objectName.methodName()
1 <script>
2     var a = String('hello world');
3     var b = a.toUpperCase() ;
4     console.log(b);
5 </script>
View Code

Javascript对象

这里主要列举JS中的字符串对象、数字对象、数组对象、日期对象、算数对象

String对象

String 对象用于处理已有的字符块。

var 变量名称 = 'string'

String方法

obj.length                           长度
 
obj.trim()                           移除空白
obj.trimLeft()
obj.trimRight)
obj.charAt(n)                        返回字符串中的第n个字符
obj.concat(value, ...)               拼接
obj.indexOf(substring,start)         子序列位置
obj.lastIndexOf(substring,start)     子序列位置
obj.substring(from, to)              根据索引获取子序列
obj.slice(start, end)                切片
obj.toLowerCase()                    大写
obj.toUpperCase()                    小写
obj.split(delimiter, limit)          分割
obj.search(regexp)                   从头开始匹配,返回匹配成功的第一个位置(g无效)
obj.match(regexp)                    全局搜索,如果正则中有g表示找到全部,否则只找到第一个。
obj.replace(regexp, replacement)     替换,正则中有g则替换所有,否则只替换第一个匹配项,
                                     $数字:匹配的第n个组内容;
                                     $&:当前匹配的内容;
                                     $`:位于匹配子串左侧的文本;
                                     $':位于匹配子串右侧的文本
                                     $$:直接量$符号

利用string的方法结合定时器,完成文字滚动的效果

    <div id="i1">欢迎大欣莅临指导  </div>

    <script>

        function f1() {
            var tag = document.getElementById('i1');
            var content = tag.innerText;

            l = content.charAt(0);
            f = content.substring(1,content.length);
            new_string = f + l;
            tag.innerText = new_string ;
        }

      setInterval('f1()',500)


    </script> 

Array对象

Array 对象用于在单个的变量中存储多个值。类似于python中的list。

new Array();
new Array(size);
new Array(element0, element1, ..., elementn);

参数:

    • size 是期望的数组元素个数。
    • element ..., elementn 是参数列表。当使用这些参数来调用构造函数 Array() 时,新创建的数组的元素就会被初始化为这些值。

注意:

    1. 返回新创建并被初始化了的数组。
    2. 如果调用构造函数 Array() 时没有使用参数,那么返回的数组为空,length 字段为 0。
    3. 当调用构造函数时只传递给它一个数字参数,该构造函数将返回具有指定个数、元素为 undefined 的数组。
    4. 当其他参数调用 Array() 时,该构造函数将用参数指定的值初始化数组。
    5. 当把构造函数作为函数调用,不使用 new 运算符时,它的行为与使用 new 运算符调用它时的行为完全一样。

Array方法

obj.length          数组的大小
 
obj.push(ele)       尾部追加元素
obj.pop()           尾部获取一个元素
obj.unshift(ele)    头部插入元素
obj.shift()         头部移除元素
obj.splice(start, deleteCount, value, ...)  插入、删除或替换数组的元素
                    obj.splice(n,0,val) 指定位置插入元素
                    obj.splice(n,1,val) 指定位置替换元素
                    obj.splice(n,1)     指定位置删除元素
obj.slice( )        切片
obj.reverse( )      反转
obj.join(sep)       将数组元素连接起来以构建一个字符串
obj.concat(val,..)  连接数组
obj.sort( )         对数组元素进行排序

PS:这里的join方法和pyton中的join是有区别的,python中的join是作用在分隔符上,传入列表的,而js中的join是作用在列表上,传入分隔符的。

// javascript
>> a = [11,22,33]    # 任意数据类型
>> a.join('-')
>> "11-22-33"

// python
>>> a = ['11','22','33']      # 列表的元素比需是字符串才行
>>> '-'.join(a)
'11-22-33'
>>> 

Date对象

Date 对象用于处理日期和时间。

var myDate=new Date()

其中:可以传入指定的时间如:'2011/02/23 12:25' ,符号会自动识别。

PS:在js中想要获取时间必须要创建一个时间对象才可以

Date方法

getFullYear()        使用 getFullYear() 获取年份。
getTime()            返回从 1970 年 1 月 1 日至今的毫秒数。
setFullYear()        设置具体的日期。
toUTCString()        将当日的日期(根据 UTC)转换为字符串。
getDay()             获取时间
getDate()            获取日期
getHours()           获取小时
getMilliseconds()    获取微秒
getMinutes()         获取分钟
getMonth()           获取月份
getSeconds()         获取秒

PS:设置的话方法同上,只不过需要把get换乘set。设置当前时间+8小时

>>> var d = new Date()
>>> d
Thu Jan 25 2018 19:27:39 GMT+0800 (中国标准时间)
>>> new_Hours = d.getHours() + 8
27
>>> d.setHours(new_Hours)
1516908459129
>>>d
Fri Jan 26 2018 03:27:39 GMT+0800 (中国标准时间)

Javascript函数

javascript的函数和其他任何一门语言的函数是相同的,都是用来组合代码块完成某个功能和任务的。

不同的是:执行函数的代码可以放在函数之前,也可以放在函数之后,因为js是先编译完毕后再执行代码中的语句。

基本语法

函数分为带参数的和不带参数的。

<script>

// 不带参数的函数
function functionname()
{
    执行代码
}

// 带参数的函数
function myFunction(var1,var2)      // 同样是形参
{
    执行代码
}

</script>

函数的调用

和Python的相同,只需要写函数名加上括号即可,如果函数有参数,那么在括号内传入即可。

<script>

function myFunction(name,job){
    alert("Welcome " + name + ", the " + job);
}

myFunction('daxin','Linux')    // 调用时传递参数
</script>

PS:函数对象也有lenght属性,它返回的是函数期望的参数个

函数的返回值

没错,也和Python的相同,只需要在函数里写上return 即可返回对应的值

<script>

function myFunction() {
    var name = 'daxin'
    return name
}

myname = myfunction()    // 把name的值返回

alert(myname)

</script>

PS:当然函数的返回值也可以直接调用,例如:document.getElementById('text').innerText=myfunction();

内置对象arguments

在javascript的函数中内置了一个arguments对象,用来存放传入的函数内部的参数。就算没有指定函数接受参数,如果我们调用时加上了参数,那么也还是会存储到arguments中去,但对于python来说,就会报错了。

<script>
function add(){
    for (var item in arguments) {
        console.log(arguments[item])
    }
}
</script>

>> add(1,2,3,4)
>> 1
>> 2
>> 3
>> 4

PS:arguments的length属性,表示传入参数的个数。

函数的其他类型

javascript中的函数其实分为:普通函数,匿名函数,立即执行函数(IIFE,或者叫做自执行函数)

普通函数就如上面所说,那什么是匿名函数?

匿名函数

匿名函数就是没有名称,在调用时直接定义,比如定时器的例子。

setInterval( function () {
	var i = 0;
	console.log(i);
},5000)

PS:定时器接受的第一个参数是函数名(),这里可以直接定义函数,那么定时器每隔5秒钟就会执行以下这段函数

当然匿名函数也可以被复制给一个变量称为有名函数,这样创建函数的方式叫做 函数的表达式形式。

var funcname = function () {
    alert(123)
};
funcname()

立即执行函数

由于函数是一个封闭的作用域范围,并且可以嵌套函数,所以可以使用这种匿名自执行函数来实现封装自己的所有函数和变量,从而避免来自多个js文件的多个函数相互冲突,并且,由于它们位于同一个函数中,所以可以互相引用。 
由于外部无法引用函数内部的变量,因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。这同时也相当于定义了一个命名空间,来自不同的js文件的功能位于自己的命名空间内。

基本格式

基本格式如下:还有基于!,+,void等,这里不在赘述

( function (接收的参数) {
    代码
})(传递的参数) 

PS:那么为什么不直接在匿名函数后面加括号来直接执行呢,就像python一样?在javascript中会提示语法错误,因为当解释器解析到function时,会把这段代码当作函数的定义,所以就算在函数的定义后面直接加括号执行,也会报错。因为解释器不识别。

使用匿名自执行函数的优点

防止包冲突

// lib1
var a = 1

// lib2 
var a = 2

// 这样a就可能在引入时被覆盖


//lib1
(function () {
    var a = 1
}()


//lib2
(function () {
    var b = 2
}()

// 这样在引入完毕后,执行函数体就不会使变量覆盖
如何访问匿名自执行函数里面的函数和对象 

通常是为函数定义一个参数,该参数是一个对象,在里面的函数或变量前加上对该对象的引用,这样该函数或变量就成为该对象的方法或属性了。

最常用到的是将全局对象window作为参数传递进去,这样函数或变量就成为全局函数和变量了。很多库函数就是用到了这种匿名自定义函数定义,例如jQuery,整个库都位于匿名自执行函数中,并传递window作为参数。

(function(window,undefined){
//jQuery定义
})(window);

函数之词法分析

看到这个名字,也许你会蒙蔽,不要被名字所迷惑,其实理解起来很简单,理解了词法分析,那么对上面函数的知识,就会有一个整体的理解。

什么是词法分析?简单来说,js运行前会有一个类似编译的过程,这个或者就叫做词法分析。此法分析主要有三步:

  1. 先分析参数
  2. 再分析变量的声明
  3. 分析函数说明

看如下例子:

<script>
    function t1(name) {
        console.log(name);
        var name = 'daxin';
        console.log(name);
        function name() {
            console.log(name)
        }
        console.log(name);
    }
    t1()
</script>

分析过程如下:

函数在此法分析的同时,会建立一个 Active Object 对象,简称AO对象,词法分析基于AO对象

分析参数
    由于函数接受name变量,所以会预先绑定给AO对象:AO.name = undefined
    函数调用是传递的参数为'dachenzi',这里修改了AO的值 AO.name = 'dachenzi'

分析变量的声明
    声明了变量name = 'daxin',它会查询AO是否有name属性,如果有就不做变化,没有就设置 AO.name = undefined

分析函数说明
    声明了函数name,然后赋值给AO.name,如果存在,则覆盖

根据上面的分析步骤,代码在还没有执行的之后,name就已经被function覆盖了。所以,试着分析结果:function name,daxin,daxin

PS:赋值方式的创建函数,属于变量阶段分析的内容。

分析打印的对象

<script>
    function t1(name) {
        console.log(name);
        function name() {
            console.log(name)
        }
        name();   // 这里调用了函数name
        console.log(name);
    }
    t1('daxin')
</script>

 根据此法分析知道,传入的参数,在分析时,就已经被function覆盖,在执行内部的name函数时,由于内部是没有name属性的,会向上查找,而name在t1中是个函数,所以这里会打印三个funcion name(){}

其他

三元运算

和python相同,在javascript中也是存在三元运算符的,具体格式如下:

var v = 表达式?真值:假值

// ?后面跟的是表达式为真时的结果
// :后面跟的是表达式为假时的结果

举例说明:

>>> v =  1==2?true:false
>>> v
false

窗口相关

前面用了很多console.log,那么这些都是什么东西

console.log    // 输出到console控制台
alert          // 警告弹窗
confirm        // 提示弹窗

// confirm 会返回一个对象,当用户点击确认,那么返回的就是true,否则返回false

URL和刷新 

location.href              // 获取URL
location.href = "url"      // 重定向
location.reload()          // 重新加载

定时器 

setInterval(函数/函数体,执行的间隔时间)     // 循环定时器,返回定时器对象
clearInterval(循环定时器对象)             // 清除多次定时器
setTimeout(函数/函数体,多久之后执行)       // 单次定时器,返回定时器对象 
clearTimeout(单次定时器对象)              // 清除单次定时器

序列化

  • JSON.stringify(obj)   序列化
  • JSON.parse(str)        反序列化
>>> arr = [1,2,3,4,5]
(5) [1, 2, 3, 4, 5]

>>> JSON.stringify(arr)
"[1,2,3,4,5]"

>>> new_arr = JSON.stringify(arr)
"[1,2,3,4,5]"

>>> JSON.parse(new_arr)
(5) [1, 2, 3, 4, 5]

转义

在使用js和服务端进行交互时,用于把特殊字符进行转义后存储或者发送

  • decodeURI( )                   对URl中转义的字符进行翻译
  • decodeURIComponent( )   对URl中转义的字符进行翻译(包含符号:或者//等都进行转义)
  • encodeURI( )                   对URI中的转义字符进行转义
  • encodeURIComponent( )   对URI组件中的字符进行转义(包含符号:或者//等都进行转义)
  • escape( )                         对字符串转义
  • unescape( )                     给转义字符串解码
  • URIError                         由URl的编码和解码方法抛出
>>> url = 'https://www.baidu.com/query=中国'
"https://www.baidu.com/query=中国"

>>> encodeURI(url)
"https://www.baidu.com/query=%E4%B8%AD%E5%9B%BD"

>>> encodeURIComponent(url)
"https%3A%2F%2Fwww.baidu.com%2Fquery%3D%E4%B8%AD%E5%9B%BD"

eval

JavaScript中的eval是Python中eval和exec的合集,既可以编译代码也可以获取返回值。

在Python中evel和exec有如下区别:

  1、evel可以执行字符串表达式,但是不能执行代码段,比如for循环的字符串格式,就不行

  2、exec可以执行代码段以及字符串表达式,但是没有返回值

>>> s = '1+1'
"1+1"
>>> eval(s)
2

>>> s = 'for(var i in [1,2,3,4] ) { console.log(i); }'
"for(var i in [1,2,3,4] ) { console.log(i); }"
>>> eval(s)
0
1
2
3

作用域

有其他语言基础的小伙伴,知道,在C,C#,java等语言中,是以代码块为作用域的,也可以说是以{}为作用域的,如下C#代码为例

public void func() {
    if (1=1) {
        string name = 'daxin'
    }
    console.write(name)
}

PS:由于是以代码块为作用域的,所以name变量只在if条件这个代码块中生效,所以执行打印操作,就会报错

但是在Python和javascript中,是以函数为作用域的,所以上面的实例在javascript中是可以正确输出的。(在新版本中使用let代替var,可以创建块级变量)

总结来说有以下几点:

  1. 以函数为作用域
  2. 函数的作用域在函数未被调用之前就已经创建(当解释器解析到函数时,就会创建,不会等到执行函数时再创建)
  3. 函数的作用域存在作用域链,并且也是在被调用之前创建
  4. 函数内局部变量会提前声明

关于作用域链

javascript的作用域链,比如在函数嵌套的场景下,当内部作用域中变量不存在时,会上上一层函数作用域中寻找,这一点和python相同

<script>
    var name = 'daxin';
    function test() {
        var name = 'dachenzi';
        function inner() {
            var name = 'hi';
            console.log(name);
        }
        inner()
    }
    test()
</script>

// 链式作用域,当内部变量不存在时,会继续向上一层中寻找

情况一:请分析打印的是什么?

<script>

    var name = 'daxin';
    function test() {
        var name = 'dachenzi';
        function inner() {

            console.log(name);
        }
        return inner          // 返回inner函数
    }

    var result = test();      // 定义变量获取 inner函数
    result();                 // 执行inner函数

</script>

在函数创建的时候作用域就已经创建,所以这里还是会引用函数内部的name属性。

情况二:请分析打印的是什么?

<script>

    var name = 'daxin';
    function test() {
        var name = 'dachenzi';
        function inner() {
            console.log(name);
        }
        var name = 'hi'
        return inner         
    }

    var result = test();     
    result();               
</script>

可以确定的是变量还是引用的test中的变量,但是dachenzi呢还是hi,因为在函数编译时,并不会执行函数,所以在编译阶段test函数内的hi就已经替换了之前的dachenzi,所以这里打印的是hi。和Python相同哦

关于提前声明

请看如下例子:

function test() {
    console.log(name);
    var name = 'daxin'
}

test()      // 这里会打印undefine

为什么会打印undefine?

javascript在解析到函数时,会创建作用域,以及作用域链,并且同时会把函数中的定义的变量预先声明

function test() {
    // var name;      会把变量提前进行声明
    console.log(name);
    var name = 'daxin';
}

所以:在打印只声明没有赋值的变量时,就会显示undefine,而在python中则会直接报错,因为python的函数没有提前声明动作。

面向对象

javascript也是一种面向对象的语言,那么如何在javascript创建类似python中的class类呢,答案是函数(在javascript中函数就是对象),看如下代码

function Foo(name) {
    this.name = name;
    this.sayName = function () {
        console.log(this.name)
    }
}

看完很定会有几个疑问:

  1. this是啥
  2. 为啥this.sayName还可以嵌套一个函数

首先,在函数中使用了this,就可以理解为这不仅仅是一个函数了,是一个函数对象(默认情况下函数本身就是一个对象),this指代的是对象本身(和python 面向对象中的self一个意思),而sayName等于一个函数,表示给对象绑定了一个方法(在python中定义方法是在class内部定义函数)。在实例化的时候,需要注意:创建对象时,需要时用new关键字。

var daxin = new Foo('daxin')
daxin.name
daxin.sayName()

// 实例化完毕后,就可以调用对象的属性了

原型

关于原型,在javasscript中有很深的含义,但是这里我们可以简单的理解为继承关系(很像python中的父类,但是有区别),沿用上面的例子

PS:在javascript中默认会为函数对象创建原型对象并存放一些属性信息,具体信息可以自行百度了解。

function Foo(name) {
    this.name = name;
    this.sayName = function () {       // 这段代码不同的对象,会重复创建,消耗内存空间
        console.log(this.name)
    }
}

针对重复创建,那么很多人想到的办法是放在一个公共的地方,对象如果需要就来调用。那么原型就是一个很好的、公共的地方。

function Foo(name) {
    this.name = name;
}

// 原型
Foo.prototype = {        // 利用原型给函数对象绑定公共属性或方法
    'sayName': function () {
         console.log(this.name)
    },
    'sayHello':function () {
        console.log('hello')
    }
};

daxin = new Foo('daxin');
console.log(daxin.name);
daxin.sayName();     // 调用对象方法
daxin.sayHello();

 这种绑定方式可以认为是组合绑定,关于原型:

  1. 使用函数名.prototype修改对象原型(也可以针对原型的某个属性进行定义:Foo.prototype.sayName = function ... ... )
  2. 对象原型类似于一个字典,可以使用key:value来进行属性或者方法的绑定。
  3. 当执行对象的方法时,如果对象本身不存在该方法,则会寻找它对应的原型对象是否存在该方法,若存在则执行,若不存在则会继续查找原型链。

动态原型模式创建对象

很多人觉得把构造方法和原型分开写,总感觉不舒服,应该想办法把构造方法和原型封装在一起,所以就有了动态原型模式。

function Foo(name) {
    this.name = name;

    if(typeof this.sayName !='function') {       //之所以这里可以使用typeof 判断不存在的方法,还记得函数的提前声明吗?,没错,这里函数内部会提前声明sayName变量,它的值为undefined.
        Foo.prototype.sayName = function (){
            console.log(this.name)
        }
    }

}

var daxin = new Foo('daxin');
daxin.sayName()

动态原型模式把所有的属性和方法都封装在构造方法中,而仅仅在需要的时候才去在构造方法中初始化原型,又保持了同时使用构造函数和原型的优点。

PS:这里只是对javascript面向对象的入门,毕竟运维层面没有这么深入。

JS正则表达式

定义正则表达式

js支持的正则表达式匹配模式有:

  • /.../    用于定义正则表达式
  • /.../g  表示全局匹配
  • /.../i   表示不区分大小写
  • /.../m 表示多行匹配

JS正则匹配时本身就是支持多行,此处多行匹配只是影响正则表达式^和$,m模式也会使用^$来匹配换行的内容)

varpattern = /^Java\w*/gm;
vartext = "JavaScript is more fun than \nJavaEE or JavaBeans!";
result = pattern.exec(text)    // ['JavaScript']
result = pattern.exec(text)    // ['JavaEE']
result = pattern.exec(text)    // null

PS:定义正则表达式也可以  reg= new RegExp()

PS:当正则表达式中包含括号时,表示取出匹配到的数据,那么利用exec获取数据时,会在列表中返回匹配到的数据和括号中匹配到的数据。

匹配

JavaScript中支持正则表达式,其主要提供了两个功能:test() , exec()

  • test(string)     检查字符串中是否和正则匹配
n = 'uui99sdf'
reg = /\d+/
reg.test(n)  ---> true
 
# 只要正则在字符串中存在就匹配,如果想要开头和结尾匹配的话,就需要在正则前后加 ^和$
  • exec(string)    获取正则表达式匹配的内容,如果未匹配,值为null,否则,获取匹配成功的数组。
# 获取正则表达式匹配的内容,如果未匹配,值为null,否则,获取匹配成功的数组。
非全局模式
    获取匹配结果数组,注意:第一个元素是第一个匹配的结果,后面元素是正则子匹配(正则内容分组匹配)
    varpattern = /\bJava\w*\b/;
    vartext = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)
    varpattern = /\b(Java)\w*\b/;
    vartext = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)
全局模式
    需要反复调用exec方法,来一个一个获取结果,直到匹配获取结果为null表示获取完毕
    varpattern = /\bJava\w*\b/g;
    vartext = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)
    varpattern = /\b(Java)\w*\b/g;
    vartext = "JavaScript is more fun than Java or JavaBeans!";
    result = pattern.exec(text)

字符串中相关方法

obj.search(regexp)                   获取索引位置,搜索整个字符串,返回匹配成功的第一个位置(g模式无效)
obj.match(regexp)                    获取匹配内容,搜索整个字符串,获取找到第一个匹配内容,如果正则是g模式找到全部
obj.replace(regexp, replacement)     替换匹配替换,正则中有g则替换所有,否则只替换第一个匹配项,
                                        $数字:匹配的第n个组内容;
                                          $&:当前匹配的内容;
                                          $`:位于匹配子串左侧的文本;
                                          $':位于匹配子串右侧的文本
                                          $$:直接量$符号

Javascript DOM对象

当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model,DOM),它是一种用于HTML和XML文档的编程接口。它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式。DOM把网页和脚本以及其他的编程语言联系了起来。DOM属于浏览器,而不是JavaScript语言规范里的规定的核心内容。

通过Dom:

  • JavaScript 能够改变页面中的所有 HTML 元素
  • JavaScript 能够改变页面中的所有 HTML 属性
  • JavaScript 能够改变页面中的所有 CSS 样式
  • JavaScript 能够对页面中的所有事件做出反应

DOM结构

HTML DOM 简单来说:

  • 定义了访问和操作HTML文档的标准方法
  • 把 HTML 文档呈现为带有元素、属性和文本的树结构(节点树)

说到Dom的结构,那么就要说一下Dom树了,Dom把HTML解析成了一个树形结构:

DOM 是这样规定的:

  1. 整个HTML是一个文档节点 
  2. 每个 HTML中的标签是一个元素节点 
  3. 包含在 HTML元素中的文本是文本节点 
  4. 每一个 HTML属性是一个属性节点

 

PS:节点之间存在父子、兄弟、等等关系,在后面标签查找时进行说明。

标签查找

在DOM中,我们可以通过document对象来对文档内的标签进行查找,正所谓找到之后才能嘿嘿嘿嘛,根据查找的方式不同,又分为直接查找和间接查找。

直接查找

直接通过节点的某个特征进行查找。

document.getElementById('id对应的值')                 // 通过标签的ID进行查找
document.getElementsByTagName('标签名')               // 通过标签的名称进行查找
document.getElementsByClassName(''class属性的值’)     // 通过标签的class属性进行查找
document.getElementsByName('name属性的值')            // 通过标签的name属性进行查找

注意:

  • id属性在文档内是唯一的,所以通过id进行的是精确查找,所以返回的就是查找到的标签(这一点查看方法名Element是单数的也能看到)。
  • 通过其他属性在文档内不一定是唯一,所以查找到的就算是1个,返回的也是数组。
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <a href="http://www.google.com">hello</a>
 9     <a href="http://www.google.com">world</a>
10     <div id="id1">18</div>
11     <p class="name">daxin</p>
12     <span name="job">Linux</span>
13 </body>
14 <script>
15     console.log(document.getElementById('id1'));
16     console.log(document.getElementsByClassName('name'));
17     console.log(document.getElementsByTagName('a'));
18     console.log(document.getElementsByName('job'))
19 </script>
20 </html>
直接查找示例

间接查找

先找到某个标签后,已该标签为参照物,然后进行查找。

parentElement           // 父节点标签元素
children                // 所有子标签
firstElementChild       // 第一个子标签元素
lastElementChild        // 最后一个子标签元素
nextElementtSibling     // 下一个兄弟标签元素
previousElementSibling  // 上一个兄弟标签元素

PS:当能唯一定位到一个标签的时候,那么返回的就是标签本身,如果不能,则返回的是数组

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <a href="http://www.google.com">hello</a>
 9     <a href="http://www.google.com">world</a>
10     <div id="id1">
11         <p id="test">测试abc</p>
12     </div>
13     <p class="name">daxin</p>
14     <span name="job">Linux</span>
15 </body>
16 <script>
17     div_tag = document.getElementById('test').parentElement;   // 这样就找到了id为id1的div标签
18     console.log(div_tag);     // 通过console.log可以方便的输出到控制台的console栏,可以方便查看
19     p_tag = div_tag.nextElementSibling;    // 这样就找到了class为name的p标签
20     console.log(p_tag);
21 </script>
22 </html>
间接查找示例

操作标签

前面说了,如何查找标签,那么既然查找到了, 我们不光可以打印它,还可以修改它。

创建标签

通过dom我们可以动态的创建某个标签,并指定它的属性值,然后添加到文档中去

// 创建节点:
createElement('标签名')  返回一个标签。
var tag = document.createElement('a')
tag.innerText = "dachenzi"
tag.className = "c1"
tag.href = "http://www.cnblogs.com/dachenzi"

// 添加节点:(放在父节点的里面,需要先找到或者创建一个父标签)
父节点.appendChild(标签对象)       -->只能追加到父节点的最后

// 在子节点的前面添加
子节点.insertBefore(标签对象)

// 删除节点
父节点.removeChild(标签对象)

// 替换节点
父节点.replaceChild(newnode,oldnode)
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <div id="id2">
10     <input type="button" value="+" id="id1" >
11     <p><input type="text"></p>
12 </div>
13 
14 </body>
15 <script>
16     document.getElementById('id1').onclick = function () {
17         var tag = document.createElement('p');
18         var input = document.createElement('input');
19         input.setAttribute('type', 'text');
20         input.fontSize = '20px';
21         input.style.color = 'red';
22         tag.appendChild(input);
23         document.getElementById('id2').appendChild(tag)
24     };
25 
26 </script>
27 
28 </html>
点击+号添加输入框

获取文本节点的值

我们使用innerText或者innerHTML来获取文本节点的值。那么它俩有什么具体的区别吗?

  • innerText:获取标签的值,当存在标签嵌套时,会去除嵌套的标签只获取嵌套标签的值
  • innerHTML:获取标签的值,相对于innerText,它会保留嵌套的标签
  • value:针对input/textarea标签,可以获取输入框输入的值,对于checkbox/radio等,获取的就是对应(选中)的标签的value属性的值。
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <a href="http://www.google.com">hello</a>
 9     <a href="http://www.google.com">world</a>
10     <div id="id1">
11         测试888
12         <p id="test">测试abc</p>
13     </div>
14     <p class="name">daxin</p>
15     <span name="job">Linux</span>
16 </body>
17 <script>
18     console.log(document.getElementById('id1').innerText);
19     console.log(document.getElementById('id1').innerHTML);
20 </script>
21 </html>
innerText/innerHTML区别

PS:关于select标签还可以设置value的值,设置不同的value,那么就会在页面上显示value对应的option选项,并且select标签还有一个selectedIndex属性,对应的就是option的列表的索引,设置为不同的索引值,也可以控制页面的选中情况

 1 <select name="" id="i0">
 2     <option value="i1">北京</option>
 3     <option value="i2">天津</option>
 4     <option value="i3">广西</option>
 5 </select>
 6 <script>
 7     var tag = document.getElementById('i0');
 8     tag.value = 'i2';
 9     tag.value = 'i3';
10     tag.selectedIndex;
11     tag.selectedIndex = 0;
12 </script>
select的value

attribute操作

针对标签的自定义属性,那么可以通过下面的方法进行操作

elementNode.setAttribute('属性名','值')      // 设置属性和对应的值
elementNode.getAttribute('属性名')           // 获取属性对应的值
elementNode.removeAttribute('属性名')        // 删除属性
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <a href="http://www.google.com">hello</a>
 9     <a href="http://www.google.com">world</a>
10     <div id="id1">
11         测试888
12         <p id="test">测试abc</p>
13     </div>
14     <p class="name">daxin</p>
15     <span name="job">Linux</span>
16 </body>
17 <script>
18     var tag = document.getElementById('id1');
19     tag.setAttribute('name','daxin');
20     console.log(tag);
21     console.log(tag.getAttribute('name'));
22 //    tag.removeAttribute('name');
23 //    console.log(tag);
24 </script>
25 </html>
添加/查看/删除属性

PS:class属性比较特殊,我们可以通过setAttribute为它设置属性,但这不是特别正规,因为dom提供了专门的方法对它进行操作。

class的操作

elementNode.className         // 获取标签class属性的值
elementNode.classList.add     // 当class的值有多个的时候,添加新的class值
elementNode.classList.remove  // 在class list中删除

PS:当class的值时多个的话,就需要使用classList来获取class属性的数组形式了。

改变css样式

var tag = document.getElementById('id1')

tag.style.color = 'blue';
tag.style.fontSize = '25px';

// 等等还有一大堆,基本上css定义的,这里都可以进行修改

PS:通过js修改css样式时,可以通过style关联css属性,需要注意的是这时css属性的名称就会被js按照它的规则重新定义(移除-,然后驼峰命名,首字母小写后面单词的字母都大写)

// font-size
tag.style.fontSize

// background-color
tag.style.backgroundColor

提交表单

在form中,提交表单的动作是由input标签的submit按钮,进行提交的,但是使用javascript,不用submit也可以进行提交。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="https://www.sogou.com/web" id="id1">
    <input type="text" name="query">
    <div onclick="submitFunc()" >提交</div>
</form>

<script>
    function submitFunc() {
        document.getElementById('id1').submit()
    }
</script>

</body>
</html>

只要能定位到form就可以利用submit尽心提交

DOM Event(事件)

事件是js可以侦测到的用户行为,然后对事件做出反应。哪什么是事件呢?

HTML 事件的例子:

  • 当用户点击鼠标时
  • 当网页已加载时
  • 当图像已加载时
  • 当鼠标移动到元素上时
  • 当输入字段被改变时
  • 当提交 HTML 表单时
  • 当用户触发按键时

事件类型及说明

onclick        当用户点击某个对象时调用的事件句柄。
ondblclick     当用户双击某个对象时调用的事件句柄。

onfocus        元素获得焦点。               练习:输入框
onblur         元素失去焦点。               应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证.
onchange       域的内容被改变。              应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动)

onkeydown      某个键盘按键被按下。          应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress     某个键盘按键被按下并松开。
onkeyup        某个键盘按键被松开。

onload         一张页面或一幅图像完成加载。

onmousedown    鼠标按钮被按下。
onmousemove    鼠标被移动。
onmouseout     鼠标从某元素移开。
onmouseover    鼠标移到某元素之上。
onmouseleave   鼠标从元素离开

onselect       文本被选中。
onsubmit       确认按钮被点击。

绑定事件

如果我们要对某一事件进行采集,那么我们首先需要在采集的地方进行事件绑定,根据绑定的方式不同,主要分为两种:

// 行内式
function func() {
    code 
}
<p onclick = "func()"></p>  


// 标签对象.事件=函数
eles = document.getElementsByClassName('items')
for (var i=0;i < eles.length;i++) {
	eles[i].onclick = function () {
    }
}

this的作用

在函数绑定的时候,我们也可以使用this,别误会,这里的this可不是面向对象。

this:指代触发该函数的标签对象,对于不同的绑定方式,使用this的方式也是不同的

对于行内式

对于行内式,必须要手动传入this,才可以在内部调用,来指代标签本身。

<div id='id2' onclick="submitFunc(this)" >提交</div>

<script>
    function submitFunc(ths) {
        console.log(ths.getAttribute('id'))
    }
</script>

标签绑定式

对于标签绑定式,那么直接就可以在在内部使用this指代,触发事件的标签本身

<div id='id2' name="daxin">提交</div>

<script>
    var tag = document.getElementById('id2');
    tag.onclick = function () {
        console.log(this.getAttribute('name'))
    }
</script>

需要注意的是:

  当批量对多个标签绑定事件的时候,我们可能会有如下操作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<table border="1px" >
    <tbody>
       <tr>
           <td>1</td>
           <td>1</td>
           <td>1</td>
           <td>1</td>
           <td>1</td>
       </tr>
      <tr>
          <td>2</td>
          <td>2</td>
          <td>2</td>
          <td>2</td>
          <td>2</td>
      </tr>
      <tr>
          <td>3</td>
          <td>3</td>
          <td>3</td>
          <td>3</td>
          <td>3</td>
      </tr>
    </tbody>
</table>

<script>
    var tr_list = document.getElementsByTagName('tr');
    for(var tr = 0;tr<tr_list.length;tr++){
        tr_list[tr].onmouseover = function () {
            tr_list[tr].style.backgroundColor = 'red';
        }
    }
    // 从代码逻辑上看,是没错的,但是由于是定义实践触发的函数,在定义阶段不会被执行,但是循环已经循环完毕了,那么,如果tr有3个,那么每次执行的时,都已经循环完毕了,tr的值永远都是2,这就不对了。所以在这种情况,一定要使用this来指代触发事件的标签。
</script>

</body>
</html>

正确的函数写法:时把tr_list[tr].style,换乘this.style 即可。

绑定事件的方式补充***(可能是面试点)

除了上面两种时间绑定方式以外,有些资深的装13的前端开发,可能会用另一种事件的绑定方式,这里简要说明。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="main"></div>

<script>

    var tag = document.getElementById('main');
    tag.addEventListener('click',function () {
        console.log('我被点击了')
    },false)

</script>
</body>
</html>

这里使用了Target.addEventListener() 绑定了事件,Target.addEventListener() 方法将指定的监听器注册到Target 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 

<!-- 最常用的语法参数如下 -->
target.addEventListener(type, listener[, useCapture]);

其中:

  • type:表示监听事件类型的字符串,比如click,等
  • listener:当所监听的事件类型触发时,会接收到一个事件通知(实现了 Event 接口的对象)对象。listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数
  • useCapture:表示事件传播模式,当一个元素嵌套了另一个元素,两个元素都对同一个事件注册了一个处理函数时,所发生的事件冒泡事件捕获是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。true表示捕捉,不填或者false表示冒泡(一般不要省略false)

PS:关于事件冒泡和事件捕捉,可以简单的理解为:从内(冒泡),或者从外(捕捉),都是基于DOM树来说的。看下面的例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #main {
            background-color: red;
            width: 500px;
            height: 500px;
            margin: 0 auto;
            position: relative;
        }

        #content {
            background-color: pink;
            width: 250px;
            height: 250px;
            position: absolute;
            top: 50%;
            left: 50%;
            margin-top: -125px;
            margin-left: -125px;
        }
    </style>
</head>
<body>

<div id="main">
    <div id="content"></div>
</div>

<script>
    var main = document.getElementById('main');
    var content = document.getElementById('content');
    main.addEventListener('click',function () {
        console.log('main')
    },false);
    content.addEventListener('click',function () {
        console.log('content');
    },false);

</script>
</body>
</html>

在标签嵌套的情况下触发content的click,同时也表示触发了main的click事件,这里为false,表示使用事件冒泡,即从内向外,所以会先打印content,然后再打印main

阻止事件传播

对于上面的例子,很多人可能有疑问,由于使用了标签嵌套,那么在嵌套部分就只需要执行最上层的标签绑定的事件即可,没必要都执行,那么针对这种需求,我们可以阻止事件进行传播。

事件是可以被 JavaScript 侦测到的行为。在DOM中,用e或者window.event表示触发的事件。

如果想要阻止事件传播,那么就可以使用eventObj.stopPropagation() ,需要注意的是,需要把事件对象传入到函数中才可以对事件进行抑制。

<!-- 上面的代码添加事件抑制后 -->

<script>
    var main = document.getElementById('main');
    var content = document.getElementById('content');
    main.addEventListener('click',function (e) {
        console.log('main');
        e.stopPropagation();   <!-- 对click事件抑制,就不会触发其他标签的click事件 -->
    },false);
    content.addEventListener('click',function (e) {
        console.log('content');
        e.stopPropagation();
    },false);

</script>

之所以在两个标签中都进行抑制,是根据不同的事件传播类型来说的,针对不同的事件类型,写一个抑制即可。 

抑制默认事件

比如a标签,我们都知道当我们点击A标签的时候,它会默认触发一个跳转动作,那我们是否可以再给它绑定一个其他的事件?答案当然是可以的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="http://www.baidu.com" id="a">百度</a>
<script src="jquery-3.1.1.js"></script>
<script>
     var tag = document.getElementById('a');
     tag.onclick = function () {
         alert(123);
         return false     // 只需要return false即可抑制默认事件
     }
</script>
</body>

</html>

PS:对于行内式的绑定方式,还需要在绑定时添加return参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="http://www.baidu.com" onclick="return fun()">百度</a>  <!-- 表示接受函数的返回值 -->
<script src="jquery-3.1.1.js"></script>
<script>
    function fun() {
        alert(123);
        return false;
    }
</script>
</body>

</html>

 PS:做事件抑制的原因是,比如我们在进行form表单提交时,如果用户填写的数据不符合规范,我们就可以在用户点击提交的同时进行检查,如果不符合要求,就抑制提交事件,如果不做条件判断只是单纯的进行抑制,那么在行内式的绑定方式中,可以直接return false;

onclick="fun();return false;"

注意:因为a、submit、等标签我们自定义的事件先于默认事件触发,我们才能抑制默认事件,而checkbox事件比较特殊,它的默认事件先于自定义事件触发,所以没有办法抑制

其他

javascript操作cookie

  在javascript中可以利用DOM对象来操作本地缓存的cookies。

document.cookie     # 获取站点的cookies
document.cookie = "username=daxin;expires=10"   # 在站点的cookie中添加,多个参数用;隔开

PS:可以看到设置cookie的方式,是直接等号,但是这样的方式不代表覆盖,而相当于添加,如果要修改某些key对应的值,那么需要使用同名的key来进行重新赋值,如果想要删除掉cookie,那么可以给该cookie的过期时间设置为过去某一个时间,让其失效。

练习

1、表格的全选,反选,以及取消

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7 
 8         #id1 tr th, #id1 tr td, #id1 {
 9             border: 1px solid red;
10             border-collapse: collapse;
11         }
12     </style>
13 </head>
14 <body>
15 <table id='id1'>
16     <thead>
17     <tr>
18         <th>序号</th>
19         <th>IP</th>
20         <th>信息</th>
21     </tr>
22     </thead>
23     <tbody>
24     <tr>
25         <td><input type="checkbox"></td>
26         <td>1.1.1.1</td>
27         <td>Administrator</td>
28     </tr>
29     <tr>
30         <td><input type="checkbox"></td>
31         <td>2.2.2.2</td>
32         <td>Administrator</td>
33     </tr>
34     <tr>
35         <td><input type="checkbox"></td>
36         <td>3.3.3.3</td>
37         <td>Administrator</td>
38     </tr>
39     </tbody>
40 
41 </table>
42 <div>
43     <input type="button" value="全选" onclick="selectAll()">
44     <input type="button" value="取消" onclick="cancelAll()">
45     <input type="button" value="反选" onclick="reverseAll()">
46 </div>
47 
48 <script>
49 
50     function selectAll() {
51         var tr_list = document.getElementById('id1').children[1].children;
52         for (var i = 0; i < tr_list.length; i++) {
53             var tr = tr_list[i];
54             tr.children[0].children[0].checked = true;
55         }
56         ;
57     }
58     ;
59 
60     function cancelAll() {
61         var tr_list = document.getElementById('id1').children[1].children;
62         for (var i = 0; i < tr_list.length; i++) {
63             var tr = tr_list[i];
64             tr.children[0].children[0].checked = false;
65         }
66         ;
67     }
68     ;
69 
70     function reverseAll() {
71         var tr_list = document.getElementById('id1').children[1].children;
72         for (var i = 0; i < tr_list.length; i++) {
73             var tr = tr_list[i];
74             tr.children[0].children[0].checked = !tr.children[0].children[0].checked;
75         }
76         ;
77     }
78     ;
79 
80 
81 </script>
82 
83 </body>
84 </html>
View Code

PS:对于checkbox来讲,可以直接通过标签.checked 来设置/获取它对应的属性的值。

2、模态对话框

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>Title</title>
  6     <style>
  7 
  8         #id1 tr th, #id1 tr td, #id1 {
  9             border: 1px solid red;
 10             border-collapse: collapse;
 11         }
 12 
 13         .hide {
 14             display: none;
 15         }
 16 
 17         .back {
 18             position: fixed;
 19             top: 0;
 20             bottom: 0;
 21             right: 0;
 22             left: 0;
 23             background-color: darkgray;
 24             opacity: 0.6;
 25             z-index: 6;
 26         }
 27 
 28         .talk {
 29             height: 400px;
 30             width: 600px;
 31             background-color: white;
 32             position: fixed;
 33             top: 50%;
 34             left: 50%;
 35             margin-top: -200px;
 36             margin-left: -300px;
 37             z-index: 10;
 38             text-align: center;
 39             line-height: 400px;
 40         }
 41 
 42 
 43     </style>
 44 </head>
 45 <body>
 46 <div>
 47     <input type="button" value="添加" onclick="addHost()">
 48 </div>
 49 <table id='id1'>
 50     <thead>
 51     <tr>
 52         <th>序号</th>
 53         <th>IP</th>
 54         <th>信息</th>
 55     </tr>
 56     </thead>
 57     <tbody>
 58     <tr>
 59         <td><input type="checkbox"></td>
 60         <td>1.1.1.1</td>
 61         <td>Administrator</td>
 62     </tr>
 63     <tr>
 64         <td><input type="checkbox"></td>
 65         <td>2.2.2.2</td>
 66         <td>Administrator</td>
 67     </tr>
 68     <tr>
 69         <td><input type="checkbox"></td>
 70         <td>3.3.3.3</td>
 71         <td>Administrator</td>
 72     </tr>
 73     </tbody>
 74 
 75 </table>
 76 <div>
 77     <input type="button" value="全选" onclick="selectAll()">
 78     <input type="button" value="取消" onclick="cancelAll()">
 79     <input type="button" value="反选" onclick="reverseAll()">
 80 </div>
 81 
 82 
 83 <!-- 背景遮罩层 -->
 84 <div class="back hide" id="back"></div>
 85 <!-- 模态对话框 -->
 86 <div class="talk hide" id="talk">
 87     <div class="userinfo">
 88         <label for="user">用户名:</label>
 89         <input type="text" id='user'>
 90         <label for="pass">密码:</label>
 91         <input type="password" id="pass">
 92         <input type="button" value="取消" onclick="cancelHost()">
 93     </div>
 94 
 95 </div>
 96 
 97 
 98 <script>
 99 
100     function selectAll() {
101         var tr_list = document.getElementById('id1').children[1].children;
102         for (var i = 0; i < tr_list.length; i++) {
103             var tr = tr_list[i];
104             tr.children[0].children[0].checked = true;
105         }
106         ;
107     }
108     ;
109 
110     function cancelAll() {
111         var tr_list = document.getElementById('id1').children[1].children;
112         for (var i = 0; i < tr_list.length; i++) {
113             var tr = tr_list[i];
114             tr.children[0].children[0].checked = false;
115         }
116         ;
117     }
118     ;
119 
120     function reverseAll() {
121         var tr_list = document.getElementById('id1').children[1].children;
122         for (var i = 0; i < tr_list.length; i++) {
123             var tr = tr_list[i];
124             tr.children[0].children[0].checked = !tr.children[0].children[0].checked;
125         }
126         ;
127     }
128     ;
129 
130     function addHost() {
131         document.getElementById('back').classList.remove('hide');
132         document.getElementById('talk').classList.remove('hide');
133     }
134 
135     function cancelHost() {
136         document.getElementById('back').classList.add('hide');
137         document.getElementById('talk').classList.add('hide');
138     }
139 </script>
140 
141 </body>
142 </html>
View Code

 3、左侧菜单

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         .hide {
 8             display: none;
 9         }
10         .page_menu {
11             width:500px;
12         }
13         .item {
14             font-size:25px;
15             font-family: Consolas;
16         }
17         .item .page_header {
18             background-color: blue;
19             font-weight: 700;
20             color:white;
21         }
22     </style>
23 </head>
24 <body>
25 
26 <div class="page_menu">
27     <div class="item">
28         <div class="page_header" id="i1" onclick="showMenu('i1')">菜单1</div>
29         <div class="page_content">
30             <div>菜单1</div>
31             <div>菜单1</div>
32             <div>菜单1</div>
33         </div>
34     </div>
35      <div class="item">
36         <div class="page_header" id="i2" onclick="showMenu('i2')">菜单2</div>
37         <div class="page_content hide">
38             <div>菜单2</div>
39             <div>菜单2</div>
40             <div>菜单2</div>
41         </div>
42     </div>
43      <div class="item">
44         <div class="page_header" id="i3" onclick="showMenu('i3')">菜单3</div>
45         <div class="page_content hide">
46             <div>菜单3</div>
47             <div>菜单3</div>
48             <div>菜单3</div>
49         </div>
50     </div>
51      <div class="item">
52         <div class="page_header" id="i4" onclick="showMenu('i4')">菜单4</div>
53         <div class="page_content hide">
54             <div>菜单4</div>
55             <div>菜单4</div>
56             <div>菜单4</div>
57         </div>
58     </div>
59 
60 
61 </div>
62 
63 <script>
64     function showMenu(id) {
65         var header = document.getElementById(id);    // 找到点击的菜单
66         var item_list = header.parentElement.parentElement.children;    // 获取所有菜单列表
67         for(var i = 0;i<item_list.length;i++){
68             item_list[i].children[1].classList.add('hide');     // 给所有菜单列表添加hide属性,不显示子菜单
69         }
70         header.nextElementSibling.classList.remove('hide');   // 给自己删除hide属性,显示子菜单
71 
72     }
73 </script>
74 
75 
76 </body>
77 </html>
View Code

 方法二:引入this的概念,表示标签自己

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 
 7     <style>
 8         .left_menu {
 9             width: 20%;
10             height: 500px;
11             background-color: wheat;
12             float: left;
13         }
14 
15         .content_menu {
16             width: 80%;
17             height: 500px;
18             background-color: darkgray;
19             float: left;
20         }
21 
22         .title {
23             text-align: center;
24             background-color: brown;
25             line-height: 30px;
26             color: white;
27         }
28 
29         .item {
30             margin: 20px;
31         }
32 
33         .hide {
34             display: none;
35         }
36     </style>
37 
38 </head>
39 <body>
40 <div class="outer">
41     <div class="left_menu">
42 
43         <div class="item">
44             <div class="title">菜单一</div>
45             <div class="con">
46                 <p>1111</p>
47                 <p>1111</p>
48                 <p>1111</p>
49             </div>
50         </div>
51         <div class="item">
52             <div class="title">菜单二</div>
53             <div class="con hide">
54                 <p>2222</p>
55                 <p>2222</p>
56                 <p>2222</p>
57             </div>
58         </div>
59         <div class="item">
60             <div class="title">菜单三</div>
61             <div class="con hide">
62                 <p>3333</p>
63                 <p>3333</p>
64                 <p>3333</p>
65             </div>
66         </div>
67     </div>
68     <div class="content_menu"></div>
69 </div>
70 <script>
71     var ele = document.getElementsByClassName('title');
72     for (var i = 0; i < ele.length; i++) {
73         ele[i].onclick = function () {
74             console.log(this);
75             this.nextElementSibling.classList.remove('hide');
76             var arr_item = this.parentElement.parentElement.children;
77             var ele_curr_p = this.parentElement;
78             for (var j = 0; j < arr_item.length; j++) {
79                 if (arr_item[j] != ele_curr_p) {
80                     arr_item[j].children[1].classList.add('hide')  //不存在重复添加的概念
81                 }
82             }
83         }
84     }
85 
86 </script>
87 </body>
88 </html>
View Code

 3、输入框提示文本,获取鼠标焦点时消失

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 <input type="text" id="i1" value="请输入搜索的内容"> <input type="button" value="搜索">
10 
11 <script>
12 
13     var ele = document.getElementById('i1');
14     ele.onfocus = function () {
15         if(this.value == '请输入搜索的内容') {
16             this.value = ''
17         }
18     };
19     ele.onblur = function () {
20         if(this.value == '') {
21             this.value = '请输入搜索的内容'
22         }
23     };
24 
25 </script>
26 </body>
27 </html>
placeholder的js效果

 

posted @ 2017-07-31 18:13  SpeicalLife  阅读(423)  评论(0编辑  收藏  举报