一、昨日反馈
1、数据类型转换
a)转换成字符串
i.使用 变量.toString();
//不能转换undefined和null
ii.使用String(变量);
//能转换所有的数据类型
iii.其他类型的变量和字符串相加(连)操作的时候,会把其他类型的变量通过String自动转换成字符串,然后在完成连接操作
b)转换成数值型
i.parseInt(变量);
检查字符0处的字符是否是数字,如果是继续向后检查,直到发现一个非数字为止,然后将前面的数字部分转换成整型;如果发现0处的字符不是数字,则转换成NaN。
ii.parseFloat(变量);
转换成浮点型,规则和parseInt一样,只不过parseFloat允许有一个小数点。
iii.强制转换Number(变量);
false=0; true=1; undefined=NaN; null=0;
c)转换成布尔型
i.下面的值转换成浮点型之后为false:""、0、 0.0、 undefined、 null、NaN。
ii.除了上面列举的值,其他值转换成布尔都是true,包括"0", [], {};
2、流程控制
a)顺序结构
b)分支结构
c)循环结构:
可以给循环起一个名字,比如( a:for(…)…)for循环中,前面的a就表示它的名字,用于break等指定循环使用
3、函数基础
i.常规的方式:function 函数名(){} //可以先调用,后声明
ii.表达式方式:var 函数名 = function(){}; //只能先定义,后使用
iii.立即调用模式: ( function(){} ) (); //红色的小括号必须的,表示里面声明的函数是一个整体;绿色的小括号表示调用函数。
4、作用域
a)分类:
全局作用域和局部(函数)作用域
b)作用域规则
i.函数可以使用函数之外定义的变量
ii.函数内部优先使用内部的变量,如果内部没有,才去函数外部查找。(注意变量提升)
iii.函数内部没有用var声明的变量,也是全局变量。
5、变量提升和函数预加载
a)变量提升
i.如果在声明变量之前,就使用了一个变量。这种情况不会报错,它实际执行的过程是把声明变量的过程提升到使用之前,注意的是只是把声明变量的过程提升到使用之前,并没有把变量的赋值过程提升。
b)函数预加载
i.函数声明必须是常规方式( function 函数名(){} )
ii.函数的调用和声明必须在同一个script标签中
二、今日目标
1、理解什么是DOM,它的作用是什么
2、能够通过多种方式查询页面中的元素
3、能够对页面中的元素进行增删改克隆操作
4、能够设置或获取元素的css样式
5、能够通过dom节点为元素绑定事件
6、能够获取兼容各个浏览器的事件对象
7、能够通过事件对象获取当前的keyCode
三、DOM介绍
1、什么是DOM
DOM全称是Document Object Model(文档对象模型),它是JS将HTML按文档结构和内容层次抽象出的模型,使得JavaScript有了访问HTML的能力,能够实现对HTML中内容的操作。DOM存在广泛,PHP以及其他语言也有各自的DOM模型。
2、节点与DOM模型
DOM模型呈现树状结构,因此也叫“树模型”,树中的内容(标签、属性、文本)称为“节点”,节点在dom中就是对象。包含有元素节点(标签)、属性节点、文本节点。dom模型中,每个节点,都是一个JavaScript对象。
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
1、整个文档是一个文档节点,用document对象表示,最大的节点
2、每个 HTML 元素是元素节点,比如html、head、body、a、h1
3、HTML 元素内的文本是文本节点
4、每个 HTML 属性是属性节点,比如href
5、注释是注释节点
3、节点之间的关系
节点之间的关系犹如人类家族中的族谱。
节点之间的关系包括:
父子关系(父子、后代、祖先级)
兄弟(姐妹)关系
单词:
parent — 父母
child — 孩子
children — 孩子(复数),表示所有孩子
siblings — 兄弟姐妹、同胞
四、元素(标签)节点查询操作
document是JS内置的一个对象,表示整个HTML文档。根据document查询,意思就是在整个文档范围内查询。
单词:
get -- 获取、得到
Element -- 元素
Elements -- 很多元素
By… -- 根据…./通过….
Class -- 类
Tag -- 标签
query -- 查询
Selector -- 选择器
练习:
getElementById() -- 根据元素的id值获取一个元素类型的节点 返回值是一个dom对象
getElementsByTagName() -- 通过标签名获取很多个元素类型的节点 返回一个包含很多dom对象的数组
具体查询方法见下表:
<ul>
<li class="a">李清照</li>
<li id="tangwei">汤唯</li>
<li class="a">唐婉</li>
<li>王昭君</li>
</ul>
<p class="a">上述内容是美女型诗人。</p>
<br>
请输入更多诗人: <input type="text" name="shiren" />
<script>
/****************** script标签一定要放到ul/p/input标签下面 *******************/
//------------------------根据id查询
var tangwei = document.getElementById('tangwei');
//console.log(tangwei); 输出; <li id="tangwei">汤唯</li>
//tangwei.style.样式名称 = 值; 给标签添加样式
tangwei.style.color = 'red';
//-----------------------根据标签名查询
var lis = document.getElementsByTagName('li'); // 返回数组,数组中包含满足条件的4个li
//console.log(lis);
for(var i=0; i<lis.length; i++){
lis[i].style.backgroundColor = '#ccffcc';
}
//---------------------根据元素的类名查询
var as = document.getElementsByClassName('a'); // 返回数组,数组中包含类名为a的元素
for(var i=0; i<as.length; i++){
as[i].style.fontSize = '30px';
}
//---------------------根据元素的name属性查询
var input = document.getElementsByName('shiren'); // 返回数组,数组中包含属性name为shiren的元素
input[0].style.backgroundColor = '#ccc';
//--------------------根据css选择器选择元素
//document.querySelector('css选择器');
var liqingzhao = document.querySelector('.a'); // 返回一个dom对象,class为a的有很多,也只返回第一个
liqingzhao.style.border = 'solid 1px pink';
var all = document.querySelectorAll('p, input'); //返回数组
for(var i in all){
all[i].style.border = 'dashed 1px blue';
}
</script>
2、相互关系查询
相互关系查询可以分为下面三种情况:
根据父节点查找子节点
根据子节点查父节点
查询兄弟节点
单词:
child -- 孩子
children -- 很多孩子
Node -- 节点
nodes -- 很多节点
first -- 第一个
last -- 最后一个
Element -- 元素
Sibling -- 兄弟,姐妹
Siblings -- 所有的兄弟,姐妹
previous -- 上一个
next -- 下一个
具体属性/方法见下表:
演示:
<ul id="u">
<li>泽拉斯</li>
<li>蚂蚱</li>
<li>拉克丝</li>
<li>安妮</li>
<li>维克托</li>
</ul>
/** 根据父节点查找子节点 **/
//先找到父节点
//var ul = document.getElementsByTagName('ul')[0];
//var ul = document.getElementById('u');
//var ul = document.querySelector('ul');
var ul = document.querySelector('#u');
查询所有ul的子节点
// --- 查询所有ul的子节点 -- children
var lis = ul.children; // 返回数组。 查询ul的所有子节点
console.log(lis);
// -- 查询所有ul的子节点 -- childNodes
var lis = ul.childNodes; //
console.log(lis);
包含 li 前后的空白
避免:可以把源代码前后的空白都删掉
//---------------查询所有ul的子节点 ---
var lis = ul.getElementsByTagName('li'); //在ul中查找所有ul后代中的li
console.log(lis);
查询ul的第一个子节点
//-- 查询ul的第一个子节点 --- firstChild
var li1 = ul.firstChild;
console.log(li1); //不好用,会把第一个空白当做第一个子元素
//-- 查询ul的第一个子节点 --- firstElementChild
var li1 = ul.firstElementChild;
console.log(li1); //好用,但是IE8+才支持
//--- 查询ul的最后一个子节点 --- lastChild
//-- 查询ul的最后一个子节点 --- lastElementChild
根据子点查找父节点
/** 根据子点查找父节点 **/
//随便找一个子节点
var mazha = document.getElementsByTagName('li')[1];
var ul2 = mazha.parentNode;
console.log(ul2);
兄弟关系查询
/** 兄弟关系查询 **/
//随便找一个子节点
var mazha = document.getElementsByTagName('li')[1];
//查询上一个兄弟
var zelasi = mazha.previousSibling;
console.log(zelasi); // #text 不好使,会认为空白是上一个兄弟
var zelasi = mazha.previousElementSibling;
console.log(zelasi); // <li>泽拉斯</li> 好使,但是IE8+支持
//查询下一个兄弟 -- nextSibling
//查询下一个兄弟 -- nextElementSibling
3、遗留DOM
早期DOM访问形式,在一些特定元素的获取上比较方便。被保留下来使用,W3C标准化之后 称为“0级DOM”。
<form name="f1">
用户名:<input type="text" name="username" value="123"><br>
密码:<input type="password" name="pwd" value="123">
</form>
<form name="f2">
邮箱:<input type="text" name="email" value="123"><br>
电话:<input type="password" name="tel" value="123">
</form>
//获取body节点
var body = document.body;
body.style.backgroundColor = '#ccc';
//获取form
document.forms[1].style.border = 'solid 1px red';
//获取form,通过name值
document.f1.style.border = 'solid 1px blue';
//找表单中各个项,通过name值
document.f1.username.style.backgroundColor = 'yellow';
五、元素(标签)节点增删改操作
1、创建、增加节点
方法一:父节点.appendChild(子节点);
<ul>
<li>林青霞</li>
<li>张曼玉</li>
<li>刘欢</li>
<li>陈冠希</li>
</ul>
<script>
/** createElement/createTextNode/appendChild **/
//创建一个 <li>谢霆锋</li>
//创建元素类型的节点
var li = document.createElement('li');
//创建文本类型的节点
var text = document.createTextNode('谢霆锋');
//添加节点,将文本节点添加到元素节点中
li.appendChild(text); // 得到<li>谢霆锋</li>
//添加节点,将组合好的li,添加到ul中
document.querySelector('ul').appendChild(li);
</script>
方法二:父节点.insertBefore(新节点, 参照的节点);
/** insertBefore **/
//创建一个 <li>渣渣辉</li>
var newLi = document.createElement('li');
var newText = document.createTextNode('渣渣辉');
newLi.appendChild(newText); //得到 <li>渣渣辉</li>
//找到参照的张曼玉所在的li
var zhangmanyu = document.getElementsByTagName('li')[1];
//找到li的父节点
var ul = document.querySelector('ul');
//父节点.insertBefore(新节点, 参照的节点);
ul.insertBefore(newLi, zhangmanyu);
2、克隆节点
原来的节点.cloneNode([true]);
<ul class="a" style="color:red;">
<li>鲁智深</li>
<li>张飞</li>
<li>猪八戒</li>
<li>李逵</li>
</ul>
<script>
//克隆一份ul,然后放到页面中
//先找到要克隆的ul
var oldUl = document.querySelector('ul');
//克隆一个新的ul
//var newUl = oldUl.cloneNode(); //只克隆ul标签本身,不包含里面的内容
var newUl = oldUl.cloneNode(true); //克隆ul标签并包含里面的内容
//把新的ul放到body中
document.body.appendChild(newUl);
</script>
3、替换节点
父节点.replaceChild(新节点, 待替换的节点);
<ul>
<li>林黛玉</li>
<li>贾宝玉</li>
<li>薛宝钗</li>
<li>刘姥姥</li>
</ul>
<script>
// 父节点.replaceChild(新节点, 待替换的节点);
//找父节点 getElementsByTagName返回的是数组,所以需要添加下标
var ul = document.getElementsByTagName('ul')[0];
//新节点
var newLi = document.createElement('li');
var text = document.createTextNode('王熙凤');
newLi.appendChild(text);
//找到待替换的节点
var jiabaoyu = document.getElementsByTagName('li')[1];
//执行替换
ul.replaceChild(newLi, jiabaoyu);
</script>
4、删除节点
父节点.removeChild(子节点);
<ul>
<li>林黛玉</li>
<li>贾宝玉</li>
<li>薛宝钗</li>
<li>刘姥姥</li>
</ul>
/** 删除节点 **/
//父节点.removeChild(子节点);
var ul = document.querySelector('ul');
var xiaoLiu = document.getElementsByTagName('li')[3];
ul.removeChild(xiaoLiu);
六、设置/获取元素的css样式
1、设置css样式
elementNode.style.css样式 = 值
css样式的写法:
①、一个单词的直接写即可。比如color height …
②、样式名称带中横线的,去掉中横线,后面单词首字母大写。比如fontSize lineHeight backgroundColor
2、获取css样式
使用 “node.style.样式名称” 的方式只能获取行内样式和js已经设置过的样式。
要想获取全部的样式,则必须使用下面的方法:
在IE中支持node.currentStyle.样式名称
火狐支持getComputedStyle(node).样式
node.style.样式名称 只能获取行内样式和js已经设置过的样式。
<p>nice to meet you!</p>
<script>
//设置p元素的css样式,color是红色,背景颜色是金色。
var p = document.getElementsByTagName('p')[0];
p.style.color = 'red';
p.style.backgroundColor = 'gold';
/** 获取元素的css样式 **/
//只能获取行内样式和js已经设置过的样式
var c = p.style.color;
console.log(c);
var f = p.style.fontSize;
console.log(f);
</script>
获取完整样式的写法
//获取完整样式的写法(非IE)
var f = getComputedStyle(p).fontSize;
console.log(f);
//获取完整样式的写法(IE8)
var f = p.currentStyle.fontSize;
console.log(f);
为了兼容各个浏览器,所以需要自己封装一个函数,用于获取完整的css样式:
//兼容各个浏览器的获取完整css样式的写法
function getStyle(node, styleName){
if(node.currentStyle){
//说明是IE
return node.currentStyle[styleName];
}else{
return getComputedStyle(node)[styleName];
}
}
console.log(getStyle(p, 'fontSize'));
七、事件和事件对象
1、什么是事件
浏览网页时,当我们做出点击鼠标、按键盘、移动鼠标等行为时,这些行为会被浏览器内置的JavaScript引擎所捕获,并执行对应的某些操作(函数)。
那么你的行为(动作)+ JavaScript引擎捕获 + 执行对应的操作 = 事件。
所以,一个完整的事件应该包括:
用户行为;
浏览器捕获你的行为;
执行对应的操作(函数)
常见行为有:鼠标点击、鼠标的移动、鼠标的移入和移出、键盘控制等等。
事件的作用是:通过事件,我们(浏览网页的人)就可以和浏览器进行一些交互了。
2、事件绑定方式
node.事件名 = function(){
//事件被触发时,执行这个函数。
};
//例如
document.getElementById('btn').onclick = function(){
console.log('你点击我了');
}
<input type="button" value="点我试试" id="btn" />
<input type="text" id="username" value="请输入用户名" />
<script>
//找到要绑定事件的元素节点
var btn = document.getElementById('btn');
//单击事件
btn.onclick = function(){
alert('你真敢点');
};
//找到username,绑定获取焦点事件
document.getElementById('username').onfocus = function () {
document.getElementById('username').value = '';
};
</script>
在事件处理函数中,this表示绑定事件的那个元素:
所以上面获得焦点的事件可以优化代码为:
练习:
页面中有很多个td,点击td的时候,让td的背景颜色发生变化:
<table>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
table,td{
border:solid 1px #ccc;
border-collapse: collapse; /*合并边框*/
}
td{
width:150px;
height:50px;
/*color:rgb(30,50,10);*/
}
table{
margin:10px auto; /*让表格左右居中对齐*/
}
//点击页面中的td,点击之后,让被点击的td背景颜色改变成红色
//先找到所有的td
var tds = document.getElementsByTagName('td'); // 返回数组
//循环,为每个td都绑定一个单击事件
for(var i=0; i<tds.length; i++){
tds[i].onclick = function () {
//alert(123);
//this 表示绑定事件的那个td
//Math.random() 返回0-1之间的随机数
var r = Math.floor(Math.random()*256);//返回0~255之间的随机数
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
this.style.backgroundColor = 'rgb('+r+', '+g+', '+b+')';
//判断如果是红色,就变成白色
/*if(this.style.backgroundColor != 'red'){
this.style.backgroundColor = 'red';
}else{
this.style.backgroundColor = 'white';
}*/
};
}
3、常用事件列举
页面事件:
onload :当页面载入完毕(页面中的标签和外部资源)后触发
焦点事件
oonfocus :当获取焦点时触发
oonblur :当失去焦点时触发
鼠标事件
onmouseover :当鼠标悬浮时触发
onmouseout :当鼠标离开时触发
键盘事件
oonkeypress :当键盘按下时触发(如果按住某个键不松开,会一直触发press事件)
oonkeydown :当键盘按下时触发
oonkeyup :当键盘弹起时触发
其他事件
onchange :内容改变时会触发,常用于select>option。
onsubmit :表单提交时触发,这个事件要给form绑定而不是给提交按钮绑定
onresize : 页面窗口改变大小时会触发
onscroll :滚动条滚动时触发
4、什么是事件对象
事件对象也是一个对象,它提供了一些属性,这些属性描述了当前事件的特点;
不同的事件中,事件对象也有所差异,比如单击事件中,事件对象会提供pageX和pageY属性,表示点击的点距离页面的距离,比如键盘事件中,事件对象会提供keyCode属性,表示按的是什么键。
总之,事件对象中提供了一些属性,这些属性可以很好的描述当前的事件的特点。
5、获取事件对象
IE浏览器:window.event;
火狐浏览器:传递给事件处理函数的形参
下面代码演示获取事件对象的方式:
<input type="text">
<script>
document.getElementsByTagName('input')[0].onclick = function(a){
//console.log(a); // IE8+ 支持,获取事件对象的方法
//console.log(window.event); // IE8浏览器
//兼容各个浏览器的获取事件对象的方法
/*var e;
if(window.event){
e = window.event; //IE8
}else{
e = a; // IE8+
}*/
var e = window.event||a;
};
</script>
兼容各个浏览器的获取事件对象的方法
var e = window.event||a;
6、事件对象常用属性
下面列举一些事件对象中的常用属性:
keyCode:表示键盘上的键对应的数值。
altKey:表示是否按了alt键,按了结果为true,没按结果为false(组合按键的时候,才会有作用)
shiftKey:表示是否按了shift键,按了结果为true,没按结果为false(组合按键的时候,才会有作用)
ctrlKey:表示是否按了ctrl键,按了结果为true,没按结果为false(组合按键的时候,才会有作用)
pageX: 鼠标距离页面左边的距离
pageY: 鼠标距离页面上面的距离
screenX: 鼠标距离屏幕左边的距离
screenY: 鼠标距离屏幕上面的距离
下面的代码是获取keyCode的代码:
//在页面中任何位置,按键,当键盘弹起的时候,执行函数
document.onkeyup = function(evt){
//先获取事件对象
var e = window.event||evt; //兼容各个浏览器的获取事件对象的方式
//获取键盘对应的数字
var keyCode = e.keyCode;
//alert(keyCode);
if(keyCode == 13){
alert('您按了回车键');
}
}