、DOM

JavaScript语言核心。变量的定义、变量的类型、运算符、表达式、函数、if语句、for循环、算法等等。这些东西都属于语言核心,下次继续学习语言核心就是面向对象了。JavaScript能做非常多的事情:DOM开发、Ajax开发、Canvas开发、NodeJS开发、前端框架(React、Vue、Angular等等)、HTML5开发。这些都需要语言核心的知识。

DOM开发说白了就是浏览器中的页面效果开发,在2011年之前,DOM开发占据了前端开发工程师的90%的工作;但是现在,DOM开发的工作比重已经降到了10%以下。换句话说,2011年之前,前端 = 做特效的;2011年之后,前端要负责得到后台的数据接口,用前端MVC逻辑分层开发前端组建、界面、功能,还要写HTML5,还要做canvas动画!

上层的框架屏蔽了下层的语言的一些麻烦、不方便的东西,并且提供更方便的API。

jQuery就是干这个事情的,把JS中的不方便封装起来,暴露的API都是非常简便的。

jQuery的哲学就是DOM编程领域的霸主,操作DOM节点、绑定监听、运动、css样式、Ajax等等都有封装。

工作上都是用jQuery,如果不用jQuery也是用类似的东西。没有人会不用轮子去开发页面效果。

JavaScript中Library表示“库”,如果这个库的功能很强大,甚至颠覆了传统编程的语法、行文习惯,我们就可以叫做“框架”。


1.1 DOM是什么

文档对象模型 (DOM,Document Object Model) 是 HTML 和 XML 文档的编程接口。它给文档(结构树)提供了一个结构化的表述并且定义了一种方式—程序可以对结构树进行访问,以改变文档的结构,样式和内容。 DOM 提供了一种表述形式— 将文档作为一个结构化的节点组以及包含属性和方法的对象。从本质上说,它将 web 页面和脚本或编程语言连接起来了

到底什么是DOM?就是你可以像操作对象一样操作HTML页面,而不是操作字符串。

DOM将 web 页面和脚本或编程语言连接起来了。

回看一下我们之前学习的DOM操作,都在干嘛?我们在开发特效,但是微观的看,实际上在进行:

1) 得到HTML节点

2) 改变节点的属性

3) 改变节点的样式

4) 修改节点、删除节点、增加节点

5) 节点之间的关系


1.2原生JavaScript得到节点

document.getElementById('box');

document.getElementsByTagName('p');

以上两是全线浏览器都兼容的得到元素方法。

以下这些得到元素的方法都不兼容IE678。

document.getElementsByName('aaa')[0]  //通过name属性得到元素们
document.getElementsByClassName('pp') //通过类名得到元素们
document.querySelector('#box');
document.querySelectorAll('#box p'); //通过选择器得到元素们

jQuery是DOM开发的王者!帮我们解决了元素选择的兼容问题。

jQuery底层很强大,比如$('.par1')机制不是getElementsByClassName(),而是在遍历所有节点,选择类名有par1的项。


二、原生JavaScript节点关系

在jQuery中学习parent()、children() 、siblings()、next()、prev()等等节点关系,JS中也有对应的属性。

原生JS提供的节点关系很少:

childNodes、firstChild、lastChild、parentNode、nextSibling、previousSibling

常见的nodeType值:

1-普通元素节点、比如div、p等等

2-属性节点

3-文本节点

8-注释节点

9-document节点

10-文档DTD

想要查看某一个元素的节点类型,直接读取它的nodeType属性即可。

改变nodeType为3的文本节点的内容,要改变他的nodeValue属性

2.1 childNodes儿子节点

childNodes在IE6、7、8和高级浏览器不一致,高级浏览器认为所有的换行为空文本节点,而IE678无视这个空文本节点。

div中没有文本节点,此时应该是4个节点,但是IE9、Chrome、火狐会认为有9个节点、IE8认为有4个节点。

高级浏览器会把空文本当做一个节点,标签前后的空文本也被算作一个。

注释的前后算不算空文本节点,各个浏览器有不同的解释。所以用节点的时候,一定要去过滤、判断节点的nodeType是不是1。

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

oBox.childNodes.length;  //Chrome数值9、IE678是4

为解决兼容性问题(到底空文本算不算儿子,所以要封装函数来解决):

可以利用nodeType是不是1来过滤文本节点、注释节点等,编写一个函数,得到一个标签真正的子节点。

jQuery也有这层过滤:

//封装一个children函数,这个函数能返回obj对象的所有真正儿子节点
function chidlren(obj,num){
var arr = []; //存储所有儿子
//遍历所有的节点
for(var i = 0; i < obj.childNodes.length;i++){
//遍历的过程,寻找真正的HTML儿子节点、过滤文本、注释等节点
//判断节点类型是不是1
if(obj.childNodes[i].nodeType == 1){
arr.push(obj.childNodes[i]); //如果是儿子节点就插入数组中
}
}
//return arr;
//返回的是:如果用户传入了num,返回某一个儿子,如果没有num,返回所有儿子
return num ? arr[num] : arr;
}
chidlren(oBox)[2].style.backgroundColor = 'red';
chidlren(oBox,3).style.backgroundColor = 'red';

2.2 parentNode父亲节点

parentNode属性表示父亲节点。任何节点的parentNode的nodeType一定是1,也就是说父亲节点一定是标签节点。文本节点、注释节点没有儿子。

var input = document.getElementsByTagName('input');
for(var i = 0;i < input.length;i++){
//当点击某个input时,如果自己被选中,此时改变父亲的颜色为绿色,否则为白色
input[i].onclick = function(){
if(this.checked){
this.parentNode.style.backgroundColor = 'green';
}else{
this.parentNode.style.backgroundColor = 'white';
}
}
}

2.3 previousSibling和nextSibling兄弟节点

上一个兄弟previousSibling、下一个兄弟nextSibling。同样的,文本节点也属于节点,注释也是节点,所以一个节点的上一个兄弟可能是文本、注释节点。原生JS中没有提供类似nextAll()、prevAll()、siblings()方法,如果节点没有上一个兄弟或下一个兄弟、返回null。

 

console.log(pp.previousSibling.nodeType)

console.log(pp.nextSibling.nodeType)

var pp = document.getElementById("pp");
//返回obj的前面一个兄弟
function prevSibling(obj){
//开始遍历obj节点的前面,直到遇见一个nodeType为1的节点
var prev = obj;
//循环遍历。注意while的条件是一个赋值语句!赋值语句也有表达式的
while(prev = prev.previousSibling){
if(prev.nodeType == 1){
return prev;
}
}
return null;
}
//得到真正的后面兄弟
function nextSibling(obj){
//开始遍历obj节点的前面,直到遇见一个nodeType为1的节点
var next = obj;
while(next = next.nextSibling){
if(next.nodeType == 1){
return next;
}
}
return null;
}
//返回obj的前面所有兄弟
function prevAll(obj){
//开始遍历obj节点的前面,直到遇见一个nodeType为1的节点
var prev = obj;
var arr = [];
while(prev = prev.previousSibling){
if(prev.nodeType == 1){
arr.push(prev);
}
}
return arr;
}
prevSibling(pp).style.background = "red";
nextSibling(pp).style.background = "green";
prevAll(pp)[1].style.background = "green";

三、原生JavaScript DOM节点操作

HTML节点我们原来最多就是改改HTML属性,比如改改src属性;或者改改css样式,比如.style或者.css()。

现在的问题是,我们要增加节点、删除节点、移动节点、替换节点。


3.1 createElement()创建和appendChild()添加

创建节点的方法: create创建,Element元素。接收一个参数,就是创建的标签是什么。

document.createElement()

追加节点的方法:创建出来的节点不在DOM树上,所以就应该用appendChild()来添加到DOM树上:

父亲.appendChild(新儿子);

var btn = document.getElementById('btn');
var txt = document.getElementById('txt');
var ul = document.getElementsByTagName('ul')[0];
btn.onclick = function(){
//创建一个li标签,用变量oLi 来表示,创建除了的节点不是任何节点的儿子(没有在DOM树上)
var oLi = document.createElement('li');
oLi.innerHTML = txt.value; //改变这个节点的内容
//把新创建的节点,追加到DOM树上
ul.appendChild(oLi);
}

appendChild()一般来说就是用来追加新创建的节点,如果试图把页面上已经有的节点,appendChild()到别的地方,那么这个节点将移动,也就是说,同一个节点不可能在页面上两个地方出现。

比如:

<div id="box1">
<p id="xiaoming">我是小明</p>
</div>
<div id="box2"> </div>
<script type="text/javascript">
var box2 = document.getElementById('box2');
var xiaoming = document.getElementById('xiaoming');
box2.appendChild(xiaoming);
</script>

以上将把xioaming移动到box2里面。

用innerHTML创建节点:

事实上,工作的时候很少用createElement。因为innerHTML足够好用,innerHTML也可以用来创建节点,甚至效率createElement还高。

var year = document.getElementById('year');
for(var i = 1950; i <= 2018;i++){
//创建节点
var op = document.createElement('option');
//改变创建出来的节点内容
op.innerHTML = i;
//上DOM树
year.appendChild(op); // 父亲.appendChild(新儿子);
}

innerHTML创建:

for(var i = 1950; i <= 2018; i++) {
year.innerHTML += '<option>'+i+'</option>';
}

JavaScript是动态变量:

var oBox = document.getElementById('box');
//得到box里面所有的p,现在box没有p,所以ops是一个空数组
var ops = oBox.getElementsByTagName('p');
var np = document.createElement('p'); //创建节点
oBox.appendChild(np); //追加节点
var np = document.createElement('p'); //创建节点
oBox.appendChild(np); //追加节点
var np = document.createElement('p'); //创建节点
oBox.appendChild(np); //追加节点
var np = document.createElement('p'); //创建节点
oBox.appendChild(np); //追加节点
var np = document.createElement('p'); //创建节点
oBox.appendChild(np); //追加节点
//这里弹出多少?初学者认为弹出0,因为先得到数组p,然后创建节点,节点又没有往数组里面push,所以应该ops数不变才对。
//但是JS中存储DOM节点的变量是动态,不是一个瞬时照片,而是一个有生命的动态对象,当oBox里面的p标签变化时,ps也变化
console.log(ops.length)

3.2 insertBefore()添加

appendChild是把新节点插入在父亲的所有子节点的后面,也就是说添加的节点就是父亲的最后一个儿子。

我们可以在任意一个位置添加子节点:会在原有标杆儿子之前插入

父亲.insertBefore(新儿子,原有标杆儿子)

var btn = document.getElementById('btn');
var txt = document.getElementById('txt');
var ul = document.getElementsByTagName('ul')[0];
var lis = document.getElementsByTagName('li');
btn.onclick = function(){
//创建一个li标签,用变量oLi 来表示,创建除了的节点不是任何节点的儿子(没有在DOM树上)
var oLi = document.createElement('li');
oLi.innerHTML = txt.value; //改变这个节点的内容
//把新创建的节点,追加到DOM树上
//在lis[0]的前面插入
ul.insertBefore(oLi,lis[0]);
}

如果想每次都在开头添加,那么就是:

ul.insertBefore(oLi,lis[0]);

lis这个变量是动态的,这次添加的li,下回就是lis[0]。


3.3 removeChild()删除

父亲.removeChild(儿子);
<ul>
<li>吃饭 <a href="###">删除</a></li>
<li>睡觉 <a href="###">删除</a></li>
<li>打豆豆 <a href="###">删除</a></li>
</ul>
<script type="text/javascript">
var ul = document.getElementsByTagName('ul')[0];
var lis = document.getElementsByTagName('li');
var as = document.getElementsByTagName('a'); for(var i = 0;i< as.length;i++){
as[i].onclick = function(){
ul.removeChild(this.parentNode); //如果要自杀,也要找到爸爸
//this.parentNode.removeChild(this);
}
}
</script>

如果要自杀,也要找到爸爸:

this.parentNode.removeChild(this);


3.4 replaceChild()替换

替换节点:

父亲.replaceChild(新儿子,旧儿子)

<div>
<p>赵丽颖</p>
<p id="xh">小黑</p>
<p>迪丽热巴</p>
</div>
<script type="text/javascript">
var oBox = document.getElementsByTagName('div')[0]
var xh = document.getElementById('xh'); //创建节点,孤儿节点
var op = document.createElement('p');
op.innerHTML = '朱老师'; //更改op的内容
oBox.replaceChild(op,xh);
</script>

3.5 clone()克隆

克隆节点,参数true表示深度克隆,节点里面的所有内容和事件一同复制。

复制之后的节点是个孤儿节点,所以也要使用appendChild()等方法来添加上DOM树。

克隆对象.cloneNode(true)

<div id="box1">
<ul>
<li><span>赵丽颖</span></li>
<li><span>迪丽热巴</span></li>
<li><span>柳岩</span></li>
<li><span>志玲姐姐</span></li>
</ul>
</div>
<div id="box2"> </div>
<script type="text/javascript">
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var ul = document.getElementsByTagName('ul')[0];
var lis = document.getElementsByTagName('li'); //克隆li和li的所有后代(要加true),然后追加到ul中
//ul.appendChild(lis[0].cloneNode()); //克隆第0个li
box2.appendChild(ul.cloneNode(true)); //克隆ul追加到box2中
</script>

四、事件监听

一堆理论知识正要来袭。

4.1事件流

我们考虑一个结构,三个div嵌套,点击最内层的div,我们点击了谁?仅仅点击了最内层div吗?不是就像手指放在到一个同心圆中,实际上手指触碰到了任何一个圆。

点击最内层的div,实际上浏览器会认为我们点击了所有的盒子,甚至于body、document、window。

 

为了描述事件的传播,人为规定了一个事件的传播方向,称为“事件流”。两个阶段:事件捕获阶段,事件冒泡阶段。

“事件流”描述的是页面上各个元素接收事件的顺序。


4.2 DOM0级事件监听

DOM分级别,DOM0级、1级、2级、3级,是不同的标准,标准一直在升级。

之前学习的on开头的语法添加事件,称为“DOM0级事件”。

事件的触发一定是按照事件流的顺序,由于DOM0级只能监听冒泡阶段,所以顺序是:box3→box2→box1→body→document→window 如果改变监听顺序,弹出顺序不变。

box1.onclick = function(){ alert('我是box1');}
box2.onclick = function(){ alert('我是box2');}
box3.onclick = function(){ alert('我是box3');}
document.body.onclick = function(){alert('我是body')}
document.onclick = function(){alert('我是document')}
window.onclick = function(){alert('我是window')}

这种监听写法,就是DOM0级,就是把onclick当做属性添加给了div元素。

这种事件添加方法,只能监听冒泡过程,不能监听事件捕获阶段。

 

DOM0级事件处理函数中,this指的是触发事件的DOM元素,就是事件传播到的这个元素。

DOM0级事件处理函数中,如果同一个对象,同一个事件名,绑定多个监听,后面写的覆盖前面写的。

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

box1.onclick = function(){ alert('我是box1,后面写的');}

DOM0级事件,IE6、7事件只能冒泡到document,IE8只能冒泡body,不能继续冒泡到window。也就是说不能给window对象添加事件。


4.3 DOM2级事件监听

DOM1级规范中,没有对事件进行改动,所以没有DOM1级的事情

DOM2级做了新的规范,不用on**来绑定监听了,而是用一个方法

W3C推出了addEventListener()函数,add添加、event事件,listener监听

它接收三个参数:事件,函数,是否监听捕获阶段

元素.addEventListener(事件,事件处理函数,是否添加到捕获阶段)

第一个参数:事件名不用谢on。(click、mouseover)

第二个参数:函数可以是匿名函数,也可以是有名函数

第三个参数:布尔值,true表示监听捕获,false表示监听冒泡阶段

box1.addEventListener('click',function(){
alert('我是box1的捕获阶段')
},true);

第三个参数是true,表示监听box1的捕获阶段的单击事件。

要记住true表示捕获,false冒泡阶段:口诀:true上,false下。

box1.addEventListener('click',function(){
alert('我是box1的捕获阶段')
},true);
box2.addEventListener('click',function(){
alert('我是box2的捕获阶段')
},true);
box3.addEventListener('click',function(){
alert('我是box3的捕获阶段')
},true);
box1.addEventListener('click',function(){
alert('我是box1的冒泡阶段')
},false);
box2.addEventListener('click',function(){
alert('我是box2的冒泡阶段')
},false);
box3.addEventListener('click',function(){
alert('我是box3的冒泡阶段')
},false);

box1的捕获→box2的捕获→box3的捕获→box3的冒泡→box2的冒泡→box1的冒泡

坑:最内层的box3,谁先写就谁先执行,也就是说对于最内层的box3,就不区分冒泡和捕获了,对于不少罪内层的元素来说,改变事件监听的顺序,不会影响执行结果,先捕获,后冒泡。

 

DOM2级事件中,如果给同一个元素,同一个事件名,同一个阶段添加多个事件监听,彼此不会覆盖,先写的先执行。

box1.addEventListener('click',function(){
alert('我是box1的冒泡阶段A')
},false);
box1.addEventListener('click',function(){
alert('我是box1的冒泡阶段B')
},false);
box1.addEventListener('click',function(){
alert('我是box1的冒泡阶段C')
},false);

弹出顺序是:A→B→C

DOM2级事件监听中,this指的是触发事件的这个元素,就是事件传播到的这个元素。


DOM2级小测试-看看执行顺序:正确答案在下篇文章。

小题目:页面box1最大,嵌套box2、box3,点击box3弹出顺序

box2.onclick = function(){
alert('A');
}
box2.onclick = function(){
alert('B');
}
box2.addEventListener('click',function(){
alert('C')
},false);
box2.addEventListener('click',function(){
alert('D')
},false);
box2.addEventListener('click',function(){
alert('E')
},true);
box2.addEventListener('click',function(){
alert('F')
},true);
box3.addEventListener('click',function(){
alert('G')
},false);
box3.onclick = function(){
alert('H')
}
box3.addEventListener('click',function(){
alert('I')
},true);

4.4低版本IE事件监听

IE6、7、8不支持addEventListener()方法,支持attachEvent()。

box1.attachEvent('onclick', function(){
alert(1)
});

第一个参数:必须写on,和addEventListener不一样

第二个参数:事件处理函数

没有第三个参数,不能自由选择添加到什么阶段,永远是冒泡阶段,也就是说IE678不能监听捕获阶段。

box1.attachEvent('onclick', function(){
alert('我是1a');
});
box1.attachEvent('onclick', function(){
alert('我是1c');
});
box1.attachEvent('onclick', function(){
alert('我是1b');
});
box2.attachEvent('onclick', function(){
alert('我是2');
});
box3.attachEvent('onclick', function(){
alert('我是3');
});

比较搞笑,如果给同一个元素添加多个事件名相同的监听,不互相覆盖,但是倒着执行,先执行后写:

box1.attachEvent('onclick', function(){
alert('我是a');
});
box1.attachEvent('onclick', function(){
alert('我是b');
});
box1.attachEvent('onclick', function(){
alert('我是c');
});

弹出c、b、a

最诡异是,this永远是window对象而不是事件传播到的元素。

box1.attachEvent('onclick', function(){
alert(this === window);
});

所以最正确的工作实践,就是用DOM0级事件监听方法,除非基于特别充分的理由,否则不用DOM2级。什么时候理由充分用DOM2级呢?比如一些新兴事件,如手机事件:touchstart、touchmove、touchend事件等等。只能用DOM2级。

上面学习的就是一些理论知识,总结一下:

事件流永远是先下(捕获)后(冒泡),但是不同监听方式,决定了监听那一部分。

面试意义大于实际意义!

jQuery中用的就是DOM2级,也有轮子,jQuery事件同名不会被覆盖。


4.5事件监听移除

DOM0级事件监听的移除很简单,直接把事件属性赋值给null即可。

var box1 = document.getElementById('box1');
box1.onclick = function(){
alert('你好,再次点击就没有效果了');
box1.onclick = null; //移除事件监听
}

DOM2级事件监听移除,必须指名道姓移除,也就是说,如果是匿名函数添加的事件监听,是不可能去掉的。

添加的时候要有名字:

box1.addEventListener('click',function fun(){
alert('你好');
box1.removeEventListener('click',fun,true);
},true);

点击按钮后,移除box1的事件监听:

btn.onclick = function(){
box1.removeEventListener('click',fun,true);
}

IE6、7、8用detachEvent即可,同样,也必须起名。

box1.attachEvent('onclick',fun)
function fun(){
alert('你好');
}
btn.onclick = function(){
box1.detachEvent('onclick',fun);
}

五、事件对象event

这里的知识就不是理论了 ,有实战价值。

5.1 event兼容性问题

在任何事件中,都有事件对象event。浏览器会往事件处理函数中,传入一个实参,就是事件对象,里面封装了你这次触发事件(点击、鼠标移入、移出、键盘按下)的细节。比如鼠标位置、是否按下某个键等等。

一般用变量event来接收,注意,不是必须的,名字可以改。

所有事件的细节,都被封装到event对象里面。

比如clinetX、clinetY就是这次鼠标点击的位置。

先说兼容性问题,IE678中,event这事件对象不是实参,而是全局变量,系统会在每一个事件发生的时候,都去改变这个全局变量的值:

box.onclick = function(){  //圆括号不能写event,如果写了,就遮蔽了全局的event
alert(event.clientX)
}

兼容写法:

box.onclick = function(event){
//因为在Chrome中event是实参,IE678events全局变量,所以用或的短路语法,它支持哪个用哪个
var event = event || window.event;
alert(event.clientX)
}

5.2事件对象属性

event.type      返回事件类型,没有on,比如“click”

event.target    返回你点击的最小哪个元素,即使这个元素身上没有监听,也返回它

event.currentTarget  返回自己,this一定和它是同一个元素,都是自己

event.bubbles     返回布尔值,表示这个事件是否冒泡

●bubbles属性,表示事件是否冒泡

box1.onmouseover = function(event){
var event = event || window.event;
console.log(event.bubbles); //表示是否冒泡
}

基本上所有事件这个属性都是true,表示这个事件冒泡,但是要记住:

onmouseover的event.bubbles是true,表示冒泡

onmouseout的event.bubbles是true,表示冒泡

onmouseenter的event.bubbles是false,表示不冒泡

有两个事件不冒泡:

onmouseenter和mouseleave的event.bubbles是false,不冒泡

onmouseenter和mouseleave这两个事件IE678910全面兼容!反而是Chrome30之前不兼容,但是现在可以当做全面兼容。它们两个事件是著名天生不冒泡的,当一个内部元素鼠标进入了,会执行这个元素的事件处理函数,但是事件捕获继续往外层传播。它的外层盒子不会触发onmouseenter事件。

box1.onmouseenter = function(event){
alert('鼠标进入了box1')
}
box2.onmouseenter = function(event){
alert('鼠标进入了box2')
}
box1.onmouseout = function(event){
alert('鼠标离开了box1')
}
box2.onmouseout = function(event){
alert('鼠标离开了box2')
}

onmouseenter和mouseleave比onmouseover和onmouseout好用

// $('#box').mouseenter(function(){
// $(this).children('.mask').slideDown();
// });
// $('#box').mouseleave(function(){
// $(this).children('.mask').slideUp();
// });
$('#box').mouseover(function(){
$(this).children('.mask').slideDown();
});
$('#box').mouseout(function(){
$(this).children('.mask').slideUp();
});

●target、srcElement属性,表示事件发生的最内层元素

chrome同时支持下面2个属性,IE只支持srcElement:

var target = event.target || event.srcElement;

用这个属性可以优化代码效率,可以制作“事件委托”把子元素的事件,委托给父亲,父亲通过event.target来判断是谁触发了事件。不使用事件委托,我们将会有很多事件监听;使用事件委托,事件监听只有1个。提升了页面的效率。

box1.onclick = function(event){
var event = event || window.event;
var target = event.target || event.srcElement;
alert(target.id)
}

事件委托:

比如,小圆点添加监听,不要给所有li,直接给ol,让ol的event.target这个元素有cur

<body>
<ol>
<li class="cur">0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
</body>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$('ol').mouseover(function(event){
var event = event || window.event;
//得到触发事件的最小元素
var target = event.target || event.srcElement;
//让触发事件的元素添加cur
$(target).addClass('cur').siblings().removeClass('cur');
});
</script>

当页面上有大量的重复元素要添加监听的时候,比如100/200个,一定要注意事件委托。

window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(123);
alert(target.innerHTML);
}
}
}

前端笔记之JavaScript(十)深入JavaScript节点&DOM&事件的更多相关文章

  1. JavaScript要点(十二) HTML DOM 事件

    HTML DOM 使 JavaScript 有能力对 HTML 事件做出反应. 对事件做出反应 我们可以在事件发生时执行 JavaScript,比如当用户在 HTML 元素上点击时. 如需在用户点击某 ...

  2. Web前端面试指导(二十):JavaScript中如何翻转一个字符串?

    题目点评 字符串作在程序中是非常常见的,因为程序中绝大部分的数据都可以当作字符串来处理.需要对字符的处理方法比较熟悉,在回答的时候尽量能够说出多种解决方法更好! 字符串翻转的方法 1)使用字符串函数 ...

  3. HTML5学习笔记(二十二):DOM

    DOM即文档对象模型(Document Object Model),其定义了访问和操作 HTML 文档的标准方法. DOM 将 HTML 文档表达为树结构,如下: 通过DOM,开发人员可以动态的添加. ...

  4. HTML5学习笔记(二十四):DOM扩展

    DOM扩展 DOM标准扩展最开始都是来自各个浏览器的自定义扩展DOM的功能,后被收录为标准的DOM相关API. 本笔记只记录被各大浏览器支持的标准扩展,对于特定浏览器的专有扩展不讨论. 选择符API ...

  5. 前端笔记知识点整合之JavaScript(一)初识JavaScript

    一.JavaScript简介 1.1网页分层 web前端一共分三层: 结构层 HTML         : 负责搭建页面结构 样式层 CSS          : 负责页面的美观 行为层 JavaSc ...

  6. 前端笔记之JavaScript(一)初识JavaScript

    一.JavaScript简介 1.1网页分层 web前端一共分三层: 结构层 HTML         : 负责搭建页面结构 样式层 CSS          : 负责页面的美观 行为层 JavaSc ...

  7. 前端笔记知识点整合之JavaScript(三)关于条件判断语句、循环语句那点事

      一.条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句. JS中有三种语法是可以表示条件分支的 1.1 if……else…… 条件分支的主力语法,这个主力 ...

  8. JavaScript权威设计--JavaScript函数(简要学习笔记十)

    1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"lik ...

  9. 前端笔记之JavaScript面向对象(一)Object&函数上下文&构造函数&原型链

    一.对象(Object) 1.1 认识对象 对象在JS中狭义对象.广义对象两种. 广义:相当于宏观概念,是狭义内容的升华,高度的提升,范围的拓展.狭义:相当于微观概念,什么是“狭”?因为内容狭隘具体, ...

随机推荐

  1. 展开被 SpringBoot 玩的日子 《 四 》 Session 会话共享

    共享Session-spring-session-data-redis 分布式系统中,sessiong共享有很多的解决方案,其中托管到缓存中应该是最常用的方案之一. Spring Session官方说 ...

  2. 【C语言编程练习】5.9 爱因斯坦的阶梯问题

    1. 题目要求 有一个长阶梯,每2步上,最后剩1个台阶,若每3步上,最后剩2个台阶.若每5步上,最后剩4个台阶,若每6步上,最后剩5个台阶.只有每步上7阶,才可以刚好走完,请问台阶至少有多少阶? 2. ...

  3. 巨坑npm run dev 报错 终于找到正确答案 Error: EPERM: operation not permitted, open '/data/public/build/css/add.p

    Windows10环境 npm run dev 报错  终于找到正确答案 Error: EPERM: operation not permitted, open '/data/public/build ...

  4. Spring Cloud微服务笔记(五)Feign

    Feign 一.Feign概述 Feign是一个声明式的Web Service客户端.在Spring Cloud 中使用Feign,可以做到 使用HTTP请求访问远程服务,就像调用本地方法一样,同时它 ...

  5. Jenkins pipeline job 根据参数动态获取触发事件的分支

    此文需要有Jenkins pipeline job 的简单使用经验 场景 我们日常的测试函数, 一般是不能仅仅在本地跑的,还需要一个公共的跑测试的环境,作为合并新的PR的依据. 如果用Jenkins ...

  6. docker pull 镜像报错

    [root@localhost ~]# docker pull ningx Using default tag: latest Trying to pull repository docker.io/ ...

  7. java DTO对象与PO对象的相互转换

    2018-09-27 10:27:50 前言: 在实际开发中往往需要DTO对象与PO对象的相互转换: 先说说什么是DTO对象吧,个人觉得DTO就是PO的扩展而已,PO专门指向数据库,DTO作扩展(字段 ...

  8. Spring Cloud 组件 —— feign

    feign 作为一个声明式的 Http Client 开源项目.在微服务领域,相比于传统的 apache httpclient 与在 spring 中较为活跃的 RestTemplate 更面向服务化 ...

  9. linux-Vim命令合集

    Vim命令合集 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filena ...

  10. aarch64的架构:unrecognized command line option '-mfpu=neon'

    不用添加这个'-mfpu=neon'的编译器选项了,因为这个架构下neon是默认启动的. 参考: https://lists.linaro.org/pipermail/linaro-toolchain ...