JavaScript基础

学习笔记源自:绿叶

对于CSS来说,外部CSS文件只能在head中引入。对于JavaScript来说,外部JavaScript文件不仅可以在head中引入,还可以在body中引入。引入外部CSS文件使用的是“link标签”,而引入外部JavaScript文件使用的是“script标签”。

基本语法

变量

变量由字母、下划线、$或数字组成,并且第一个字母必须是字母、下划线或$。区分大小写

变量不能是系统关键字和保留字。

所有JavaScript变量都由var声明。

常量名全部采用大写形式

数据类型

基本数据类型有5种:数字、字符串、布尔值、未定义值和空值。
常见的引用数据类型只有一种:对象(数组也是属于对象的一种)。

null跟undefined的区别?
1
2
3
4
console.log(null==undefined);    //true  因为两者都默认转换成了false
console.log(typeof undefined); //"undefined"
console.log(typeof null); //"object"
console.log(null===undefined); //false "==="表示绝对相等,null和undefined类型是不一样的,所以输出“false”

null和undefined转换成number数据类型
null 默认转成 0
undefined 默认转成 NaN

null表示”没有对象”,即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

undefined表示”缺少值”,就是此处应该有一个值,但是还没有被赋值。典型用法是
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有return返回值时,默认返回undefined。

显式类型转换

将字符串转换为数字,有两种方式。
Number( )。只能将纯“数字型字符串”转换为数字
parseInt( )和parseFloat( )。提取“首字母为数字的任意字符串”中的数字,可以接受第1个字符是加号或减号。
提取类似”100px”这种字符串中的数字,这个时候我们就应该使用parseInt( )和parseFloat( )
如果数字是小数,则parseInt( )和parseFloat( )两个方法返回的结果是不一样的,我们可以利用这个特点,来判断一个数是整数,还是小数。

将数字转换为字符串,也有两种方式。
与空字符串相加。 使用更多
toString( )。

这些转换在一些跟数位有关的算法题中很常用。

内置对象

常用的内置对象有4种。

字符串对象:String。

  • length属性来获取字符串的长度。
  • toLowerCase( )方法将大写字符串转化为小写字符串,toUpperCase( )方法将小写字符串转化为大写字符串。
  • charAt( )方法来获取字符串中的某一个字符。var char=str.charAt(i);
  • substring( )方法来截取字符串的某一部分。substring(start,end)的截取范围为“[start,end)”当end省略时,截取的范围为“start到结尾”。
  • replace( )方法来用一个字符串替换另外一个字符串的某一部分。replace( )方法有两种使用形式:一种是直接使用字符串来替换,另外一种是使用正则表达式来替换。正则只会替换第一个匹配的
  • split( )方法把一个字符串分割成一个数组,分割符可以是一个字符、多个字符或一个正则表达式。split( )方法有两个参数:第1个参数表示分割符,第2个参数表示获取“分割之后的前n个元素”。split(””)可以用来分割字符串的每一个字符。数组join( )方法一般都是配合字符串的split( )方法来使用的。
  • indexOf( )方法可以找出“某个指定字符串”在字符串中“首次出现”的下标位置
  • lastIndexOf( )方法可以找出“某个指定字符串”在字符串中“最后出现”的下标位置。如果字符串中不包含“指定字符串”,indexOf( )或lastIndexOf( )会返回-1
  • 两个字符之间比较的是ASCII码的大小
  • isNaN( )函数来判断一个值是否为NaN值。NaN,意为Not a Numer(非数字)。

数组对象:Array。

1
2
var 数组名=new Array(元素1,元素2,……,元素n);  //完整形式
var 数组名=[元素1,元素2,……,元素n];       //简写形式
  • length属性来获取数组的长度。
  • slice( )方法获取数组的某一部分。slice(start,end)的截取范围为[start,end)
  • unshift( )方法在数组开头添加新元素
  • shift( )方法删除数组中的第一个元素
  • push( )方法在数组结尾添加新元素,不需要知道数组有多少个元素
  • pop( )方法删除数组的最后一个元素
  • sort( )方法对数组中的所有元素进行大小比较,可以将排序函数作为参数
  • reverse( )方法实现数组中所有元素的反向排列
  • join( )方法将数组中的所有元素连接成一个字符串。默认情况下,一般会采用英文逗号(,)作为连接符。str1.split("*").join("#") 即可实现符号替换
  • 数组是可以存储“不同数据类型”的数据的,只不过在实际开发中极少这样做。

日期对象:Date。
创建一个日期对象,必须使用new关键字。其中Date对象的方法有很多,主要分为两大类:getXxx( )和setXxx( )。

注意getMonth( )方法的返回值是0(一月)到11(十二月)之间的整数
此外还要注意,要获取当前的“日”,不是使用getDay( ),而是使用getDate( ),getDay( )是用来获取星期几的,返回数字,有时需要用预设汉字数组转为汉字

set比get能设置更多的信息

数值对象:Math。
Math对象不需要使用new关键字来创造,而可以直接使用它的属性和方法。
Math对象的属性都是常量

120*Math.PI/180 //120°
Math对象中的方法(常用)

atan2(x)能够精确判断角度对应哪一个角,而atan(x)不能。大多数用的是atan2(x)
random( )方法的范围是[0, 1)

例子:随机生成验证码

函数

根据作用域,变量可以分为全局变量和局部变量。
全局变量一般在主程序中定义,其有效范围是从定义开始,一直到整个程序结束。也就是全局变量在任何地方都可以使用。
局部变量一般在函数中定义,其有效范围只限于在函数中。也就是局部变量只能在函数中使用,函数之外是不能使用函数中定义的变量的。

JavaScript代码是从上到下执行的,JavaScript遇到函数定义部分会直接跳过(忽略掉),只有遇到函数调用时才会返回执行函数定义部分。也就是说,函数定义之后只有被调用才有意义。

JavaScript的函数调用方式有很多,常见的有以下4种。

  • 直接调用。
  • 在表达式中调用。
  • 在超链接中调用,指的是在a元素的href属性中用“javascript:函数名”的形式来调用函数。当用户点击超链接时,就会调用该函数。
  • 在事件中调用。如鼠标移动,点击等
嵌套函数

可以在一个函数的内部定义另外一个函数。但是在内部定义的函数只能在内部调用,如果在外部调用,就会出错。

嵌套函数的功能非常强大,并且跟JavaScript最重要的一个概念“闭包”有重要的关系。

一句话理解闭包:内部的嵌套函数可以访问到外部函数的变量,即使这个外部函数已经执行完毕退出了。

DOM

DOM,全称是“Document Object Model(文档对象模型)”,它是由W3C定义的一个标准。

DOM采用的是“树形结构”,用“树节点”的形式来表示页面中的每一个元素。每一个元素就是一个节点,而每一个节点就是一个对象。也就是说,我们在操作元素时,其实就是把这个元素看成一个对象,然后使用这个对象的属性和方法来进行相关操作

节点和元素是不一样的概念,节点是包括元素的。DOM节点共有12种类型,但是常见的只有下面3种。
元素节点。
属性节点。
文本节点。
属性节点和文本节点看起来像是元素节点的一部分,但实际上,它们是独立的节点,并不属于元素节点
只有元素节点才可以拥有子节点,属性节点和文本节点都无法拥有子节点。

可以使用nodeType属性来判断一个节点的类型。

节点操作(元素节点)

获取元素节点

获取的是一个DOM对象,我们在给变量命名的时候,习惯性地以英文“o”开头

  • getElementById( )类似于CSS中的id选择器
  • getElementsByTagName( )类似于CSS中的“元素选择器”。获取的是一个“类数组”(也叫伪数组),只能使用数组的length属性以及下标
  • getElementsByClassName( )类似于CSS中的class选择器。
  • querySelector( )和querySelectorAll( )使用CSS选择器的语法来获取所需要的元素。前者获取第一个。实际上调用了CSS选择器,性能不太好
  • getElementsByName( )只用于表单元素,一般只用于单选按钮和复选框。
    document.title和document.body 一个页面只有一个title元素和一个body元素

注意element的单复数,如果是数组必须加索引才能访问到元素

getElementById( )前面只可以接document,也就是document.getElementById( )。getElementsByTagName( )前面不仅可以接document,还可以接其他DOM对象。
getElementById( )和getElementsByClassName( )不可以操作动态创建的DOM元素,而getElementsByTagName( )可以操作动态创建的DOM元素。

创建元素

使用createElement( )来创建一个元素节点,也可以使用createTextNode( )来创建一个文本节点,然后可以将元素节点与文本节点“组装”成我们平常看到的“有文本内容的元素”。这种方式又被称为“动态DOM操作”。所谓的“动态DOM”,指的是使用JavaScript创建的元素。这个元素一开始在HTML中是不存在的。

在操作动态DOM时,设置元素class用的是className而不是class,因为JavaScript有很多关键字和保留字,其中class已经作为保留字了

插入元素

插入元素有以下两种方法。
appendChild( )把一个新元素插入到父元素的内部子元素的“末尾”。
insertBefore( )将一个新元素插入到父元素中的某一个子元素“之前”。A.insertBefore(B,ref)则表示在ref之前插入B。

这两种插入元素的方法都需要先获取父元素才可以操作。

删除元素

使用removeChild( )方法来删除父元素下的某个子元素。
oUl.removeChild(oUl.lastElementChild);

复制元素

obj.cloneNode(bool)
参数obj表示被复制的元素,而参数bool是一个布尔值,取值如下。
1或true:表示复制元素本身以及复制该元素下的所有子元素。
0或false:表示仅仅复制元素本身,不复制该元素下的子元素。

替换元素

A.replaceChild(new,old);

综上可知,要实现节点的各种操作,必须先找到父元素才行。

HTML属性操作(属性节点)

使用对象属性

使用obj.attr这种方式,不仅可以获取静态HTML元素的属性值,还可以获取动态创建的DOM元素中的属性值

要获取一个元素的class,写成oBtn.class是错误的,正确的写法是oBtn.className。

在实际开发中,在更多的情况下,我们要获取的是表单元素的值。其中文本框、单选按钮、复选框、下拉列表中的值,都是通过value属性来获取的。

使用对象方法

关于操作HTML元素的属性,JavaScript为我们提供了4种方法。

  • getAttribute( ) 注意参数要加引号,不仅可以用来获取静态HTML元素的属性值,还可以用来获取动态DOM元素中的属性值
  • setAttribute( )
  • removeAttribute( )在更多情况下是结合class属性来“整体”控制元素的样式属性的
  • hasAttribute( )直接使用removeAttribute( )删除元素的属性的做法是不太正确的,比较严谨的做法是先用hasAttribute( )判断这个属性是否存在,只有存在,才去删除。

使用obj.attr(也就是对象属性方式)是无法获取自定义属性值的,只能用getAttribute(”attr”)(也就是对象方法方式)来实现。
同样地,对于自定义属性的值的设置,我们也只能用setAttribute( )方法来实现。
想要删除元素的某个属性,我们只能使用removeAttribute( )这一个方法。

记住:只有“对象方法方式”才可以操作自定义属性。

CSS属性操作

获取CSS属性值getComputedStyle(obj).attr
需要注意的是,这里的属性名使用的是“骆驼峰型”的CSS属性名。如font-size应该写成fontSize

getComputedStyle( )方法其实有两种写法:getComputedStyle(obj).attr和getComputed Style(obj)[“attr”]。实际上,凡是对象的属性都有这两种写法。后者常用于通过get获得的字符串用于设置。

设置一个CSS属性的值,有两种方式可以实现。

  • style对象。obj.style.attr="值"; 这种方式设置的是“行内样式”

  • cssText属性。同时设置多个CSS属性,这也是在元素的style属性中添加的。cssText的值是一个字符串。注意,这个字符串中的属性名不再使用骆驼峰型的写法,而是使用平常的CSS写法因为变量中是不允许出现中划线的
    oDiv.style.cssText="width:100px;height:100px;border:1px solid gray;";

    在实际开发的时候,如果要为一个元素同时设置多个CSS属性,我们很少使用cssText来实现,而更倾向于使用操作HTML属性的方式给元素加上一个class属性值,从而整体地给元素添加上样式。

获取CSS属性值,不可以用obj.style.attr或obj.style.cssText吗?为什么一定要用getComputedStyle( )呢?
obj.style.attr只可以获取元素style属性中设置的CSS属性,对于内部样式或者外部样式,它是没办法获取的。
getComputedStyle( ),从名字上就可以看出来,意思是get computed style(获取计算后的样式)。所谓“计算后的样式”,是指不管是内部样式,还是行内样式,最终获取的是根据CSS优先级计算后的结果。

DOM遍历

使用parentNode属性来获得某个元素的父元素。

使用以下两组方式来获得父元素中的所有子元素或某个子元素。
childNodes、firstChild、lastChild。
children、firstElementChild、lastElementChild。更常用

使用childNodes、firstChild、lastChild这几个方法来操作元素节点非常麻烦,因为它们都把文本节点(一般是空白节点)算进来了

使用以下2组方式来获得兄弟元素。
previousSibling、nextSibling。
previousElementSibling、nextElementSibling。

跟查找子元素的两组方式一样,previousSibling和nextSibling查找出来的可能是文本节点(一般是空白节点),因此如果只操作元素节点,建议使用previousElementSibling和nextElementSibling。

innerHTML和innerText

使用innerHTML属性很方便地获取和设置一个元素的“内部元素”,也可以使用innerText属性获取和设置一个元素的“内部文本”。

innerHTML后面的字符串要换行只要在每一行后面加上个反斜杠(\)就可以了

使用appedChild( )方法需要依次设置属性值。
innerHTML属性可以直接很多属性。

document.write( )和innerHTML之间有什么区别?
  • write是DOM方法,向文档写入HTML表达式或Java代码,可列出多个参数,参数被顺序添加到文档中。innerHTML是DOM属性,设置或返回调用元素开始结束标签之间的HTML元素。
  • document.write 会直接写入文档流中, 如果在文档渲染完毕后调用会迫使浏览器重新渲染,innerHtML 仅仅修改DOM 内部的内容.document.write会重绘整个页面,而innerHTML是可以重绘页面的某一部分.
  • 通过document.write插入<>元素会自动执行其中的脚本;大多数浏览器中,通过innerHTML插入<>元素并不会执行其中的脚本。
  • innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。

事件

其实从本质上来说,事件调用方式用于操作元素的属性。只不过这个属性不是一般的属性,而是“事件属性”。

调用方法

在JavaScript中,调用事件的方式有两种。

  1. 在script标签中调用。 更常用
1
2
3
obj.事件名=function(){
……
};

如果多个元素都要调用,可以写成一个专门的函数。再将函数赋值给事件

  1. 在元素中调用。

事件类型

JavaScript常见的事件共有以下5种。

页面事件

onload表示文档加载完成后再执行的一个事件。一般地,只有在想要“获取页面中某一个元素”的时候才会用到。因为在默认情况下,浏览器是从上到下来解析一个页面的。如果没有加载完就会出现解析错误。但是如果script中只定义了函数,在元素中进行调用,则不会报错。

1
2
3
window.onload=function(){
……
}

onbeforeunload表示离开页面之前触发的一个事件。

鼠标事件


onmouseover和onmouseout分别用于控制鼠标“移入”和“移出”这两种状态,如在下拉菜单导航中,鼠标移入会显示二级导航,鼠标移出则会收起二级导航。

在实际开发中,onmousedown、onmouseup和onmousemove经常配合实现拖拽、抛掷等效果

键盘事件

键盘按下:onkeydown。
键盘松开:onkeyup。

表单事件

onfocus表示获取焦点时触发的事件,而onblur表示失去焦点时触发的事件,两者是相反的操作。一般用于单行文本框和多行文本框。focus( )是一个方法,仅仅用于让元素获取焦点。而onfocus是一个属性,它是用于事件操作的。

当我们选中“单行文本框”或“多行文本框”中的内容时,就会触发onselect事件。select( )是一个方法,仅仅用于全选文本。而onselect是一个属性,它是用于事件操作的。

onchange事件常用于“具有多个选项的表单元素”的操作,选择某一项时触发。

选择下拉列表的某一项时,触发的是onchange事件,而不是onselect事件。onselect事件仅仅在选择文本框中的内容时才会触发

编辑事件

使用oncopy事件来防止页面内容被复制。

使用onselectstart事件来防止页面内容被选取。

使用oncontextmenu事件来禁止使用鼠标右键。

事件监听与处理

事件处理器通过操作HTML属性的方式来实现,如oBtn.onclick=function( ){……};事件处理器不能为一个元素添加多个相同事件。

事件监听器又称为“绑定事件”。可以为同一个元素添加多个相同的事件obj.addEventListener(type ,fn ,false)
type是一个字符串,指的是事件类型。如单击事件用click,鼠标移入用mouseover等。一定要注意,这个事件类型是不需要加上“on”前缀的。
fn是一个函数名,或是一个匿名函数。
false表示事件冒泡阶段调用。

解绑obj.removeEventListener(type ,fn ,false);
如果你想使用removeEventListener( )方法来解除一个事件,那么在使用addEventListener( )添加事件的时候,就一定要用定义函数(不能是匿名函数)的形式。

removeEventListener( )只可以解除“事件监听器”添加的事件,不可以解除“事件处理器”添加的事件。如果要解除“事件处理器”添加的事件,我们可以使用“obj.事件名 = null;”来实现

event对象

当一个事件发生的时候,这个事件有关的详细信息都会临时保存到一个指定的地方,这个地方就是event对象。

每次调用一个事件的时候,JavaScript都会默认给这个事件函数加上一个隐藏的参数,这个参数就是event对象。一般来说,event对象是作为事件函数的第1个参数传入的
其实e只是一个变量名,它存储的是一个event对象。也就是说,e可以换成其他名字,如ev、event、a等

使用event对象的type属性来获取事件的类型。

获取键盘中的键对应的键码,可以使用event对象的keyCode属性。e.keyCode返回的是一个数字,而e.shiftKey、e.ctrlKey、e.altKey返回的都是布尔值(true或false)

事件操作中的this

哪个DOM对象(元素节点)调用了this所在的函数,那么this指向的就是哪个DOM对象。

主要用在定义的事件被不同的元素调用时,可以方便地设置对应元素的属性值。其实这就是典型的闭包问题。

在事件函数中,如果想要使用当前的元素节点,我们应该尽量使用this来代替oBtn、oLi[i]等写法。

window对象

一个浏览器窗口就是一个window对象

window对象下面又分为很多对象。window对象及下面这些location、navigator等子对象,由于都是用于操作浏览器窗口的,所以我们又称之为“BOM”,也就是Browser Object Module(浏览器对象模型)。

window对象的常用方法


对于window对象,无论是它的属性,还是方法,都可以省略window前缀。

window.open(url,target)
url为空,则表示打开一个空白窗口。空白窗口很有用,我们可以使用document.write( )往空白窗口输出文本,甚至输出一个HTML页面。
target表示打开方式,它的取值跟a标签中target属性的取值是一样的,常用取值有两个:_blank(默认值)和_self。
实际上,window.open( )就像函数调用一样,会返回新窗口对应的window对象。
如果你打开的是同一个域名下的页面或空白窗口,就可以像上面那样操作新窗口的元素或样式;但是如果你打开的是另外一个域名下的页面,是不允许操作新窗口的内容的,因为涉及跨域的问题。

alert( )对话框一般只用于提示文字。
confirm( )对话框不仅提示文字,还提供确认。根据不同布尔值可以设置不同的操作。
prompt( )对话框不仅会提示文字,还会返回一个字符串。

setTimeout(code,time);
参数code可以是一段代码,可以是一个函数,也可以是一个函数名。
参数time是时间,单位为毫秒,表示要过多长时间才执行code中的代码。

定义一个变量timer,用于保存setTimeout( )这个定时器,以便使用clearTimeout(timer)来暂停。

setInterval( )跟setTimeout( )语法是一样的,唯一不同的是可以重复执行无数次。

为了避免重复点击开启多个定时器,最好在开始时清除一下。

document对象

document是浏览器为每个窗口内的HTML页面创建的对象。

document对象常用的属性

  • document.URL和window.location.href都可以获取当前页面的URL,但是它们也有区别:document.URL只能获取不能设置,window.location.href既可以获取也可以设置。
  • document.referrer 可以通过它来统计“用户都是通过什么方式来到你的网站的”。

document对象常用的方法

location对象

location对象的属性

地址“?”后面的这些内容,也叫作querystring(查询字符串),一般用于数据库查询。

井号(#)一般用于锚点链接

window.navigator.userAgent 获取浏览器的类型。