Topic 1 : 动态创建元素的三种方法 :
1 . document.write()
2 .innerHTML
3 .document.createElement();
建议使用第三种方法,因为第三种方法好操作,生成的都是对象;
我们看三种方法的比较:
1. 中间的但是跟最快的比较接近点
<script>
function fn() {
var d1 = +new Date();
for ( var i = 0; i < 1000; i++ ) {
var div = document.createElement('div');
div.style.width = '100px';
div.style.height = '2px';
div.style.border = '1px solid red';
document.body.appendChild( div );
}
var d2 = +new Date();
console.log( d2 - d1 );
}
fn();
</script>
2. 最快
<script>
function fn() {
console.time('flag');
var array = [];
for ( var i = 0; i < 1000; i++ ) {
array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
}
document.body.innerHTML = array.join('');
var d2 = +new Date();
console.timeEnd('flag');
}
fn();
</script>
3. 最慢
<script>
// console.log(Date.now());
function fn() {
// 获取日期的毫秒形式
var d1 = +new Date();
var array = [];
var str = '';
for ( var i = 0; i < 1000; i++ ) {
document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
}
var d2 = +new Date();
console.log( d2 - d1 );
}
fn();
</script>
注意 :
这里有两个打印时间间隔的方法:
1.
var d1 = +new Date();
var d2 = +new Date();
console.log( d2 - d1 );
2.
console.time('flag');
console.timeEnd('flag');
Topic 2 : 节点操作 :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>节点操作</title>
</head>
<body>
<ul id="ul">
<li>第一个li</li>
<li>第二个li</li>
<li>第三个li</li>
<li>第四个li</li>
<li>第五个li</li>
</ul>
<script>
//节点的操作
// 1 . 在节点的最后追加
var ul = document.getElementById('ul');
var li = document.createElement('li');
// 注意这里我们要是还用第一步使用的那个li那么我们第一步的操作就会被覆盖
li.innerHTML = '我是在结尾追加的li'
ul.appendChild(li);
// 2. 在节点的任意元素前添加
var li1 = document.createElement('li');
li1.innerHTML = '我是在第五个li之前追加的li'
ul.insertBefore(li1,ul.children[4]);
// 3. 替换节点的某一个操作
var li2 = document.createElement('li');
li2.innerHTML = '我是替换第四个li的li'
ul.replaceChild(li2,ul.children[3]);
// 4. 删除
// 删除一个li
ul.removeChild(ul.children[0]);
// 5. 全部删除
// 我们要删除ul里面所有的内容
// 5.1 简单的方法 就是设置他的innerHTML为空 但是这个方法有一个小问题
// 问题就是我们的这个方法没有办法清空事件 要是ul里面有事件的话我们就不能使用这个删除了
// ul.innerHTML = '';
// 5.2 我们就使用循环遍历删除就可以 但是呢我们这个地方要注意我们的数组做了删除操作 他的索引会重新排列的问题
// 就是如果我们删除了数组的第一个话 那么数组就会把第二个变为索引为0的那个元祖
// 所以我们要解决这个问题的话那么我们可以从后往前删除 或者只删除数组索引为0的那个
var i,len = ul.children.length;
// 因为他是一个集合所以没有forEach方法 s所以我们只能在这里用for就ok了 注意我们这里是len-1
for(i = len-1; i >= 0; i-- ) {
ul.removeChild(ul.children[i]);
}
</script>
</body>
</html>
Topic 3 : 选水果游戏
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>权限选择</title>
<style type="text/css">
select {
width: 200px;
height: 200px;
background-color: aqua;
}
</style>
</head>
<body>
<select id="select1" multiple="multiple">
<option>西瓜</option>
<option>苹果</option>
<option>香蕉</option>
<option>橘子</option>
</select>
<input type="button" value=">>" id="button1">
<input type="button" value="<<" id="button2">
<input type="button" value=">" id="button3">
<input type="button" value="<" id="button4">
<select id="select2" multiple="multiple">
</select>
<script>
var select1 = document.getElementById('select1');
var select2 = document.getElementById('select2');
var button1 = document.getElementById('button1');
var button2 = document.getElementById('button2');
var button3 = document.getElementById('button3');
var button4 = document.getElementById('button4');
var i,len = select1.children.length;
// 1. 全选
button1.onclick = function () {
for (i = 0; i < len; i++) {
// 注意这个地方我们一直移动的都是children【0】 因为重新排列问题
select2.appendChild(select1.children[0]);
}
}
// 2. 全不选
button2.onclick = function () {
for (i = 0; i < len; i++) {
// 注意这个地方我们一直移动的都是children【0】 因为重新排列问题
select1.appendChild(select2.children[0]);
}
}
// 3. 移动选中的项
button3.onclick = function () {
for (i = 0; i < len; i++) {
var li = select1.children[i];
if ( li.selected ) {
select2.appendChild(li);
// 注意这一步非常容易犯错 因为本来就移走了一个 索引会重新排列所以我们的i要减一从我们本身开始
// 看看这个移动过来的是不是一个被选中的
i--;
}
}
}
// 4. 移动回来选中的项
button4.onclick = function () {
for (i = 0; i < len; i++) {
var li = select2.children[i];
if ( li.selected ) {
select1.appendChild(li);
// 注意这一步非常容易犯错 因为本来就移走了一个 索引会重新排列所以我们的i要减一从我们本身开始
// 看看这个移动过来的是不是一个被选中的
i--;
}
}
}
</script>
</body>
</html>
这段代码的核心是: 重新排列和 li.selected 这个条件
Topic 4 :注册事件
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>注册事件</title>
</head>
<body>
<div id="box">
</div>
<input type="button" value="按钮" id="btn">
<script src="../js/common.js"></script>
<!-- <script src="../js/table.js"></script>-->
<script>
var btn = document.getElementById('btn');
//
// 好处: 可以给同一个元素注册多个事件处理函数
//
// add 添加 Event 事件 Listener 监听者(事件处理函数) IE9以后才支持
// 第一个参数 事件名称 不带on
// 第二个参数 事件处理函数
// 第三个参数 事件冒泡/事件捕获 false是冒泡 true是捕获;
// btn.addEventListener('click', function () {
// // alert('abc');
// alert(this); // 触发事件的对象
// }, false);
//
// btn.addEventListener('click', function () {
// // alert('hello');
// alert(this);
// }, false);
// // IE9以前 老版本的IE
// btn.attachEvent('onclick', function () {
// alert('123');
// // attachEvent 事件处理函数中的this 指向window
// });
// 我们经过兼容性处理的函数
addEventListener(btn, 'click', function () {
alert(this);
});
// 测试我们新创建的table.js是否可以用
// var box = document.getElementById('box');
// var body = [
// {name: 'wang', hobby: 'aha'},
// ];
// var head = [
// '名字','爱好'
// ]
// createTable(box,head,body);
</script>
</body>
</html>
Topic 5 : 移除事件
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>移除事件</title>
</head>
<body>
<input type="button" value="按钮" id="btn">
<script src="../js/common.js"></script>
<script>
// 移除事件 方法一:
var btn = document.getElementById('btn');
// btn.onclick = function () {
// alert('hello');
// // 这一句话的作用就是这个按钮的功能只执行一次
// this.onclick = null;
//
// }
// 移除事件 方法二:
// 想要移除事件不能使用匿名函数
// 因为要是我们不写函数的名称的话 我们移除的时候需要用到就没法移除 除非使用上一种方法
// btn.addEventListener('click', function () {
// alert('hello');
// // 移除事件
// // 第一个参数 事件名称
// // 第二个参数 事件处理函数
// // 第三个参数 事件捕获/事件冒泡
// btn.removeEventListener('click', );
//
// }, false);
// btn.addEventListener('click', btnClick, false);
// function btnClick() {
// alert('hello');
// // 移除事件 也是执行一次后不执行了
// this.removeEventListener('click', btnClick, false);
// }
// // IE的老版本
// //我们同样对他进行兼容性的处理
// btn.attachEvent('onclick', btnClick);
// function btnClick() {
// alert('hello');
// // 移除事件
// btn.detachEvent('onclick', btnClick);
// }
MyAddEventListener(btn,'click', btnClick);
function btnClick() {
alert('hello');
// 移除事件 也是执行一次后不执行了
MyRemoveEventListener(btn,'click', btnClick);
}
</script>
</body>
</html>
Topic 6 : 事件冒泡捕获
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
<style>
#box1 {
width: 300px;
height: 300px;
background-color: red;
}
#box2 {
width: 200px;
height: 200px;
background-color: blue;
}
#box3 {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
<script>
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');
var array = [box1, box2, box3, document.body, document];
array.forEach(function (item) {
// item.onclick = function () {
// console.log(this);
// }
// 第三个参数 true 事件捕获 false 事件冒泡
item.addEventListener('click', function () {
console.log(this);
}, true);
})
// 事件的三个阶段 / 事件流
// 1 事件捕获阶段
// 2 目标阶段
// 3 冒泡阶段
</script>
</body>
</html>
Topic 7 : 事件委托与事件对象中e.type的用处
事件委托:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>事件委托</title>
</head>
<body>
<ul id="ul">
<li>西施</li>
<li>貂蝉</li>
<li>贵妃</li>
<li>葛文</li>
</ul>
<script>
// 事件委托,把本来应该li应该做的事情,转交给父元素来做(事件冒泡)
var ul = document.getElementById('ul');
ul.onclick = function (e) {
// alert('123');
// 如何去找点击的li?
// console.log(this); // this指向ul
// 当事件发生的时候,系统会把事件发生时候的一些数据传递给事件处理函数 这个不需要我们来写
// 我们记住 e 事件对象(事件参数)
// e.target 真正触发事件的对象 li
e.target.style.backgroundColor = 'red';
}
</script>
</body>
</html>
事件对象 :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>事件对象</title>
<style>
#box {
width: 200px;
height: 200px;
background-color: red;
}
</style>
</head>
<body>
<input type="button" value="按钮" id="btn">
<div id="box">
</div>
<script>
var btn = document.getElementById('btn');
// btn.onclick = function (e) {
//// // 判断是否按下了alt键
//// if (e.altKey) {
//// console.dir(e);
//// }
//
// // 获取事件名称
// console.log(e.type);
// }
// e.type 的作用
// 就是当一个元素有多个事件的时候我们无法判断是哪一个触发了 我们就可以这样做
var box = document.getElementById('box');
box.onclick = fn;
box.onmouseover = fn;
box.onmouseout = fn;
function fn(e) {
// e有兼容性问题 IE9以前不支持
// IE的老版本获取事件对象的方式 window.event
// 处理兼容性
e = e || window.event;
switch (e.type) {
case 'click':
console.log('点击事件');
break;
case 'mouseover':
console.log('鼠标经过');
break;
case 'mouseout':
console.log('鼠标离开');
break;
}
}
</script>
</body>
</html>
脱离文档流:
CSS中脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位。
需要注意的是,使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围。
而对于使用absolute positioning脱离文档流的元素,其他盒子与其他盒子内的文本都会无视它。
还有就是子绝父相;
注意 :
节点操作 :
appendChild();是把这个元素放到最后;
ul.children 不是数组他是一个集合他没有forEach方法 但是他和数组一样有从新排列的问题;
我们在测试兼容性的时候我们以前还要考虑怎么在我们的w10版本的电脑上下载ie6来测试兼容性的问题,但是现在我们不需要考虑这个问题了,因为怎么我们的ie的11版本,我们调出来开发工具就能看出来,可以随意模拟ie的版本(如下图);
图示的那个框里面可以调节ie的版本
onclick不能给一个按钮注册多个事件会覆盖的,所以我们就要用addEventListener;
注意事件对象的兼容性问题:
用到e我们就会想到兼容性问题
// 处理兼容性
e = e || window.event;