Web前端教程3-JavaScript教程
1. JavaScript介绍
前端三大块
- HTML: 页面结构
- CSS: 页面表现,元素大小,颜色,位置,隐藏或者显示,部分动画效果
- JavaScript: 页面行为,部分动画效果,页面和用户的交互(一般不用JS,而是用JQuery)
其他插件:
- Ajax: 读取数据,无需刷新
1.1. JS嵌入页面的方式
<script type="text/javascript" src="../js/setting.js"></script>
2. JS基本语法
2.1. 变量类型
JS是一种弱类型语言,它的变量类型由它的值来决定
- 5种基本数据类型:
number, strign ,boolean, undefined, null
- 1中复合类型:
object
定义变量如下:
var a = 123;
var d; //这个是undefined
2.2. 获取元素方法
方法1:(不推荐)
/* title是属性 */
/* 问题是:这个语句是按照上下顺序执行的 */
document.getElementById('div1').title="我看到了!";
<div di="div1" class='div1' title='这是div元素哦'>这是一个div元素</div>
方法2:
/* 当整个文档加载完之后,再执行这个语句 */
window.onload = function(){
document.getElementById('div1').title="我看到了!";
}
2.3. 操作元素属性
可以参考任何标签的属性,包括linkdeng
操作方法主要分为两种:
.
的操作[]
操作
属性的写法
- htm属性和js属性要一直
class
属性写成className
style
属性里面的属性,有横杠的改成驼峰式font-size
改成oA.style.fontSize
操作方法1的写法
<script type="text/javascript">
window.onload = function(){
/* 写属性 */
document.getElementById('div1').href="www.baidu.com";
/* 没有title属性会自动添加 */
var oA = document.getElementById('div1');
oA.title="666";
/* 读属性 */
alert(oA.id);
}
</script>
.....
<div id="div1">这是一个div元素</div>
操作方法2的写法
<script type="text/javascript">
window.onload = function(){
var oA = document.getElementById('div1');
var attr ='color';
/* 三种方法完全一致 */
oA.style.color='red';
oA.style[attr]='red';
oA['style'][attr]='red';
}
</script>
.....
<div id="div1">这是一个div元素</div>
2.4. innerHTML的使用
<script type="text/javascript">
window.onload = function(){
var oA = document.getElementById('div1');
/* 用处1:可以读取这个标签包裹的元素 */
/* 输出:这是一个div元素 */
alert(oA.innerHTML)
/* 用处2:可以塞文字 */
oA.innerHTML = "666";
}
</script>
.....
<div id="div1">这是一个div元素</div>
3. JS函数
3.1. 函数的定义
<script type="text/javascript">
// 定义函数
function func_name(){
Operations;
}
// 调用函数1:直接调用
// 调用函数2:在控件中调用
func_name();
</script>
...
<input type="button", name="", onclick="func_name()">
技巧:统一js代码再同一块中:实现JS和HTML分离
<script type="text/javascript">
window.onload = function(){
var oBtn01 = document.getElementById('btn01');
var oBtn02 = document.getElementById('btn02');
/* 注意不要写括号 */
oBtn01.skin01;
}
function skin01(){
var oLink = document.getElementById('link1')
oLink.href = '1.css'
}
</script>
...
<input type="button", name="", value='皮肤01' id="btn01">
<input type="button", name="", value='皮肤02' id='btn02'>
3.2. 变量和函数预解析
JS解析过长分为两个阶段,先是编译阶段,然后执行阶段,在编译阶段会将Function定义的函数提前,并且将var定义的变量声明提前(赋值不提前),将它复制为underfined
- 方便JS的读写
<script type="text/javascript">
// 变量的预解析
alert(a); //a的声明提前,因为没有赋值所以弹出undefined,a的值未定义
alert(c); //会报错,c没有声明
var a = 10;
// 函数的预解析
my_akert(); // 函数的预解析,这个弹出hello
function my_akert(){
alert('hello')!
}
</script>
3.3. 匿名函数
没有函数名的函数
<script type="text/javascript">
window.onload = function (){
var oDiv = document.getElementById('div1');
oDiv.onclick = function (){
alert('hello');
}
}
</script>
3.4.函数的参数
传入多个参数
<script type="text/javascript">
window.onload = function (){
var oDiv = document.getElementById('div1');
function changestyle(styl,val){
oDiv.style[styl] = val;
}
changestyle('color', gold);
changestyle('backgound', red);
changestyle('width', 300px);
}
</script>
.....
<div id="div1">这是一个div元素</div>
返回值
实现两个输入框,值进行相加的操作
<script type="text/javascript">
window.onload = function (){
var oInput01 = document.getElementById('input01');
var oInput02 = document.getElementById('input02');
var oBtn = document.getElementById('btn');
oBtn.onclick = function (){
var val01 = oInput01.value;
var val02 = oInput02.value;
var rs = add(val01,val02);
alert(rs)
}
function add(a,b){
var c = parseInt(a) + parseInt(b)
return c;
}
}
</script>
.....
<input type="text" name="" value="" id="input01">
<input type="text" name="" value="" id="input02">
<input type="button" name="" value="相加" id="btn">
<input type="text" id="input01">
<input type="text" id="input02">
<input type="button" value="相加" id='btn'>
return关键字
- 返回结果
- 结束运行,return后面的语句都不会执行
- 阻止默认行为
4. 条件循环
运算符
- 算术运算符:
+,-,*,/, %
- 条件运算符:
==, >=,<=, !=, &&(and), ||(or), |(not)
- if-else
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.box{
width: 300px;
height: 300px;
backgound:gold;
}
</style>
<script type="text/javascript">
window.onload = function(){
var a1 = document.getElementById('box');
var btn = document.getElementById('btn');
var a = 100;
// 单条件语句
btn.onclick = function(){
if (a1.style.display == "none"){
a1.style.display == "block";
}
else{
a1.style.display == "none";
}
}
// 多条件语句--建议用switch-case写
if (a>50){
a = 50;
} else if (a>30){
a=30;
} else {
a=0;
}
}
</script>
</head>
<body>
<div id="div1">这是一个div元素</div>
<input type="button" name="" value="相加" id="btn">
<div class="box" id="box"></div>
</body>
</html>
- switch-case
var a ==6;
switch(a){
case 1:
alert('1');
break;
case 2:
alert('2');
break;
default:
alert('0000');
break;
}
- for,while
for(var i=0;i<len;i++){
operations;
}
5.JS中的数组
5.1. 创建数组的方式
/* 定义方法1: 面向对象法 */
var aRr01 = new Array(1,2,3,4,'abc');
/* 定义方法2:建议使用 */
var aRr02 = [1,2,3,4,'abc'];
/* 获取数组长度 */
var alen = aRr02.length;
/* 也可以设置长度 */
aRr02.length = 10;
/* 获取某个元素,从0开始的角标 */
var aval = aRr02[2];
/* 定义多维数组 */
var aRr03 = [[1,2,3],[4,5,6],['a','b','c']];
var aval02 = aRr03[1][2];
5.2. 数组方法
var aRr01 = [1,2,3,4];
// 数组连接字符串
var sTr01 = aRr01.join('-'); //输出1-2-3-4
var sTr02 = aRr01.join('');//输出1234
aRr01.push(5); //从尾部增加了一个成员:1,2,3,4,5
aRr01.pop(); //从尾部删除了一个成员 1,2,3,4
aRr01.unshift(0); //从头部增加了一个成员
aRr01.shift(); //从头部删除了一个成员
aRr01.reverse(); // 将元素倒装,4,3,2,1
aRr01.indexOf(2); // 只返回元素2第一次出现的index值
aRr01.splice(2,1,7,8,9); // 从第2个元素开始,删除1个元素,然后在此位置增加7,8,9
5.3. 遍历数组
- for循环
- foreach方法
window.onload = function (){
for(var i=0;i<aLi.length;i++){
aLi[i].style.backgound='gold';
}
var arr = [5,7,9];
// 函数由我们创建,不由我们调用,数组有几个元素,就会执行几次
// 每次执行时,以实参形式传递进来
// 浏览器在回调函数中传递三个参数
// 1. value--当前正在遍历的元素: 5,7,9
// 2. index--当前正在遍历的元素索引: 0,1,2
// 3. arr ---当前正在遍历的数组
arr.foreach(function(value, index, arr){
console.log("value=" + value + ", index = " + index + ", array = " + arr);
});
}
5.4. 获取元素的第二种方法
通过document.getElementByTagName
获取的是一个选择集,不是数组,但是可以通过下标方式操作选择集中的dom元素
window.onload = function (){
/* 选择特定的li元素 */
var oList = document.getElementById('list01');
/* aLi是一个选择集,而不是数组,获取文档中所有的li元素 */
var aLi = oList.getElementByTagName('li');
for(var i=0;i<aLi.length;i++){
aLi[i].style.backgound='gold';
}
}
<ul id='list01'>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul id='list02'>
<li>5</li>
<li>6</li>
</ul>
5.4. 数组去重
var aList = [1,2,3,3,4,5,2,3,1,5,4,3,2,2,1];
var aList2=[];
for(vari=0;i<aList.length;i++){
if(aList.indexOf(aList[i]==i)){
aList2.push(aList[i]);
}
}
5.6. 实例: 计算器
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>测试</title>
<script type="text/javascript">
window.onload = function(){
var a1 = document.getElementById('input01');
var a2 = document.getElementById('input02');
var op = document.getElementById('fuhao');
var btn = document.getElementById('btn');
btn.onclick = function(){
var v1 = a1.value;
var v2 = a2.value;
var fuhao = op.value;
// 判断输入框是否为空
if (v1 == '' || v2 == ''){
alert('不能为空');
return;
}
// 判断输入为数字
if(isNaN(v1) || isNaN(v2)){
alert('请输入数字');
return;
}
switch(fuhao){
case '0':
alert(parseFloat(v1) + parseFloat(v2));
break;
case '1':
alert(parseFloat(v1) - parseFloat(v2));
break;
case '2':
alert(parseFloat(v1) * parseFloat(v2));
break;
case '3':
alert(parseFloat(v1) / parseFloat(v2));
break;
}
}
}
</script>
</head>
<body>
<h1>计算器</h1>
<input type="text" name="" value="" id="input01">
<select class="" name="" id="fuhao">
<option value="0">+</option>
<option value="1">-</option>
<option value="2">*</option>
<option value="3">/</option>
</select>
<input type="text" name="" value="" id="input02">
<input type="button" name="" value="计算" id="btn">
</body>
</html>
6. JS的字符串
JS的组成
ECMAscript javascript
的语法(变量,函数,循环语句的语法)DOM
文档对象模型,操纵html和cssBOM
浏览器对象模型,操作浏览器的方法
6.1. 字符串的处理方法
- 字符串合并
+
parseInt()
将数字字符串转化为整数parseFloat()
将数字字符串转化为小数split('')
把一个字符串分割成字符串组成的数组charAt(index)
获取字符串中的某个字符indexOf(value)
查找字符串是否含有某字符substring(start,end)
截取字符串用法str.split('').reverse().join('');
字符串反转toUpperCase()
字符串转大写toLowerCase()
字符串转小写
7. 定时器
属于BOM,浏览器的用处
定时器的作用
- 制作动画
- 异步操作
- 函数缓冲和节流
用处1:异步操作
/* 定时器:
setTimeout 只执行一次定时器
clearTimeout 关闭只执行一次的定时器
setInterval 反复执行的定时器
clearInterval 关闭反复执行的定时器 */
/* 等1000毫秒才弹出来 */
setTimeout(myalert, 1000);
function myalert(){
alert('Hello');
}
同时我们可以自定义弹框
<style type="text/css">
.pop_con{
display: none;
}
.pop{
width:400px;
height: 300px;
background-color: #fff;
border: 1px solid #000;
position: fixed;
left: 50%;
top:50%;
margin-left: -200px;
margin-top: -150px;
/* z-index用于设置成层级 */
z-index=9999;
}
.mask{
position: fixed;
width: 100%;
height: 100%;
background-color: #fff;
left: 0;
top: 0;
/* 设置透明 */
opacity: 0.3;
filter:alpha(opacity=30);
z-index=9990;
}
</style>
<div class="pop_con" id="pop">
<div class="pop">
<h3>提示信息</h3>
<a href="#" id="shutoff">关闭</a>
</div>
<div class="mask"></div>
</div>
window.onload = function (){
var oPop = document.getElementById('pop');
var oShut = document.getElementById('shutoff');
setTimeout(showpop,40000);
function showpop(){
oPop.style.display:block;
}
oShut.onclick = function(){
oPop.style.display = 'none';
}
}
关闭定时器
// 执行一次的定时器
var timer = setTimeout(function(){
alert('hello');
},4000);
// 刚执行就关闭
clearTimeout(timer);
var timer2 = setInterval(function(){
alert('hello');
},2000);
clearInterval(timer2);
7.1. 动画
<style type="text/css">
.box{
width:100px;
height:100px;
background-color: gold;
position: fixed;
left: 20px;
top: 20px;
}
</style>
<script type="text/javascript">
window.onload = function(){
var oBox = document.getElementById('box');
var left = 20;
var timer = setInterval(function(){
left++;
oBox.style.left = left + 'px';
if(left>700){
clearInterval(timer);
}
},30);
}
</script>
<div class="box" id="box"></div>
7.2. 制作时钟
<script type="text/javascript">
window.onload = function(){
var oDiv1 = document.getElementById('div1');
function timego()){
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth()+1;
var date = now.getDate();
var week = now.getDay();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
oDiv1.innerHTML = '当前时间是' + year + '年' + month + '月' + date + '日' +
toweek(week) + hour + ':' + minute + ':'+ second;
}
timego();
setInterval(timego,1000);
}
function toweek(num){
switch(num){
case 0:
return '星期天';
break;
case 1:
return '星期一';
break;
case 2:
return '星期二';
break;
case 3:
return '星期三';
break;
case 4:
return '星期四';
break;
case 5:
return '星期五';
break;
case 6:
return '星期六';
break;
}
}
</script>
</head>
<body>
<div id="div1"></div>
</body>
</html>
结果是
当前时间是2019年3月12日星期二11:53:34
7.3. 制作倒计时
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>测试</title>
<script type="text/javascript">
window.onload = function(){
var oDiv = document.getElementById('div1');
function timeleft(){
var now = new Date();
var future = new Date(2019,10,30,24,0,0); // 实体从服务器获取
var left = parseInt((future-now)/1000); //转为秒
var day = parseInt(left / 86400);
var hour = parseInt((left%86400)/3600);
var mintue = parseInt(((left%86400)%3600)/60);
var second = left%60;
if (left<=0){
window.location.href = "http://www.baidu.com";
}
oDiv.innerHTML = '距离2019年11月30日晚上24点还有--' + day + '天' + hour +
'时' + mintue + '分' + second + '秒';
}
timeleft();
setInterval(timeleft,1000);
}
</script>
</head>
<body>
<div class="" id="div1">
</div>
</body>
</html>
8. 变量作用域
- 全局变量-函数外部顶一顶额变量,函数内部外部都可以访问,它的值可以共享,可以随意改它的值
- 局部变量-函数内部定义的变量,函数内部可以访问,外部无法访问,内部访问变量时,先在内部查找是否有这个变量,有的话就用内部的,没有的话就去外部找
9. 封闭函数
函数变量化
这种方式只能在函数定义后面调用
var myalert = funtion(){
alert('hello');
}
myalert();
/*
封闭函数的定义 (function(){...})();
1. 省去函数名
2. 局部变量不会影响其他变量(相同名字) */
var str = "abc";
(function (){
var str = '欢迎访问我的主页';
var myfunc = function(){
...;
}
myfunc;
alert(str);
})();
10. 闭包
函数嵌套,函数里面再定义函数,内部函数可以引用外部函数的参数和变量,变量存在闭包里面不会被回收
<script type="text/javascript">
function aa(b){
var a=12;
function bb(){
alert(a);
alert(b);
}
return bb;
}
var cc = aa(24); // cc=bb
cc();
</script>
- 同时闭包也可以改成封闭函数
<script type="text/javascript">
var cc = (function(b){
var a=12;
function bb(){
alert(a);
alert(b);
}
return bb;
})(24);
</script>
10.1. 闭包的作用
- 可以在循环中存索引值
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>测试</title>
<script type="text/javascript">
window.onload = function(){
var aLi = document.getElementsByTagName('li');
for(var i=0;i<aLi.length;i++){
// 一般循环无法保存i,此时的i是4
// 通过闭包存i
(function(i){
aLi[i].onclick = function(){
alert(i);
}
})(i);
}
}
</script>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
</html>
- 私有变量计数器,外部无法访问,避免全局变量的污染
11. 内置对象
对象 | 方法 | 说明 |
---|---|---|
document | document.referrer | 获取上一个跳转页面的地址 |
locaiton | window.location.href window.location.search window.location.hash |
获取或者重定url地址 获取地址参数部分 获取页面锚点或者哈希值 |
Math | Math.random Math.floor Math.ceil |
获取0-1的随机数 向下取整 向上取整 |
<script type="text/javascript">
var data = window.location.search;
// 在网址输入“..../?a=123” 的时候输出 “?a=123”
alert(data);
var hash = window.location.hash;
// 在网址输入“....#=123” 的时候输出 “#=123”
alert(hash);
</script>
12. 面向对象
12.1. JS面向对象
将相关的变量和函数组合成一个整体,这个整体叫做对象,对象中的变量叫做属性,变量中的函数叫做方法, js对象类似字典
但是JS没有类,类是通过函数实现的
- 内建对象
- 宿主对象
- 自定义对象
12.2. 自定义对象:创建对象的方法
- 单体:
<script type="text/javascript">
var Tom = {
name: 'tom',
age: 18,
showname: function(){
alert('my name is ' + this.name);
},
showage: function(){
alert('my age is ' + this.age);
}
}
alert(Tom.name);
Tom.showname();
</script>
- 工厂模式(少用)
通过一个函数创建对象
<script type="text/javascript">
function Person(name, age){
var o = new Object(); // 创建空对象
o.name = name;
o.age = age;
o.showname = function(){
alert('my name is ' + this.name);
};
o.showage = function(){
alert('my age is ' + this.age);
}
return o;
}
var tom = Person('tom',18);
tom.showname();
</script>
使用工厂方式创建的对象,使用的都是object,导致无法区分多种不同类型的对象
- 构造函数: 类型python类
构造函数就是用一般函数创建的,区别是加了new
构造函数的执行流程:
- 一旦调用构造函数,马上创建一个新的对象
- 将新建的对象设置为函数中的this
- 逐行执行函数的代码
- 将新建的对象作为返回值返回
使用同一个构造函数的对象,称为同一类对象,也称为该类的实例
<script type="text/javascript">
function Person(name, age){
this.name = name; // this为新建的对象,tom, jack,向新建对象添加属性
this.age = age;
this.showname = function(){ // 为对象添加方法
alert('my name is ' + this.name);
};
this.showage = function(){
alert('my age is ' + this.age);
}
}
var tom = new Person('tom',18);
var jack = new Person('jack',20);
tom.showname();
console.log(tom instanceof Person); // true
console.log(tom instanceof Object); //
alert(tom.showname == jack.showname); // false, 浪费资源
</script>
问题: 每一个对象的方法都有一个新的方法,浪费资源
- 原型模式:比构造函数更高效
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
, 这个属性对应原型对象
- 当函数以普通函数调用时,
prototype
没用 - 当函数以构造函数调用时,它所创建的对象都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过
__proto__
访问 - 当调用属性和方法时,首先在本身寻找,有就用,没有就去
prototype
原型寻找,没有就去原型对象的原型去找,直到找到Object
原型
<script type="text/javascript">
function Person(name, age){
this.name = name;
this.age = age;
}
// prototype上绑定的方法可以被所有person对象公用
// prototype为原型对象,所有同一个类的实例都可以访问到这个原型对象,
// 可以将共有的内容设置到这个原型对象中
Person.prototype.showname = function(){
alert('my name is ' + this.name);
}
Person.prototype.showage = function(){
alert('my age is ' + this.age);
}
// toString是在打印对象的时候自动的内容,我们可以重写这个方法让它打印更详细的信息
// console.log(tom); person[name=“tom”, age=20]
Person.prototype.toString = function(){
return "person[name = " + this.name + ", age=" + this.age + "]";
}
var tom = new Person('tom',18);
var jack = new Person('jack',20);
console.log(tom.__proto__ == Person.prototype); // true
console.log(tom.hasOwnProperty("name")); // false,只有本身有属性才会true,这个方法在原型里
alert(tom.showname == jack.showname); // true, 更加高效
</script>
- 继承
<script type="text/javascript">
// 定义父类
function Fclass(name, age){
this.name = name;
this.age = age;
}
Fclass.prototype.showname = function(){
alert('my name is ' + this.name);
}
Fclass.prototype.showage = function(){
alert('my age is ' + this.age);
}
// 定义子类,继承父类
function Sclass(name, age, job){
// 继承属性:call或者apply
// call:改变当前函数执行的this
// apply和call的用法一样,只是语法不同: Fclass.apply(this, [name, age]);
Fclass.call(this, name, age);
this.job = job;
}
// 继承方法: prototype
Sclass.prototype = new Fclass();
Sclass.showjob = function(){
alert('my job is ' + this.job);
}
var tom = new Sclass('tom',20,'engineer');
tom.showage();
</script>
12.3. 自定义对象:this的用法
- this就是
object.window
,指向的是一个对象,称为函数执行的上下文对象 - 根据函数调用方式的不同,this会指向不同的对象
- 以函数形式调用时,this为window
- 以方法形式调用时,this为调用方法的对象,比如
<script type="text/javascript">
var name ="全局";
function fun(){
// console.log(this.name); // 这种方式永远是"全局"
console.log(this.name); // 随着调用的对象不同而变化
}
var obj = {
name: "sun",
sayName: fun
};
var obj2 = {
name: "kkk",
sayName: fun
};
console.log(obj.sayName == fun); // true,同一个函数
fun(); // 以函数调用的时候,this指向对象(上下文),为Object.window
obj.sayName(); // 以方法调用的时候,this为Object.object(“sun”)
obj2.sayName(); // 以方法调用的时候,this为Object.object(“kkk”)
</script>
结果是
true
全局
sun
kkk
12.4. 宿主对象:Array:见5
13. 垃圾回收
- 就像人生活的时间长了,程序运行过程中也会产生垃圾,垃圾过多后,会导致程序运行速度过慢,需要垃圾回收机制
- 在JS中有自动垃圾回收机制,不需要也不能进行垃圾回收的操作
- 手动回收的方法:设置为null
var a = new Obect();
a = null;
14.DOM
14.1. DOM简介
- DOM: Document Object Model文档对象模型
- 文档: 一个HTML网页文档
- 对象: 网页的每个部分都转为对象,比如
body, head, h1..
都转为对象(就可以通过面向对象对他进行操作) - 模型: 用来表示对象之间的关系,方便获取对象
14.2. 节点
节点是构成网页的基本节点,比如
body, head, h1..
节点的类型不同,属性和方法也不同
- 文档节点: 整个HTML文档
- 元素节点: HTML的HTML标签
- 属性节点: 元素的属性
- 文本节点: HTML标签中的文本内容
节点的属性
节点 | 节点名称 | 节点类型 | 节点值 |
---|---|---|---|
文档节点 | #document | 9 | null |
元素节点 | 标签名 | 1 | null |
属性节点 | 属性名 | 2 | 属性值 |
文本节点 | #text | 3 | 文本内容 |
- 浏览器已经为我们提供了文档节点对象,这个对象时window属性,可以在网页中直接使用,文档节点(document)代表的是整个网页
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>测试</title>
<script type="text/javascript">
// 获取button对象
var btn = document.getElementById("btn");
// 修改button的属性
btn.innerHTML = "你好啊";
</script>
</head>
<body>
<button id='btn'>我是按钮</button>
</body>
</html>
14.3. 事件
- 事件就是文档或者浏览器窗口中发生的一些特定的交互瞬间
- JS和HTML之间的交互式通过事件实现的
- 对于WEB应用来说,有下面这些代表性的事件: 点击,移动,按键等
<script type="text/javascript">
window.onload = function(){
var btn = document.getElementById("btn");
console.log(btn);
btn.onclick = function(){
alert('hello');
}
}
</script>
....
<input type="button" name="" value="我是按钮" id="btn">
14.4. 文档加载
也就是说需要使用window.onload = function(){}
14.5. DOM查询
获取元素节点
- 通过document对象调用
方法 | 说明 |
---|---|
getElmentById() | 通过唯一id获取元素节点对象,返回对象 |
getElementsByTagName() | 通过标签名获取一组元素节点对象,返回数组 |
getElementByName() | 通过name获取一组节点对象,返回数组 |
属性的写法
- htm属性和js属性要一直
class
属性写成className
style
属性里面的属性,有横杠的改成驼峰式font-size
改成oA.style.fontSize
- 通过元素节点调用
方法 | 说明 |
---|---|
getElmentsByTagName() | 获取当前节点的指定标签名后代节点 |
属性 | 说明 |
---|---|
childNodes | 当前节点的所有子节点(会获取所有的各种节点,包括空白) |
firstChild | 当前节点的第一个子节点(包括其他节点,空白等) |
firstElementChild | 当前节点的第一个子元素(IE8以上) |
lastChild | 当前节点的最后一个子节点 |
childern | 当前节点的所有子元素(推荐) |
parentNode | 当前节点的父节点 |
previousSibling | 当前节点的前一个兄弟节点(包括其他节点,空白等) |
previousElementSibling | 前节点的前一个兄弟元素(IE8以上) |
nextSibling | 当前节点的后一个兄弟节点 |
<script type="text/JavaScript">
var btn = document.getElmentById("btn");
btn.onclick = function(){
// 获取id为city的元素
var city = document.getElmentById("city");
// 查找city下 的所有li节点
var lis = city.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
alert(lis[i].innerHTML);
}
}
</script>
其他查询方法
// 获取`body`标签
var body = document.body;
// 获取`html`标签
var html = document.documentElement;
// 获取页面所有元素, body,html, head, script,...
var all = document.all;
var all = document.getElementsByTagName("*");
// 获取class内容>IE9
var box1 = document.getElementByClassName("box1");
// 获取含有class=“box1”的div
// querySelector: 根据CSS选择器来选择--只返回一个元素
var box1_div = document.querySelector(".box1 div");
// 返回符合条件的所有box
var box1_div = document.querySelectorAll(".box1");
14.6. DOM增删改
方法 | 说明 |
---|---|
appendChild() | 添加新的子节点到指定节点 |
removeChild() | 删除子节点 |
replaceChild() | 替换子节点 |
insertBefore() | 在指定的子节点前面插入新的子节点 |
createAttribute() | 创建属性节点 |
createElement() | 创建元素节点 |
createTextNode() | 创建文本节点 |
getAttribute() | 返回指定的属性值 |
setAttribute() | 设置属性值为指定的值 |
实例: 设计一个增加删除表格
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>表格</title>
<script type="text/javascript">
function delA(){
// 点击后删除超链接所在行
// 获取当前tr
var tr= this.parentNode.parentNode;
// 获取要删除的员工名称
var emp = tr.getElementsByTagName("td")[0].innerHTML;
// 确认是否删除
if(confirm("真的删除" + emp + "?")){
// 删除tr
tr.parentNode.removeChild(tr);
}
return false; // 让a不要跳转
}
window.onload = function(){
// 实现删除功能
var allA = document.getElementsByTagName("a");
for (var i=0; i<allA.length; i++){
// for循环会在页面加载完成时,立即执行,而相应函数只是在点击的时候执行,此时for循环已经完成
// 此时的i为3
// console(i) = 3;
// 不加括号,对象赋值给this
allA[i].onclick = delA;
}
// 实现添加功能
var name = document.getElementById("empName");
var age = document.getElementById("empAge");
var btn = document.getElementById("addEmpButton");
btn.onclick = function(){
// 创建tr
var tr = document.createElement("tr");
console.log(name.value);
// 设置tr内容
tr.innerHTML = "<td>" + name.value + "</td>" +
"<td>" + age.value + "</td>" +
"<td><a href='javascript:;'>Delete</a></td>";
var a = tr.getElementsByTagName("a")[0];
a.onclick = delA;
// 获取table
var employee_table = document.getElementById("employee_table");
// 获取table的tbody
var tbody = employee_table.getElementsByTagName("tbody")[0];
// 将tr添加到tbody中
tbody.appendChild(tr);
}
}
</script>
</head>
<body>
<table id="employee_table">
<tbody>
<tr>
<th>Name</th>
<th>Age</th>
<th> </th>
</tr>
<tr>
<td>Tom</td>
<td>23</td>
<td><a href="javascript: ;">Delete</a></td>
</tr>
<tr>
<td>Jerry</td>
<td>12</td>
<td><a href="deleteEmp?id=002">Delete</a></td>
</tr>
</tbody>
</table>
<hr />
<div class="" id="formDiv">
<h4>添加新成员</h4>
<table>
<tr>
<td class="word">name: </td>
<td class="inp">
<input type="text" name="empName" id="empName"/>
</td>
</tr>
<tr>
<td class="word">age: </td>
<td class="inp">
<input type="text" name="age" id="empAge"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button id="addEmpButton" value="abc">Submit</button>
</td>
</tr>
</table>
</div>
</body>
</html>
14.7. DOM操作CSS
- 修改样式:
元素.style.样式名 = 样式值
- 读取样式(适用于内联样式):
元素.style.样式名
- 读取样式(当前正在显示的样式):
- 只能用于IE:
元素.currentStyle.样式
- 其他浏览器:
css对象 = getComputedStyle(元素名,伪元素(null))
, css对象封装了样式信息,css.width
- 只能用于IE:
<script type="text/javascript">
window.onload = function(){
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box1");
var btn01 = document.getElementById("btn");
/*
* 功能: 修改元素CSS样式
* 通过JS修改元素的CSS样式
* 语法: 元素.style.样式名 = 样式值
* 注意: 如果CSS中含有-, 应该换成驼峰状
* 其实设置的是内联样式(优先级高),所以会立即显示
*/
btn01.onclick = function(){
box1.style.width = "300px";
box1.style.backgroundColor = "yellow";
};
// 获取样式表样式(当前显示样式)
btn02.onclick = function(){
var ar = getComputedStyle(box1);
alert(ar.width);
}
};
</script>
15. DOM事件
15.1. 事件的基本使用
- 当事件的事件句柄(
Event Handlers
)被触发时(e.g, onmousemove), 浏览器会自动将一个事件对象(event)作为实参传递给响应函数 - 这个事件对象包含了很多信息(
鼠标 / 键盘属性
),比兔坐标,鼠标滚轮方向,按键,等等...
<script type="text/javascript">
window.onload = function(){
// 当事件的相应函数被触发时(onmousemove), 浏览器会自动将一个事件对象(event)作为实参传递给响应函数
// 这个事件对象包含了很多信息,比兔坐标,鼠标滚轮方向,按键,等等...
// 为了处理不同浏览器兼容问题
event = event || window.event;
btn.onmousemove = function(event){
var x = window.event.clientX;
var y = window.event.clientY;
}
}
</script>
15.2. 事件冒泡
- 事件冒泡: 事件的向上传导,当后代元素上的事件被触发的时候,其祖先元素的相同事件也会被触发
- 大部分有用,但是可以取消
<script type="text/javascript">
window.onload = function(){
var s1 = document.getElementById("s1");
var box1 = document.getElementById("box1");
s1.onclick = function(event){
alert("我是span");
// 取消事件冒泡
event = event | window.event;
event.cancelBubble = true;
}
box1.onclick = function(){
alert("我是box1");
}
document.onclick = function(){
alert("我是document");
}
};
</script>
- 当点击s1的时候,会同时触发s1, box, docuemnt的onclick事件
15.3. 事件委派
- 将事件统一绑定给元素的共同祖先元素,这样后代元素上的事件触发的时候,会一直冒泡到祖先元素
- 事件委派: 利用了冒泡,通过委派可以减少事件胖丁的次数,提高程序的高效性
<script type="text/javascript">
window.onload = function(){
var lis = document.getElementsByTagName("li");
var ul = document.getElementById("ul");
var btn = document.getElementById("btn");
// 问题1: 新加入的超链接没有绑定事件
btn.onclick = function(){
var li = document.createElement("li");
li.innerHTML = "<a href='javascript:;'>链接新来的</a>";
ul.appendChild(li);
};
// 问题2: 只能为已经有的每一个超链接绑定事件,新的超链接需要重新绑定,不推荐
// 解决方法: 将其绑定给元素的共同的祖先元素
/*
* for(var i=0;i<lis.length;i++){
* lis[i].onclick = function(){
* alert("666");
* }
* };
*/
// 因为这是一个冒泡,点击a,冒泡到ul---新添加的都有了
ul.onclick = function(event){
// 只有点击的是link的class时
if (event.target == "link") {
alert("我是ul的单击函数");
}
}
};
</script>
15.4. 事件绑定
addEventListener
- 参数1: 事件字符串
- 参数2: 回调函数,当事件触发的时候该函数执行
- 参数3: 是否铺货期间触发函数,一般为false
- 按照顺序执行
<script type="text/javascript">
window.onload = function(){
btn01. addEventListener("listener", function()[
alert(1);
], false);
btn01. addEventListener("listener", function()[
alert(2);
], false);
};
</script>
- 解决兼容性:
<script type="text/javascript">
window.onload = function(){
function bind(obj, eventStr, callback){
if (obj.addEventListener) {
// 大部分浏览器兼容的方式
obj.addEventListener(eventStr, callback, false);
} else {
// IE8及以下
obj.attachEvent("on" + eventStr, callback);
}
}
};
</script>
16. 应用: 轮播图
Web前端教程3-JavaScript教程的更多相关文章
- 大前端时代已经到来!传智播客2015之WEB前端视频教程(全套教程共15G)
大前端时代已经到来!传智播客2015之WEB前端视频教程(全套教程共15G)大前端时代已经到来!如今,前端开发工程师的职责,不是只有切图.制作网页这么简单哦! G:\传智播客2015-WEB前端视频教 ...
- 用grunt搭建自动化的web前端开发环境实战教程(详细步骤)
用grunt搭建自动化的web前端开发环境实战教程(详细步骤) jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用!前端自动化, ...
- Yeoman+Bower+gulp web前端自动化工作流程(初级教程)
Yeoman包括了三个部分yo(脚手架工具).grunt/gulp(构建工具).bower(包管理器).听说gulp更容易上手,所以我就没用grunt而选的gulp 什么是开发流程? 在我看来一个完整 ...
- 腾讯Web前端开发框架JX(Javascript eXtension tools)
转自:Web前端开发-Web前端工程师 » 腾讯Web前端开发框架JX(Javascript eXtension tools) JX – Javascript eXtension tools 一个类似 ...
- 进击的Python【第十四章】:Web前端基础之Javascript
进击的Python[第十四章]:Web前端基础之Javascript 一.javascript是什么 JavaScript 是一种轻量级的编程语言. JavaScript 是可插入 HTML 页面的编 ...
- 【前端福利】用grunt搭建自动化的web前端开发环境-完整教程
jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过 ...
- 转:【前端福利】用grunt搭建自动化的web前端开发环境-完整教程
原文地址:http://blog.csdn.net/wangfupeng1988/article/details/46418203 jQuery在使用grunt,bootstrap在使用grunt,百 ...
- 用grunt搭建自动化的web前端开发环境-完整教程
原稿:http://www.cnblogs.com/wangfupeng1988/p/4561993.html#!comments jQuery在使用grunt,bootstrap在使用grunt,百 ...
- 【前端福利】用grunt搭建自己主动化的web前端开发环境-完整教程
jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发者.假设你如今还不知道grunt或者听说过. ...
- 1+x证书Web前端开发CSS3详细教程
web 前端开发之 CSS3 新特性 http://blog.zh66.club/index.php/archives/189/ web 前端开发之 html5 新特性 http://blog.zh6 ...
随机推荐
- linux屏幕扩展、扩展屏幕的校准
#xrandr命令为屏幕扩展 #xinput命令为输入设备 #设置DSI-1为HDMI-1的右扩展 xrandr --output DSI- --right-of HDMI- --auto #DSI- ...
- 对比 Git 与 SVN,这篇讲的很易懂
---恢复内容开始--- 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯工蜂发表于云+社区专栏 导语 本文从 Git 与 SVN 的对比入手,介绍如何通过 Git-SVN 开始 ...
- git rebase 合并多次提交.
一.应用场景 为什么需要合并多个提交呢? 常常一个功能的开发,修修补补 commit 了 n 多次,带来的结果就是提交过多过杂,不够直观,究竟哪些提交是对应这个功能的呢?还有就是,如果我要将这个功能迁 ...
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限
上一篇<[原]无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限>介绍了实现Shiro的基础认证.本篇谈谈实现 ...
- git 版本库基础知识学习
什么是版本库?什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可 ...
- Windows10文件目录下添加 Shift+右键打开管理员Powershell窗口
背景(可略过) 目前在调试 Python 程序,遇到了一个问题:当程序中包含多线程时,使用 IDLE 运行是不会执行多线程的语句的,在网上一顿搜罗了解到这种情况可以换成在命令行下执行.好像用 PyCh ...
- 关于raft算法
列出一些比较好的学习资料, 可以经常翻一番,加深印象 0 raft官方git 1 raft算法动画演示 2 Raft 为什么是更易理解的分布式一致性算法 3 raft一致性算法 4 Raf ...
- 从Android源码修改cpu信息
cpuinfo 网上的文章都是怎么查看/proc/cpuinfo,一直以为这种东西没法改呢,我还是太天真了./proc/cpuinfo是个文件,只读,想直接写肯定不行的.今天研究了一下,发现它的输出逻 ...
- Feign源码解析
1. Feign源码解析 1.1. 启动过程 1.1.1. 流程图 1.1.2. 解释说明 Feign解析过程依赖Spring的初始化,它通过实现ImportBeanDefinitionRegistr ...
- java集合常见面试题
1. Array和ArrayList的区别,什么时候更合适用Array a) Array是数组,可以容纳基本类型和对象,而ArrayList是集合,只能容纳对象 b) Array是 ...