<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>变量案例-弹出用户名</title>
</head>
<body>
<script>
// 1、输入用户姓名,存储到一个 myName 的变量中
var myName = prompt('请输入用户名')
// 2、输出这个用户名
alert(myName)
</script>
</body>
</html>
undefined
(未定义的);xxx is not defined
);<body>
<script>
var age = prompt("请输入你的年龄");
var str = '你今年已经' + age + '岁了';
alert(str)
</script>
</body>
<script>
// int num=10; java
// var num; //这里的num 我们是不确定属于哪种数据类型的
var num = 10; //num属于数字型
// js 的变量数据类型是只有程序在运行过程中,根据等号右边的值来确定的
// js是动态语言 变量的数据类型是可以变化的
var x = 10; // x 是数字型
x = 'pink'; //x 是字符串
</script>
//利用算数运算 - * / 来隐式转换;
<script>
console.log('12'-0);//隐式转换为 数字型12
console.log('123'-'120');
</script>
<body>
<!-- 此案例要求在页面中弹出一个输入框,我们输入出生年份后,能计算出我们的年龄 -->
<!--
案例分析:
1、弹出一个输入框(prompt),让用户输入出生年份(用户输入);
2、把用户输入的值用变量保存起来,然后用今年的年份减去变量值,结果就是现在的年龄(程序内部处理);
3、弹出警示框(alert),把计算的结果输出(输出结果);
-->
<script>
var year=prompt("请输入你的出生年份");
var age=2022-year;//按道理year取过来的是字符串型,做减法操作这里做了隐式转换;
alert('你的年龄是'+age+'岁');
</script>
</body>
<body>
<!-- 计算两个数的值,用户输入第一个值后,继续弹出第二个输入框并输入第二个值,最后通过弹出框口显示出两次输入值相加的结果 -->
<script>
var num1 = prompt("请输入第一个值");
var num2 = prompt("请输入第二个值");
var result = parseFloat(num1) + parseFloat(num2);
alert("你的结果是:" + result);
</script>
</body>
&&
表达式2;<body>
<!--
1、用我们的布尔值参与的逻辑运算 true && false == false;
-->
<script>
// 3、逻辑与短路运算
// 3.1、逻辑与短路运算 如果表达式1结果为真,则返回表达式2;
console.log(123 && 456);//456
// 3.2、逻辑与短路运算 如果第一个表达式的值为假,则返回表达式1;
console.log(0 && 456);//0
// 如果有空的或者否定的为假(如:0、''、null、undefined、NaN),其余是真的;
// 4、逻辑或短路运算
// 4.1、如果表达式1结果为真,则返回的是表达式1;
console.log(123 || 456);//123
// 4.2、如果表达式1结果为假,则返回的是表达式2;
console.log(0 || 456);//456
// 案例分析(123为真,直接返回123,后面的 num++ 就不再执行了,所以是结果是0)
var num=0;
console.log(123 || num++);
console.log(num);//0
</script>
</body>
<script>
var num = 10;
//num=num+1; num++
//num = num + 2; ==> num += 2;
num += 2;
console.log(num);//12
</script>
!
)优先级很高;JS
语言提供了两种分支结构语句:if
语句、switch
语句;if
分支语句、switch
分支语句、三元表达式)<body>
<!--
算法:能被4整除且不能整除100的为闰年(如2004年就是闰年,1901年不是闰年)或者能被400整除的就是闰年;
-->
<script>
var year=prompt("请输入年份:");
if(year % 4 ==0 && year % 100 !== 0 || year % 400 ==0){
alert("你输入的年份是闰年");
}else{
alert("你输入的年份是平年");
}
</script>
</body>
<body>
<!--
案例描述:用户输入数字,如果数字小于0,则在前面补零;如果数字大于0,则不需要补。
-->
<script>
var time = prompt("请输入一个0~59之间的一个数字");
var result = time < 10 ? "0" + time : time
alert(result);
</script>
</body>
switch
语句switch
语句;switch
是转换、开关的意思;case
小例子或者选项的意思;switch(表达式){
case value1:
执行语句1;
break;
case value2:
执行语句2;
break;
...
default:
执行最后的语句;
}
case
后面的选项值】相匹配,如果匹配上,就执行该case
里面的语句;如果都没有匹配上,那么执行default
里面的语句。switch(2){
case 1:
console.log("这是1");
break;
case 2:
console.log("这是2");;
break;
case 3:
console.log("这是3");;
break;
default:
console.log("没有匹配结果");;
}
switch
注意事项:num
的值和case
里面的值相匹配的时候是【全等】(必须是值和数据类型一致才可以);break
如果当前的case
里面没有break
,则不会退出switch
,而是继续执行下一个case
;<body>
<script>
var fruit = prompt("请输入水果:");
switch (fruit) {
case '苹果':
alert('苹果');
break;
case '榴莲':
alert('榴莲');
break;
default:
alert('没有此水果');
}
</script>
</body>
switch
语句和if else if
语句的区别:switch...case
语句通常处理case
为比较确定值的情况,而if...else...
语句更加灵活,常用于范围判断(大于、等于某个范围);switch
语句进行条件判断后直接执行到程序的条件语句,效率更高。而if...else...
语句有几种条件,就得判断多少次;if...else...
语句的执行效率比switch
语句高;switch
语句的执行效率比较高,而且结构更清晰;for
循环、while
循环、do while
循环)for
循环、while
循环、do while
循环;//for语法结构
for(初始化变量;条件表达式;操作表达式){
//循环体
}
//初始化变量:就是用var声明的一个普通变量,通常用于作为计数器使用;
//条件表达式:就是用来决定每一次循环是否继续执行,就是终止的条件;
//操作表达式:就是每次循环最后执行的代码,经常用于我们计数器变量进行更新(递增或者递减);
for
循环可以重复执行不同的代码,因为我们有计数器变量i的存在,i每次循环值都会变化;//我们想要输出1个人1~100岁
for(var i=1;i<=100;i++){
console.log('这个人今年'+i+'岁了');
}
for
循环重复某些相同操作。for
循环因为有了计数器的存在,我们还可以重复的执行某些操作,比如做一些算术运算;<body>
<!--
案例分析:
1、需要循环100次,我们需要一个计数器i;
2、我们需要一个存储结果的变量sum,但是初始值一定是0;
3、核心算法:1+2+3+4+...sum=sum+i;
-->
<script>
var sum=0;//求和的变量
for(var i=0;i<=100;i++){
sum=sum+i;
}
console.log(sum);
</script>
</body>
<script>
// 1、求1-100之间所有数的平均值;
var sum = 0;
var average = 0;
for (var i = 1; i <= 100; i++) {
sum = sum + i;
}
average = sum / 100;
console.log(average);//50.5
// 2、求1-100之间所有偶数和奇数的和;
var event = 0;
var odd = 0;
for (var i = 1; i <= 100; i++) {
if (i % 2 == 0) {
event = event + i;
} else {
odd = odd + i;
}
}
console.log(event);//2550
console.log(odd);//2500
// 3、求1-100之间所有能被3整除的数字的和;
var result = 0;
for (var i = 1; i <= 100; i++) {
if (i % 3 == 0) {
result = result + i;
}
}
console.log(result);//1683
</script>
<body>
<!-- 要求用户输入班级人数,之后依次输入每个学生的成绩,最后打印出该班级总的成绩以及平均成绩 -->
<script>
var num = prompt('请输入班级总人数:');
var sum = 0;
var average = 0;
for (var i = 1; i <= num; i++) {
var score = prompt('请输入第' + i + '个学生成绩');
// 因为从prompt取过来的数据是 字符串型的 需要装换为 数字型;
sum = sum + parseFloat(score);
}
average = sum / num;
alert('班级总的成绩是' + sum);
alert('班级平均分是' + average);
</script>
</body>
<script>
var str = '';
for (var i = 1; i <= 5; i++) {
// console.log('⭐');
// 我们采用追加字符串的方式,这样可以打印到控制台上;
str = str + '⭐';
}
console.log(str);
</script>
var num = prompt('请输入星星个数');
var str = '';
for (var i = 0; i < num; i++) {
str = str + '⭐';
}
console.log(str);
for
循环for
循环语句中,可以再嵌套一个for
循环,这样的for
循环语句我们称之为双重for
循环; <script>
var str = '';
for (var i = 1; i <= 5; i++) {
for (var j = 1; j <= 5; j++) {
str = str + '⭐';
}
// 如果一行打印完毕5个星星,就要另起一行;(加 \n)
str = str + '\n';
}
console.log(str);
</script>
<script>
var row = prompt('请输入行数');
var column = prompt('请输入列数');
var str = '';
for (var i = 1; i <=row; i++) {
for (var j = 1; j <= column; j++) {
str = str + '⭐';
}
str = str + '\n';
}
console.log(str);
</script>
<script>
var str = '';
for (var i = 1; i <= 10; i++) {
for (var j = i; j <= 10; j++) {
str = str + '⭐';
}
str = str + '\n';
}
console.log(str);
</script>
while
循环while(条件表达式){循环体}
;true
,则执行循环体;否则,退出循环;var num=1;
while(num<=100){
console.log('你好');
num++;
}
while
循环案例 <script>
// 1、打印人的一生,从1岁到100岁;
// var i=1;
// while(i<=100){
// console.log('这个人今年'+i+'岁了');
// i++;
// }
// 2、计算1~100之间所有整数的和;
// var i = 1;
// var sum = 0;
// while (i <= 100) {
// sum = sum + i;
// i++;
// }
// console.log(sum);
// 3、弹出一个提示框,你爱我吗?如果输入我爱你,就提示结束,否则,一直询问;
var message = prompt('你爱我吗?');
while (message !== '我爱你') {
message = prompt('你爱我吗?');
}
alert('我也爱你呀');
</script>
dowhile
循环dowhile
语句其实是while
语句的一个变体。该循环会先执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环;do{
//循环体
}while(条件表达式)
while
不同的地方在于dowhile
先执行一次循环体,再判断条件;如果条件表达式结果为真,则继续执行循环体,否则退出循环;<script>
// 代码验证
var i = 1;
do {
console.log('你好');
i++;
} while (i <= 100)
</script>
dowhile
语句至少会执行一次循环体代码;dowhile
案例 <script>
// 1、代码验证
// var i = 1;
// do {
// console.log('你好');
// i++;
// } while (i <= 100)
// 2、打印人的一生,从1岁到100岁;
// var i = 1;
// do {
// console.log('这个人今年'+i+'岁了');
// i++;
// } while (i <= 100)
// 3、计算1~100之间所有整数的和;
// var i = 1;
// var sum = 0;
// do {
// sum = sum + i;
// i++;
// } while (i <= 100)
// console.log(sum);
// 3、弹出一个提示框,你爱我吗?如果输入我爱你,就提示结束,否则,一直询问;
do {
var message = prompt('你爱我吗?');
} while (message !== '我爱你')
alert('我也爱你呀');
</script>
for
、while
、dowhile
;for
;while
、dowhile
可以做更复杂的判断条件,比for
灵活一些;while
和dowhile
执行顺序不一样,while
先判断,后执行;dowhile
先执行一次,再判断执行;while
和dowhile
执行次数不一样, dowhile
至少会执行一次循环体,而while
可能一次也不执行;for
循环,它的写法更简洁直观;continue
和break
关键字continue
关键字continue
之后的代码就会少执行一次);continue
关键字案例 <script>
// continue关键字(退出本次,即当前次的循环;继续执行剩余次的循环)
// for (var i = 1; i <= 5; i++) {
// if (i === 3) {
// continue; // 只要遇到continue就退出本次循环,直接跳到
// }
// console.log(i);//1 2 4 5
// }
// 案例:求1~100之间,除了能被7整除之外的整数和;
var sum = 0;
for (var i = 1; i <= 100; i++) {
if (i % 7 == 0) {
continue;
}
// sum = sum + i;
sum += i;
}
console.log(sum);
</script>
break
关键字break
关键字用于立即跳出整个循环(循环结束); // break关键字(退出整个循环)
for (var i = 1; i <= 5; i++) {
if (i == 3) {
break;//退出整个循环
}
console.log(i);// 1 2
}
<script>
// 求数组[2,6,1,77,52,25,7]中的最大值;
/*
案例分析:
(1)、声明一个保存最大元素的变量max;
(2)、默认最大值可以取数组中的第一个元素;
(3)、遍历这个数组,把里面每个数组元素和max相比较;
(4)、如果这个数组元素大于max就把这个数组元素存到max里面,否则继续下一轮比较;
(5)、最后输出这个max;
*/
var arr = [2, 6, 1, 77, 52, 25, 7];
var max = arr[0];
for (var i = 1; i <= arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
console.log(max);
</script>
length
长度以及索引号增加数组长度;length
长度来实现数组扩容的目的;length
属性是可读写的; <script>
// 1、新增数组元素-修改length长度;
var arr = ['red', 'green', 'blue'];
console.log(arr.length);
arr.length = 5;//我们把数组长度修改为了5,里面应该有5个元素;
console.log(arr);// ['red', 'green', 'blue', empty × 2]
console.log(arr[3]);//undefined
console.log(arr[4]);//undefined
// 2、新增数组元素-通过修改数组索引新增数组元素;追加数组元素;
// 之前索引号里面没有元素时是追加元素;有元素时是替换元素;
var arr1 = ['red', 'blue', 'green'];
arr1[3] = 'pink';
console.log(arr1);//['red', 'blue', 'green', 'pink']
arr1='有点意思';
console.log(arr1);//不能直接给数组名赋值,否则会覆盖掉以前的数据;
</script>
<script>
var arr = [];
for (var i = 0; i < 10; i++) {
//arr=i; //不要直接给数组名赋值,否则以前的元素都没了;
arr[i] = i+1;
}
console.log(arr);// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</script>
<script>
// 将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素选出来,放入新数组;
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var arr1 = [];
var j = 0;
for (var i = 0; i <= arr.length; i++) {
// 新数组应该从0开始,一次递增;
if (arr[i] >= 10) {
// arr1[i] = arr[i]; //[empty × 4, 77, empty, 52, empty, 25] 原因:从第四个开始有值,当i=1,2,3时是没有值存进去的;
arr1[j] = arr[i];
j++; //[77, 52, 25]
}
}
console.log(arr1);
</script>
// 筛选数组方法二:
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var arr1 = [];
for (var i = 0; i <= arr.length; i++) {
// 新数组应该从0开始,一次递增;
if (arr[i] >= 10) {
// arr1[i] = arr[i]; //[empty × 4, 77, empty, 52, empty, 25] 原因:从第四个开始有值,当i=1,2,3时是没有值存进去的;
arr1[arr1.length] = arr[i];//刚开始 arr1.length 就是0;数组的length会根据数组长度的变化而变化;
}
}
console.log(arr1);
<script>
// 方法一:
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
// for (var i = 0; i < arr.length; i++) {
// if (newArr.indexOf(arr[i]) === -1) {
// newArr.push(arr[i]);
// }
// }
// console.log(newArr);
// 方法二:
var mySet=new Set(arr);//利用了Set结构不能接收重复数据的特点;
for(var val of mySet){
newArr.push(val);
}
console.log(newArr);
</script>
<script>
// 要求:将数组['red','green','pink','blue',purper]的内容反过来存放;
var arr = ['red', 'green', 'pink', 'blue', 'purper'];
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
console.log(newArr);
</script>
var num1=10;
var num2=20;
var temp;
temp=num1;
num1=num2;
num2=temp;
console.log(num1,num2);
<script>
var arr = [5, 4, 3, 2, 1];
for (var i = 0; i <= arr.length - 1; i++) {//外层循环管趟数
for (var j = 0; j <= arr.length - i - 1; j++) {//里面的循环管每一趟的交换次数;
// 内部交换两个变量的值,前一个和后面一个数组元素相比较;
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
</script>
function 函数名(){
//函数体
}
函数名()
<script>
function getSum() {
var sum = 0;
for (var i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);
}
getSum();
</script>
function 函数名(形参1,形参2,...){
}
函数名(实参1,实参2,...);
<script>
// 1、利用函数求任意两个数的和
function getSum(num1, num2) {
console.log(num1 + num2);
}
getSum(1, 3);
// 2、利用函数求任意两个数之间的和
function getSums(start, end) {
var sum = 0;
for (var i = start; i <= end; i++) {
sum += i;
}
console.log(sum);
}
getSums(1, 100);
</script>
undefined
,最终的结果就是NaN
;undefined
;function getSum(num1,num2){
console.log(num1+num2);
}
getSum(1,2);
getSum(1,2,3);
getSum(1);//NaN (任何数字 + undefined = NaN )
return
return
语句就可以实现;function 函数名(){
return 需要返回的结果;
}
函数名();
return
来实现的;return
,就把后面的结果返回给函数的调用者;return
后面的结果;function getResult(){
return 666;
}
getResult()
console.log(getResult());//666
function getSum(num1,num2){
return num1 + num2;
}
console.log(getSum(1,2));
<script>
function getMax(num1, num2) {
// if (num1 > num2) {
// return num1;
// } else {
// return num2;
// }
return num1 > num2 ? num1 : num2;
}
console.log(getMax(6, 2));
</script>
<script>
// var arr=[5,2,99,101,67,77];
function getArrMax(arr) {// arr 接收一个数组
var max = arr[0];
for (var i = 1; i <= arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
// console.log(getArrMax([5, 2, 99, 101, 67, 77]));//实参是一个数组送过去
var re = getArrMax([5, 2, 99, 101, 67, 77]);
console.log(re);
</script>
return
终止函数并且只能返回一个值return
终止函数,return
语句之后的代码不被执行;function getSum(num1,num2){
return num1+num2;
alert("我是不会被执行的");//return 后面的的代码不会被执行
}
console.log(getSum(1,2));
return
只能返回一个值。如果用逗号隔开多个值,以最后一个为准;function fn(num1,num2){
return num1,num2;//返回的结果是最后一个值
}
console.log(fn(1,2));
function getResult(num1,num2){
return [num1+num2,num1-num2,num1*num2,num1/num2];
}
console.log(fn(1,2));//返回的是一个数组
return
,返回undefined
;return
,则返回的是return
后面的值;如果函数没有return
,则返回undefined
;break
、continue
、return
的区别当我们不确定有多少个参数传递的时候,可以用arguments
来获取,在JS中,arguments
实际上它是当前函数的一个【内置对象】。所有函数都内置了一个arguments
对象,arguments
对象中【存储了传递的所有实参】;
<script>
function fn() {
console.log(arguments); // Arguments(3),arguments是以伪数组的形式来展示的;
//我们可以按照数组的方式遍历 Arguments;
}
fn(1, 2, 3)
/*
伪数组并不是真正意义上的数组:
1、具有数组的 length 属性;
2、按照索引的方式进行存储的;
3、没有真正数组的一些方法,如:pop()、push() 等;
*/
</script>
<script>
// 1、利用函数关键字自定义函数(命名函数)
function fn() { }
fn()
// 2、函数表达式(匿名函数)
//注意:函数表达式声明方式跟变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数;
// var 变量名 = function(){}
var fun = function () { } // 注意:此处的 fun 是变量名,不是函数名;
fun() // 变量名 + ()实现调用;函数表达式也可以进行传递参数;
</script>
arguments
案例:利用函数求任意几个数的最大值 <script>
function getMax() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(7, 2, 5, 99, 0, 2346));
</script>
<script>
function getArrReverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
console.log(getArrReverse([1, 2, 3, 4, 5]));
</script>
<script>
function sort(arr) {
for (var i = 0; i <= arr.length - 1; i++) {
for (var j = 0; j <= arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
console.log(sort([5, 7, 3, 2, 0, 8, 1]));
</script>
<script>
// 闰年:能被4整除并且不能被100整除;或者能被400整除;
// function isRunYear(year){
// if(year % 4 === 0 && year % 100 !=0 || year % 400 === 0){
// return year+'年是闰年';
// }else{
// return year+'年是平年';
// }
// }
// console.log(isRunYear(2020));
function isRunYear(year){
// 如果是闰年我们返回true;否则返回false;
var flag = false;
if(year % 4 === 0 && year % 100 !=0 || year % 400 === 0){
flag = true;
}
return flag;
}
console.log(isRunYear(2000));
</script>
function fn1(){
console.log(11);
fn2();//在fn1函数里面调用了fn2函数;
}
fn1();
function fn2(){
console.log(22);
}
<script>
function backDay(){
var year = prompt('请输入年份');
if(isRunYear(year)){//调用函数需要加小括号
alert('当前年份是闰年,2月份有29天');
}else{
alert('当前年份是平年,2月份有28天');
}
}
backDay();
// 判断是否为闰年的函数
function isRunYear(year){
// 如果是闰年我们返回true;否则返回false;
var flag = false;
if(year % 4 === 0 && year % 100 !=0 || year % 400 === 0){
flag = true;
}
return flag;
}
</script>
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的【可用性的代码范围】就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字的冲突。
Javascript作用域: 就是代码名字(变量)在某个范围内起作用和效果;目的是为了提高程序的可靠性,更重要的是减少命名冲突;js作用域(es6)之前:全局作用域 局部作用域;
全局作用域: 【整个 script 标签】或者是一个【单独的js文件】
局部作用域(函数作用域): 在函数内部就是局部作用域;这个代码的名字只在函数内部起效果和作用;
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为作用域链。(就近原则)
// 1问
console.log(num) // 报错
// 2问
console.log(num) // undefined 坑1
var num=10
// 相当于执行了以下代码
var num ;
console.log(num)
num=10
// 3问
fn() // 11
function fn(){
console.log(11)
}
fn() // 11
// 4问
fun() // 报错 fun is not a function
var fun=function(){ // 函数表达式 调用必须写在函数表达式的下面
console.log(22)
}
fun() // 22
//相当于执行了以下代码
var fun ;
fun();
fun=function(){
console.log(22)
}
var a=b=c=9;
// 相当于:var a=9;b=9;c=9 区别于【集体声明】
//所以此处的 b 和 c 直接赋值,没有 var 声明,此处的 b 和 c 当全局变量看;
// 集体声明(用逗号隔开)
var a=9,b=9,c=9
//构造函数的语法格式
function 构造函数名(){
this.属性=值
this.方法=functon(){}
}
new 构造函数名() //调用构造函数
function Star(uname,age,sex){
this.name=uname;
this.age=age;
this.sex=sex;
this.sing=function(sang){
console.log(sang)
}
}
// 调用函数返回的是一个对象
var ldh = new Star('刘德华',18,'男')
ldh.sing('冰雨');
console.log(typeof ldh)
console.log(ldh.name)
console.log(ldh['sex'])
注意:
1、构造函数名字首字母要大写;
2、我们构造函数不需要return 就可以返回结果;
3、我们调用构造函数,必须使用new;
4、我们只要 new Sar()
调用函数,就创建一个对象;
5、我们的属性和方法前面必须添加this
;
1、new
构造函数可以在内存中创建了一个空的对象;
2、this
就指向刚才创建的空对象;
3、执行构造函数里面的代码,给这个空对象添加属性和方法;
4、返回这个新对象(所以构造函数里面不需要return
);
for...in
语句用于对【数组】或者【对象的属性】进行【循环】操作;//for in 遍历对象
// 语法规则:for (变量 in 对象){}
for(var k in obj){
console.log(k); // k:变量,输出得到的是:属性名
console.log(obj[k]); // obj[k] 得到的是:属性值
//注意:此处的 k 是一个变量,无需用引号包裹;
// 我们使用 for in 时,里面的变量,我们喜欢写 k 或者 key
// for in 也可以遍历出对象里面的方法
}
Object
;for in
语句用于对对象的属性进行循环操作;ECMAScript
;第三个浏览器对象属于我们JS独有的;Math
、Date
、Array
、String
等;//利用对象封装自己的数学对象,里面有 PI 最大值和最小值
var myMath={
PI:3.141592653,
max:function(){
var max=arguments[0];
for(var i=1;i<arguments.length;i++){
if(arguments[i]>max){
max=arguments[i]
}
}
return max;
},
min:function(){
var min=arguments[0];
for(var i=1;i<arguments.length;i++){
if(arguments[i]<min){
min=arguments[i]
}
}
return min;
}
}
// 猜数字游戏案例
function getRandom(min,max){
return Math.floor(Math.random() * (max-min + 1)) + min;
}
var random =getRandom(1,10);
while(true){ //死循环
var num = prompt('你来猜?输入1~10之间的一个数字');
}
if(num>random){
alert('你猜大了')
}else if(num<random){
alert('你猜小了')
}else{
alert('猜对了!')
break; // 退出整个循环,结束程序
}
Date()
)new
来调用创建我们的日期对象;Date()
,如果没有参数,返回当前系统的当前时间;2019,10,01
或者是字符串型:2019-10-1 8:8:8
//格式化日期年月日星期(星期天返回的是0)
var arr=['星期天','星期一','星期二','星期三','星期四','星期五','星期六']
var date=new Date();
var day=date.getDay();
console.log(arr[day])
//封装一个函数返回当前的时分秒,格式:08:08:08
function getTimer(){
var time=new Date();
var h=time.getHours();
h = h<10?'0'+h:h
var m=time.getMinutes()
m = m<10?'0'+m:m
var s=time.getSeconds()
s = s<10?'0'+s:s
return h+':'+m+':'+s
}
console.log(getTimer())
length
属性呢?var str = 'andy';
console.log(str.length);
var temp = new Sring('andy');
str = temp;
temp = null;
// 案例:查找字符串“abcoefoxyozzopp”中所有o出现的位置以及次数;
/*
核心算法:先查找第一个o出现的位置,然后,只要 indexOf 返回的结果不是 -1,就继续往后查找;因为 indexOf 只能查找到第一个,所以后面的查找一定是当前索引加1,从而继续查找;
*/
var str = 'abcoefoxyozzopp'
var index = str.indexOf('o')
var num = 0;
while(index !== -1){
console.log(index)
num++
index = str.indexOf('0',index+1);
}
console.log('o出现的次数是' + num)
//案例:遍历字符串
// charAt(index) 根据位置返回字符
var str= 'andy'
console.log(str.charAt(3))
//遍历所有字符串
for(var i=0;i<str.length;i++){
console.log(str.charAt(i))
}
// 有一个对象,判断该对象里有没有该属性 对象['属性名']
var o={
age:18
}
if(o['age']){
console.log('里面有该属性')
}else{
console.log('里面没有该属性')
}
// 案例:统计字符串 'abcoefoxyozzopp' 中出现次数最多的字符
/*
核心算法:利用 charAt() 遍历这个字符串;把每个字符都存储给对象,如果对象没有该属性,就为1,如果存在了就 +1;遍历对象,得到最大值和该字符;
*/
var str = 'abcoefoxyozzopp';
var o ={}
for(var i=0;i<str.length;i++){
var charts=str.charAt(i) // charts 是字符串的每一个字符
if(o[charts]){ //o[charts]得到的是属性值
o[charts]++
}else{
o[charts]=1
}
}
console.log(o)
// 遍历对象,求出出现最多的次数
var max = 0;
var ch = '';//统计出现次数最多的字符
for(var k in o){ //遍历对象用 for in
// k 得到的是属性名
// o[k] 得到的是属性值
if(o[k]>max){
max=o[k];
ch=k
}
}
console.log(max)
console.log(ch)
str.replace('被替换的字符','替换为的字符')
,只会替换第一个字符;//案例:有一个字符 'abcoefoxyozzopp' ,要求把里面所有的 o 替换为 *;(该方法可用于实现过滤敏感词等功能)
var str = 'abcoefoxyozzopp';
while(str.indexOf('o') !== -1){
str = str.replace('o','*')
}
console.log(str)
function fn(a) {
a++
console.log(a); // 11
}
var x = 10
fn(x)
console.log(x);// 10
function Person(name){
this.name=name
}
function f1(x){//x=p
console.log(x.name)//2、这里输出什么?刘德华
x.name='张学友'
console.log(x.name)//3、这里输出什么?张学友
}
var p=new Person('刘德华')
console.log(p.name)//1、这里输出什么?刘德华
f1(p)
console.log(p.name)//4、这里输出什么?张学友
var ol=document.getElementsByTagName('ol') console.log(ol[0].document.getElementsByTagName('li') )
简单做法:给父元素添加ID,通过ID获取父元素,然后获取父元素里面的子元素;Document.getElementsByClassName()
、Document.querySelector('选择器')
(根据指定选择器返回第一个元素对象)、Document.querySelectorAll('选择器')
(根据指定选择器返回所有元素对象集合)document.body
document.documentElement
<button id='btn'>按钮</button>
var btn=document.getElementById('btn');
btn.onclick=function(){
alert('弹窗')
}
element.innerText
从起始位置到终止位置的内容,但它取出html
标签,同时空格和换行也会去掉;(不识别html标签)非标准 去除空格和换行<button>点击改变时间</button>
<div>写死的时间</div>
<p>123</p>
<script>
// 1、获取元素
var btn = document.querySelector('button');
var div = document.querySelector('div')
// 注册事件
btn.onclick = function () {
// div.innerText = '2022-1-2'
div.innerText = getDate()
}
function getDate() {
var date = new Date()
var year = date.getFullYear();
var month = date.getMonth();
var dates = date.getDate();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
var day = date.getDay();
return '今天是:' + year + '年' + month + '月' + dates + '日' + arr[day]
}
// 我们元素可以不用添加事件
var p = document.querySelector('p')
p.innerText = getDate()
</script>
element.innerHTML
起始位置到终止位置的全部内容,包括html
标签,同时保留空格和换行;(识别html标签)W3C标准 保留空格和换行var p = document.querySelector('p')
p.innerHTML = '今天是:2022-1-2' //实现给‘今天是’加粗
<p>
我是文字
<span>123</span>
</p>
var p=document.querySelector('p')
console.log(p.innerText)//我是文字 123
console.log(p.innerHTML)//我是文字 123(空格和换行依然保留)
innerText
、innerHTML
改变元素内容;src
、href
;id
、alt
、title
;//案例:分时问候案例
<img src="./images/shangwu.jpg" alt="">
<div>上午好</div>
<script>
// 获取元素
var img = document.querySelector('img')
var div = document.querySelector('div')
// 得到当前的小时数
var date = new Date();
var h = date.getHours();
// 判断小时数改变图片和文字信息
if (h < 12) {
img.src = './images/shangwu.jpg'
div.innerHTML = '上午好'
} else if (h < 18) {
img.src = './images/xiawuhao.jpg'
div.innerHTML = '下午好'
} else {
img.src = './images/wanshanghao.jpg'
div.innerHTML = '晚上好'
}
</script>
type
value
checked
selected
disabled
//1、获取元素
var btn= document.querySelector('button')
var input= document.querySelector('input')
//2、注册事件 处理程序
btn.onclick=function(){
//btn.disabled=true //禁用按钮
this.disabled=true //this 指向的是事件函数的调用者
}
//案例:仿京东显示隐藏密码明文案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>显示隐藏密码案例</title>
<style>
.box {
position: relative;
width: 400px;
border-bottom: 1px solid #ccc;
margin: 100px auto;
}
.box input {
width: 370px;
height: 30px;
border: 0;
outline: none;
}
.box img {
position: absolute;
top: 2px;
right: 2px;
width: 24px;
}
</style>
</head>
<body>
<div class="box">
<label for="">
<img src="./images/green_close_eye.png" alt="" id="eye">
</label>
<input type="password" name="" id="pwd">
</div>
<script>
var eye = document.getElementById('eye')
var pwd = document.getElementById('pwd')
//方法1: 利用flag变量记录点击
var flag = 0
eye.onclick = function () {
// 点击一次过后,flag一定要变化
if (flag == 0) {
pwd.type = 'text'
eye.src='./images/green_open_eye.png'
flag = 1;//赋值操作
} else {
pwd.type = 'password'
eye.src='./images/green_close_eye.png'
flag = 0;
}
}
//方法2: 计数器思想记录点击
var count = 0;
eye.onclick = function () {
count++
if (count % 2 == 0) {
eye.src = "./images/green_close_eye.png"
pwd.type = "password"
} else {
eye.src = "./images/green_open_eye.png"
pwd.type = "text"
}
}
</script>
</body>
</html>
element.style
行内样式操作;element.className
类名样式操作;fontSize
backgroundColor
;JS修改style样式操作,产生的是行内样式,CSS权重比较高;//案例:循环精灵图背景;可以利用for循环设置一组元素的精灵图背景。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>循环遍历精灵图</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
.box {
width: 250px;
margin: 100px auto;
}
.box li {
float: left;
width: 24px;
height: 24px;
background-color: pink;
margin: 15px;
background: url(./images/icons.png) no-repeat;
}
</style>
</head>
<body>
<div class="box">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<script>
// 1、获取所有元素,所有的li
var lis = document.querySelectorAll('li')
// 2、让索引号 乘以 44 就是每个 li 的背景y坐标,index就是我们的y坐标;
for (var i = 0; i < lis.length; i++) {
var index = i * 24 //我这张精灵图是24
lis[i].style.backgroundPosition = '0-' + index + 'px'//精灵图的y坐标是负的;x坐标永远是0
//lis[i].style.backgroundPosition = '0 0' //全部展示第一张图片
//lis[i].style.backgroundPosition = '0 -24px' //全部展示第二张图片
}
</script>
</body>
</html>
//案例:当鼠标点击文本框时,里面的默认文字隐藏;当鼠标离开文本框时,里面的文字显示;
//`onfocus` `onblur`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>显示隐藏文本框内容案例</title>
<style>
input {
color: #999;
}
</style>
</head>
<body>
<input type="text" value="手机">
<script>
var text = document.querySelector('input')
text.onfocus = function () {
console.log('得到了焦点');
if (this.value === '手机') {
this.value = ''
}
this.style.color = '#333'//获得焦点时把文本框里的文字的颜色变深
}
text.onblur = function () {
console.log('失去了焦点');
if (this.value === '') {
this.value = '手机'
}
this.style.color = '#999'//失去焦点时把文本框里的文字的颜色变浅
}
</script>
</body>
</html>
element.style
行内样式操作;element.className
类名样式操作;<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用className修改样式属性</title>
<style>
div{
width: 50px;
height: 50px;
background-color: green;
}
.change{
width: 100px;
height: 100px;
background-color: aqua;
margin-top: 100px;
}
</style>
</head>
<body>
<div class='fist'>文本</div>
<script>
var test=document.querySelector('div')
test.onclick=function(){
//我们可以通过 修改元素的 className 更改元素的样式,适合于样式较多或者功能复杂的情况
this.className='change'//点击时给div加上change的类名
//如果想要保留原先的类名,我们可以这么做 ---> 多类名选择器
this.className='fist change'
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>密码框验证信息案例</title>
<style>
div {
width: 600px;
margin: 100px auto;
}
.message {
display: inline-block;
font-size: 12px;
color: #999;
background: url(./images/reg.jpg) no-repeat left center;
padding-left: 20px;
}
.wrong {
color: red;
background-image: url(./images/wrong.jpg);//注意:此处不用写no-repeat left center
}
.right {
color: green;
background-image: url(./images/right.jpg);//注意:此处不用写no-repeat left center
}
</style>
</head>
<body>
<div class="register">
<input type="password" class="ipt">
<p class="message">请输入6~16位密码</p>
</div>
<script>
var ipt = document.querySelector('.ipt')
var messege = document.querySelector('.message')
ipt.onblur = function () {
if (this.value.length < 6 || this.value.length > 16) {
messege.className = 'message wrong';
messege.innerHTML = '你输入的位数不对,要求6~16位'
} else {
messege.className = 'message right';
messege.innerHTML = '你输入的正确'
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>排他思想</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
// 首先先排除其他人,然后才设置自己的样式,这种排除其他人的思想我们称为排他思想
var btns = document.querySelectorAll('button')
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
// 1、我们先把所有按钮的背景颜色去掉
for (var i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = ''
}
// 2、然后才让当前的元素背景颜色为pink
this.style.backgroundColor = 'pink'
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>百度换肤效果案例</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
background: url(./images/01.jpeg) no-repeat center top;
}
.baidu {
overflow: hidden;
margin: 100px auto;
background-color: #fff;
width: 410px;
padding-top: 3px;
}
.baidu li {
/* list-style: none; */
float: left;
margin: 0 1px;
cursor: pointer;
}
.baidu img {
width: 100px;
}
</style>
</head>
<body>
<ul class="baidu">
<li><img src="./images/01.jpeg" alt=""></li>
<li><img src="./images/02.jpeg" alt=""></li>
<li><img src="./images/03.jpeg" alt=""></li>
<li><img src="./images/04.jpeg" alt=""></li>
</ul>
<script>
// 1、获取元素(类名是 baidu 下的 img)
var imgs = document.querySelector('.baidu').querySelectorAll('img')
// 2、循环注册事件
for (var i = 0; i < imgs.length; i++) {
imgs[i].onclick = function () {
// this.src 就是我们点击的图片的路径
// 把这个路径 this.src 给 body 就可以了
//document.body.style.backgroundImage获取body的背景图片
document.body.style.backgroundImage = 'url(' + this.src + ')'
}
}
</script>
</body>
</html>
//onmouseover鼠标经过 onmouseout鼠标离开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表格隔行变色效果案例</title>
<style>
table{
width: 800px;
margin: 100px auto;
text-align: center;
border-collapse: collapse;//设置表格的边框是否被合并为一个单一的边框
font-size: 14px;
}
thead tr{
height: 30px;
background-color: skyblue;
}
tbody tr{
height: 30px;
}
tbody td{
border-bottom: 1px solid #d7d7d7;
color: blue;
}
.bg{
background-color: pink;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>代码</th>
<th>名称</th>
<th>最新公布净值</th>
<th>累计净值</th>
<th>前单位净值</th>
<th>净值增长率</th>
</tr>
</thead>
<tbody>
<tr>
<td>003526</td>
<td>农行金穗3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
<tr>
<td>003527</td>
<td>农行金穗4个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
</tbody>
</table>
<script>
// 1、获取元素 获取 tbody 里面所有的 tr
var trs=document.querySelector('tbody').querySelectorAll('tr')
// 2、利用循环绑定注册事件
for(var i=0;i<trs.length;i++){
// 3、鼠标经过事件 onmouseover
trs[i].onmouseover=function(){
this.className='bg';
}
// 4、鼠标离开事件 onmouseout
trs[i].onmouseout=function(){
this.className='';
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表单全选取消全选案例</title>
<style>
.wrap {
width: 300px;
margin: 100px auto;
}
table {
width: 100%;
margin: 100px auto;
text-align: center;
border-collapse: collapse;
font-size: 14px;
}
thead tr {
height: 30px;
background-color: skyblue;
}
tbody tr {
height: 30px;
}
tbody td {
border-bottom: 1px solid #d7d7d7;
}
</style>
</head>
<body>
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="j_cbAll">
</th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td>
<input type="checkbox">
</td>
<td>iphone8</td>
<td>8000</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>iphone9</td>
<td>9000</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>iphone10</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<script>
// 第一步:全选和取消全选的做法:让下面所有复选框的checked属性(选中状态)跟随 全选按钮即可
// 1、获取元素
var j_cbAll = document.getElementById('j_cbAll'); // 全选按钮
var j_tbs = document.getElementById('j_tb').getElementsByTagName('input');//下面所有的复选框
// 2、注册事件
j_cbAll.onclick = function () {
// this.checked 它可以得到当前复选框的选中状态,如果是 true 就选中,如果是 false ,就是未选中;
console.log(this.checked);
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].checked = this.checked;//将全选按钮的选中或未选中状态赋值给所有的 checkbox
}
}
//第二步:下面复选框需要全部选中,上面全选才能选中做法:给下面所有复选框绑定点击事件,每次点击,都要循环遍历
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].onclick = function () {
// flag 控制全选按钮是否选中
var flag = true
// 每次点击下面的复选框都要循环检查这四个小按钮是否全被选中
for (var i = 0; i < j_tbs.length; i++) {
if (!j_tbs[i].checked) {
flag = false;
break;//退出for循环,这样可以提高执行效率;因为只要有一个没有选中,剩下的就循环判断了;
}
}
j_cbAll.checked = flag
}
}
</script>
</body>
</html>
element.属性
获取属性值;<div id='demo'></div>
var div=document.querySelector('div')
// 获取元素的属性
// 方法1:element.属性
console.log(div.id); // demo
element.getAttribute('属性')
attribute 本意“属性”;<div id='demo'></div>
var div=document.querySelector('div')
// 获取元素的属性
// 方法2:element.getAttribute('属性')
console.log(div.getAttribute('id')); // demo
element.属性
获取属性值 和 element.getAttribute('属性')
获取属性值 的区别?element.属性
获取内置属性值(元素本身自带的属性)如:id class等;element.getAttribute('属性')
主要获得自定义的属性(标准)我们程序员自定义的属性;element.属性 = '值'
设置内置属性值;<div id='demo' class='nav'></div>
var div = document.querySelector('div')
div.className= 'sss'
element.setAttribute('属性','值')
;主要针对于自定义属性;<div id='demo' index='1' class='nav'></div>
var div = document.querySelector('div')
div.setAttribute('index','2')
// class比较特殊,这里面写的就是class,不是className
div.setAttribute('class','sss')
element.removeAttribute('属性')
<div id='demo' index='1' class='nav'></div>
var div = document.querySelector('div')
div.removeAttribute('index')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tab栏切换案例</title>
<style>
.tab {
width: 1200px;
height: 100px;
}
.tab_list {
width: 100%;
float: left;
}
.tab_con {
width: 100%;
float: left;
padding: 20px 60px;
}
.tab_list ul{
width: 95%;
height: 39px;
background: rgb(223, 221, 221);
}
.tab_list li {
float: left;
height: 39px;
line-height: 39px;
padding: 0 20px;
text-align: center;
cursor: pointer;
list-style: none;
}
.tab_list .current {
background-color: #c81623;
color: #fff;
}
.item_info {
padding: 20px 0 0 20px;
}
.item {
display: none;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<div class="item" style="display: block;">
商品介绍模块内容
</div>
<div class="item">
规格与包装模块内容
</div>
<div class="item">
售后保障模块内容
</div>
<div class="item">
商品评价模块内容
</div>
<div class="item">
手机社区模块内容
</div>
</div>
</div>
<script>
// 先获取父组件,再获取父组件下的所有的li
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
var items = document.querySelectorAll('.item')
// for循环绑定点击事件
for (var i = 0; i < lis.length; i++) {
// 开始给5个小li 设置索引号
lis[i].setAttribute('index', i) // element.setAttribute('属性','值')
// 1、上面的模块选项卡:点击某一个,当前这个底色会是红色,其余不变(排他思想) 修改类名的方式
// 干掉所有人,其余的li清除class这个类
lis[i].onclick = function () {
for (var i = 0; i < lis.length; i++) {
lis[i].className = '';
}
// 留下我自己
this.className = 'current'
/*
2、下面的显示内容模块:下面的模块显示内容和上面的选项卡一一对应,相匹配;
给上面的tab_list里面的所有小li添加自定义属性,属性值从0开始编号;
*/
var index = this.getAttribute('index')//element.getAttribute('属性')
console.log(index);
// 干掉所有人,让其余的item 这些div隐藏
for (var i = 0; i < lis.length; i++) {
items[i].style.display = 'none'
}
// 留下我自己,让对应的item显示出来
items[index].style.display = 'block'
}
}
</script>
</body>
</html>
element.getAttribute('属性')
获取;但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性;<div getTime='20'></div>
// getTime 是自定义属性,只能通过 getAttribute 获取
var div = document.querySelect('div')
console.log(div.getTime) // undefined
console.log(div.getAttribute('getTime'))
data-
开头作为属性名并且赋值;<div data-index='1'></div>
// 或者使用JS设置 element.setAttribute('data-index',2)
div.setAttribute('data-time',20)
element.getAttribute('data-index')
;element.dataset.index
或者 element.dataset['index']
ie11才开始支持;(只能获取以data-
开头的)<div getTime="20" data-index="2" data-list-name="andy"></div>
<script>
var div=document.querySelector('div')
// H5新增的获取自定义属性的方法
// dataset 是一个【集合】,里面存放了所有以data开头的自定义属性
console.log(div.dataset);// DOMStringMap {index: '2'}
console.log(div.dataset.index);// 2
console.log(div.dataset['index']);// 2
// 如果自定义属性里面有多个 - 连接的单词,我们获取的时候采用【驼峰命名法】
console.log(div.dataset.listName); //andy
</script>
document.getElementById()
等;这种方法逻辑性不强、繁琐;node
来表示;HTML DOM
树中的所有节点均可以通过JavaScript
进行访问,所有HTML
元素(节点)均可被修改,也可以创建和删除;nodeType
(节点类型)、nodeName
(节点名称)、nodeValue
(节点值)这三个基本属性;nodeType
为1;nodeType
为2;nodeType
为3;(文本节点包含文字、空格、换行等)<div class="box"></div>
var box=document.querySelector('.box')
console.dir(box)
DOM
树可以把节点划分为不同的层级关系,常见的是【父子兄层级关系】;node.parentNode
null
;<div class="box">
<span class="erweima"></span>
</div>
//获取父节点
var erweima=document.querySelector('.erweima')
//获取 erweima 节点的父节点;得到的是离元素最近的父级节点
erweima.parentNode
parentNode.childNodes
(标准)(获取到的是所有的子节点,包含 元素节点、文本节点等)parentNode.childNodes
返回包含指定节点的子节点的集合,该集合为即时更新的集合;childNodes
;<ul>
<li></li>
<li></li>
<li></li>
</ul>
//DOM提供的方法(API)获取
var ul=document.querySelector('ul')
var lis=ul.querySelectorAll('li')
//子节点(获取到的是所有的子节点,包含 元素节点、文本节点等)
console.log(ul.childNodes)
var ul=document.querySelector('ul')
for(var i=0;i<ul.childNodes.length;i++){
if(ul.childNodes[i].nodeType == 1){
//ul.childNodes[i]是元素节点
console.log(ul.childNodes[i])
}
}
parentNode.children
(非标准):是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(这个是我们重点掌握的);虽然parentNode.children
是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用。//children 获取所有的子元素节点(也是我们实际开发常用的)
var ul=document.querySelector('ul')
console.log(ul.children )
<ol>
<li></li>
<li></li>
<li></li>
</ol>
var ol=document.querySelector('ol')
//1、firstChild 第一个子节点,不管是文本节点还是元素节点;找不到就返回 null
console.log(ol.firstChild)
console.log(ol.lastChild)
//2、firstElementChild 返回第一个子元素节点
console.log(ol.firstElementChild)
console.log(ol.lastElementChild)
parentNode.firstElementChild
、parentNode.lastElementChild
注意:这两个方法有兼容性问题,IE9 以上才支持;firstChild
和 lastChild
包含其他节点,操作不方便;而firstElementChild
lastElementChild
又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?parentNode.children[0]
;//实际开发的写法,既没有兼容性问题又返回第一个子元素
console.log(ol.children[0])
console.log(ol.children[3])//第四个子元素
//得到最后一个子元素
console.log(ol.children[ol.children.length-1])
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
</ul>
<script>
// 1、获取元素
var nav = document.querySelector('.nav');
var lis = nav.children; //得到四个小li
// 2、循环遍历事件
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function () {
this.children[1].style.display = 'block'
}
lis[i].onmouseout = function () {
this.children[1].style.display = 'none'
}
}
</script>
node.nextSibling
、 node.previousSibling
、node.nextElementSibling
、node.previousElementSibling
node.nextSibling
返回当前元素的下一个兄弟节点(包括【元素节点】 和 【文本节点】等等),找不到就返回null;同样,也是包含所有的节点;<div>我是div</div>
<span>我是span<span>
var div=document.querySelector('div')
console.log(div.nextSibling) //得到div的兄弟节点,包括元素节点 和 文本节点 #text
node.previousSibling
返回当前元素的上一个兄弟节点(包括【元素节点】 和 【文本节点】等等),找不到就返回null;同样,也是包含所有的节点;node.nextElementSibling
返回当前元素下一个兄弟元素节点,找不到就返回null;node.previousElementSibling
返回当前元素上一个兄弟元素节点,找不到就返回null;node.nextElementSibling
、node.previousElementSibling
这两个方法有兼容性问题,IE9以上才支持;function getNextElementSibling(element){
var el=element;
while(el=el.nextSibling){
if(el.nodeType === 1){
return el;
}
}
return null
}
document.createElement('tagName')
document.createElement()
方法创建由tagName
指定的HTML
元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称之为【动态创建元素节点】;<ul></ul>
//创建元素节点(只是创建了节点,未添加到页面上)
var li=document.createElement('li');
node.appendChild(child)
、 node.insertBefore(child,指定元素)
node.appendChild(child)
方法将一个节点添加到指定父节点的子节点列表【末尾】。类似于css
里面的after
伪元素;(node
是父级;child
是子级)<ul></ul>
//创建元素节点(只是创建了节点,未添加到页面上)
var li=document.createElement('li');
var ul=document.querySelector('ul')
//将节点添加到页面上
ul.appendChild(li)
node.insertBefore(child,指定元素)
方法将一个节点添加到父节点的指定子节点的【前面】。类似于css
里面的before
伪元素;<ul></ul>
//创建元素节点(只是创建了节点,未添加到页面上)
var lili=document.createElement('li');
var ul=document.querySelector('ul')
//将节点添加到ul的第一个子节点的前面上
ul.insertBefore(lili,ul.children[0])
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简单版发布留言案例</title>
</head>
<body>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button>发布</button>
<ul></ul>
<script>
// 1、获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2、注册事件
btn.onclick = function () {
if (text.value == '') {
alert('你没有输入内容')
return false
} else {
// (1)、创建元素
var li = document.createElement('li');
// 先有li才能赋值
li.innerHTML = text.value
// (2)、添加元素
// ul.appendChild(li) //添加到最后
// 添加到最前面
ul.insertBefore(li,ul.children[0])
}
}
</script>
</body>
</html>
node.removeChild(child)
node.removeChild(child)
方法从DOM
中删除一个子节点,返回删除的节点;<button>删除</button>
<ul>
<li>熊大</li>
<li>熊二</li>
<li>光头强</li>
<ul>
//1、获取元素
var ul=document.querySelector('ul');
//2、删除元素
//ul.removeChild(ul.children[0]) //删除“熊大”
//3、点击按钮,依次删除里面的孩子
var btn=document.querySelector('button');
btn.onclick=function(){
if(ul.children.length == 0){
this.disabled= 'true' // 元素删完让按钮置灰
}else{
ul.removeChild(ul.children[0])
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简单版发布留言案例</title>
<style>
li {
width: 300px;
padding: 5px;
background-color: pink;
color: red;
font-size: 14px;
margin: 15px 0;
}
li a {
float: right;
}
</style>
</head>
<body>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button>发布</button>
<ul></ul>
<script>
// 1、获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2、注册事件
btn.onclick = function () {
if (text.value == '') {
alert('你没有输入内容')
return false
} else {
// (1)、创建元素
var li = document.createElement('li');
// 先有li才能赋值
// 小技巧:阻止连接跳转需要添加 javascript:void(0); 或 javascript:;
li.innerHTML = text.value + "删除"
// (2)、添加元素
// ul.appendChild(li) //添加到最后
// 添加到最前面
ul.insertBefore(li, ul.children[0])
// (3)、删除元素 删除的是当前链接的li,它的父亲 this.parentNode
var as = document.querySelectorAll('a')
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
ul.removeChild(this.parentNode);
}
}
}
}
</script>
</body>
</html>
连接跳转需要添加javascript:void(0);
或 javascript:;
如:删除
node.cloneNode()
node.cloneNode()
方法返回调用该方法的节点的一个副本。也称为【克隆节点】或【拷贝节点】;<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
var ul=document.querySelector('ul')
//1、克隆节点,第一个li
var lili= ul.children[0].cloneNode()
//2、将克隆的第一个节点放到页面中
ul.appendChild(lili)
node.cloneNode()
true
即可(既复制标签,也复制里面的内容);node.cloneNode(true)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态生成表格案例</title>
<style>
table {
width: 500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
</style>
</head>
<body>
<table cellspacing="'0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1、先准备好学生的数据
var datas = [
{ name: '张三', subject: 'javaSript', score: 100 },
{ name: '李四', subject: 'javaSript', score: 100 },
{ name: '王五', subject: 'javaSript', score: 100 },
]
// 2、往 tbody 里面创建行,有几个人(通过数组的长度)我们就创建几行;
var tbody = document.querySelector('tbody')
for (var i = 0; i < datas.length; i++) { //外面的for循环管行 tr
// 创建 tr 行
var tr = document.createElement('tr')
tbody.append(tr) //将创建的 tr 放到 tbody 里
// 行里面创建单元格 td (跟数据有关系的三个单元格),单元格的数量取决于每个对象里面的属性个数 for循环遍历对象
for (var k in datas[i]) { //里面的for循环管列 td
//创建单元格
var td = document.createElement('td')
// 把对象里面的属性值 datas[i][k] 给 td
console.log(datas[i][k]); //对象里面的属性值
td.innerHTML = datas[i][k];
tr.append(td) //将创建好的 td 放到 tr 里
}
// 3、创建有删除2个字的单元格
var td = document.createElement('td');
td.innerHTML = '删除';
tr.appendChild(td)
}
// 4、删除操作
var as = document.querySelectorAll('a')
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
// 点击a,删除当前a所在的行(链接的爸爸的爸爸)
tbody.removeChild(this.parentNode.parentNode)
}
}
// 复习:for in 遍历对象
// for(var k in obj){
// k 得到的是属性名
// obj[k] 得到的是属性值
// }
</script>
</body>
</html>
document.write
创建元素document.write
是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘;(页面上之前的元素被清除,重新创建了一个新的页面,新页面上只展示document.write创建的元素)<button>点击</button>
<p>abdjk</p>
<script>
// document.write 会导致页面重绘(页面上之前的元素被清除,重新创建了一个新的页面,新页面上只展示document.write创建的元素);(如果页面文档流加载完毕,再调用这句话会导致页面重绘)
var btn=document.querySelector('button')
btn.onclick=function(){
document.write('123')
}
</script>
//当整个页面都加载完了,再调用里面的函数
window.onload=function(){}
element.innerHTML
和 document.createElement
效率对比:element.innerHTML
是将内容写入某个DOM
节点,不会导致页面全部重绘;创建多个元素效率更高(不是拼接字符串,而是采取数组的形式拼接),结构稍微复杂;document.createElement
创建多个元素效率稍微低一点点,但是结构更清晰;element.innerHTML
效率要比 document.createElement
高;Dom
重点核心总结document.write
、innerHtml
、createElement
appendChild
、insertBefore
removeChild
src
href
title
等;innerHTML
innerText
;value
type
disabled
等;style
className
;getElementById
等;querySelector
querySelectorAll
;parentNode
)、子(children
)、兄(previousElementSibling
nextElementSibling
)提倡使用;setAttribute
:设置dom的属性值;getAttribute
:得到dom的属性值;removeAttribute
:移除属性;onclick
;特点:注册事件的【唯一性】,即同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数;<button onclick='alert("hi~")'></button>
btn.onclick=function(){}
(2)、方法监听注册方式:W3C标准推荐方式;addEventListener()
它是一个方法;IE9之前的IE不支持此方法,可使用attachEvent()
代替;特点:同一个元素同一个事件可以注册多个监听器(事件处理函数);按注册顺序依次执行;
addEventListener()
eventTarget.addEventListener(type,lister[,useCapture])
方法将指定的监听器注册到eventTarget
(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数;type
:事件类型字符串,如:click
mouseover
注意这里不要带on
;listener
事件处理函数,事件发生时,会调用该监听函数;useCapture
可选参数,是一个布尔值,默认是false
;//注意:事件监听注册事件 addEventListener 里面的事件类型是字符串,要加引号,而且不带 on
//同一个元素,同一个事件可以添加多个侦听器(事件处理程序)
btn.addEventListener('click',function(){})
attachEvent
注册事件(IE9以前的版本支持)eventTarget.attachEvent(eventNameWithon,callback)
eventTarget.attachEvent(eventNameWithon,callback)
方法将指定的监听器注册到eventTarget
(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行;eventNameWithon
:事件类型字符串,比如:onclick
onmouseover
这里要带 on ;callback
:事件处理函数,当目标触发事件时回调函数被调用;btn.attachEvent('onclick',function(){})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>注册事件兼容性解决方案</title>
</head>
<body>
<script>
function addEventListener(element, eventName, fn) {
// 判断当前浏览器是否支持 addEventListener 方法
if (element.addEventListener) {
element.addEventListener(eventName, fn);//第三个参数 默认是false
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, fn)
} else {
// 相当于 element.onclick = fn
element['on' + eventName] = fn
}
}
</script>
</body>
</html>
(1)、传统注册方式
eventTarget.onclick = null
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var divs = document.querySelectorAll('div')
divs[0].onclick = function () {
alert(11)
//传统方法删除事件
divs[0].onclick = null
}
</script>
</body>
(2)、方法监听注册方式
eventTarget.removeEventListener(type,listener[,useCapture]);
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var divs = document.querySelectorAll('div')
// removeEventListener 删除元素
divs[1].addEventListener('click', fn) //里面的 fn 不需要加小括号调用
function fn() {
alert(22);
divs[1].removeEventListener('click', fn)
}
</script>
</body>
eventTarget.detachEvent(eventNameWithOn,callback);
<div>1</div>
<div>2</div>
<div>3</div>
var divs = document.querySelectorAll('div')
divs[2].attachEvent('onclick', fn1);
function fn1() {
alert(33)
divs[2].detachEvent('onclick', fn1)
}
function removeEventListener(element,eventName,fn){
//判断当前浏览器是否支持 removeEventListener 方法
if(element.removeEventListener){
element.removeEventListener(eventName,fn);//第三个参数,默认是false
}else if(element.detachEvent){
element.detachEvent('on'+eventName,fn);
}else{
element['on'+eventName]=null;
}
}
onclick
和 attachEvent
只能得到冒泡阶段;addEventListener(type,listener[,useCapture])
第三个参数如果是 true
,表示在事件捕获阶段调用事件处理程序;如果是false
(不写默认是false),表示在事件冒泡阶段调用事件处理程序;onblur
onfocus
onmouseenter
onmouseleave
;<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM事件流</title>
<style>
.father {
width: 200px;
height: 200px;
background-color: aqua;
}
.son {
width: 100px;
height: 100px;
background-color: blueviolet;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
/*
DOM事件流 三个阶段:
1、JS代码中只能执行捕获或者冒泡其中的一个阶段;
2、onclick 和 attachEvent(ie)只能得到冒泡阶段;
3、捕获阶段 如果 addEventListener 第三个参数是 true 那么则处于捕获阶段;document->html->body->father->son
*/
// var son = document.querySelector('.son')
// son.addEventListener('click', function () {
// alert('son')
// }, true)
// var father = document.querySelector('.father')
// father.addEventListener('click', function () {
// alert('father')
// }, true)
// 4、冒泡阶段 如果 addEventListener 第三个参数是 false 或者省略, 那么则处于冒泡阶段;son->father->body->html->document
var son = document.querySelector('.son')
son.addEventListener('click', function () {
alert('son')
}, false)
var father = document.querySelector('.father')
father.addEventListener('click', function () {
alert('father')
}, false)
document.addEventListener('click', function () {
alert('document')
})
</script>
</body>
</html>
eventTarget.onclick=function(event){}
eventTarget.addEventListener('click',function(event){})
event
就是事件对象,我们还喜欢写成 e
或者 evt
;event
是个形参,系统帮我们设定为事件对象,不需要传递实参过去;event
对象代表事件的状态,比如键盘按钮的状态、鼠标的位置、鼠标按钮的状态;window.event
中获取查找;解决:e=e || window.event
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件对象</title>
</head>
<body>
<div>123</div>
<script>
var div = document.querySelector('div')
div.onclick = function (event) {
console.log(event);
}
div.addEventListener('click', function (event) {
console.log(event);
})
/*
1、event 就是一个事件对象,写到我们侦听函数的 小括号里面,当形参来看;
2、事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数;
3、事件对象是我们事件的一系列相关数据的集合,跟事件相关的;
比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标;如果是键盘事件,里面就包含了键盘事件的信息,比如:判断用户按下了哪个键;
4、这个事件对象我们可以自己命名,比如:event、evt、e;
5、事件对象也有兼容性问题,ie678通过 window.event 获取;兼容性写法:e=e || window.event;
*/
</script>
</body>
</html>
target
和 this
区别e.target
返回的是触发事件的对象(元素);<body>
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var div=document.querySelector('div')
div.addEventListener('click',function(e){
console.log(e.target); //123
console.log(this); //123
})
</script>
</body>
注意:this
返回的是绑定事件的对象(元素);
<body>
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var div = document.querySelector('div')
div.addEventListener('click', function (e) {
console.log(e.target); //123
console.log(this); //123
})
var ul = document.querySelector('ul')
ul.addEventListener('click', function (e) {
//我们给ul绑定了事件,那么 this 就指向 ul
console.log(this);//
// 注意:此处没有写第三个参数,所以默认是false(冒泡),li 没有绑定点击事件,点击的是 li ,li没找到事件就往上找,这是冒泡;
console.log(e.currentTarget);// 了解:跟 this 有个非常相似的属性 currentTarget (IE678不兼容)
console.log(e.target);//
})
/*
区别:e.target 点击了哪个元素,就返回哪个元素;this 哪个元素绑定了这个点击事件,那么就返回谁;
*/
// 考虑兼容性问题的写法
div.onclick = function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log(target);
}
</script>
</body>
e.type
<body>
<div>123</div>
<a href="http://www.baidu.com">百度</a>
<form action="http://www.baidu.com">
<input type="submit" value="提交" name="sub">
</form>
<script>
// 常见事件对象的属性和方法
// 返回事件类型
var div = document.querySelector('div')
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn)
div.addEventListener('mouseout', fn)
function fn(e) {
console.log(e.type);
}
</script>
</body>
<a href="http://www.baidu.com">百度</a>
<form action="http://www.baidu.com">
<input type="submit" value="提交" name="sub">
</form>
// 阻止默认行为(事件):让链接不跳转,或者让提交按钮不提交;
var a=document.querySelector('a');
a.addEventListener('click',function(e){
e.preventDefault();//DOM推荐的标准写法(低版本IE浏览器不支持)
})
// 传统的注册方式
a.click = function (e) {
// 普通浏览器 e.preventDefault();---> 方法
e.preventDefault()
// 低版本浏览器 ie678 用 returnValue ---> 属性
e.returnValue;
/*
我们可以利用 return false ,也能阻止默认行为,而且没有兼容性问题;
特点:return后面的代码不执行了,而且只限于传统的注册方式;
*/
return false
}
stopPropagation()
方法;<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
var son = document.querySelector('.son')
son.addEventListener('click', function (e) {
alert('son')
e.stopPropagation(); //stop停止 propagation 传播 ;有兼容性问题
e.cancelBubble=true;// 低版本IE浏览器
}, false)
var father = document.querySelector('.father')
father.addEventListener('click', function () {
alert('father')
}, false)
document.addEventListener('click', function () {
alert('document')
})
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble=true;
}
</script>
</body>
jQuery
里面称为事件委派;target
来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器;DOM
,提高了程序的性能;<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
var ul = document.querySelector('ul')
ul.addEventListener('click', function fn(e) {
// alert('被点击了')
// e.target 可以得到我们点击的对象
e.target.style.backgroundColor = 'pink'
})
</script>
</body>
event
对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象MouseEvent
和键盘事件对象KeyboardEvent
;contextmenu
主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单;document.addEventListener('contextmenu',function(e){
e.preventDefault();
})
selectstart
开始选中;document.addEventListener('selectstart',function(e){
e.preventDefault();
})
<body>
我是一段不愿意分享的文字
<script>
// contextmenu 可以禁用右键菜单
document.addEventListener('contextmenu', function (e) {
e.preventDefault();
})
// 禁止选中文字 selectstart
document.addEventListener('selectstart', function (e) {
e.preventDefault();
})
</script>
</body>
<script>
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function (e) {
// 1、client 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
// 2、page 鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
// 3、screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
})
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跟随鼠标的天使</title>
<style>
img {
position: absolute;
}
</style>
</head>
<body>
<img src="./images/angel.gif" alt="">
<script>
/*
1、鼠标不断的移动,使用鼠标移动事件:mousemove;
2、在页面中移动,给 document 注册事件;
3、图片要移动距离,而且不占位置,我们使用绝对定位即可;
4、核心原理:每次鼠标移动,我们都会获得最新的鼠标坐标,把这个 x 和 y 坐标作为图片的 top 和 left 值就可以移动图片;
*/
var pic = document.querySelector('img')
document.addEventListener('mousemove', function (e) {
// mousemove 只要我们鼠标移动1px,就会触发这个事件;
var x = e.pageX;
var y = e.pageY;
console.log('x坐标是' + x, 'y坐标是' + y);
// 注意:千万不要忘记给 left 和 top 添加 px 单位;
// 减50和40是减去图片的长和宽的一半,从而使鼠标箭头的位置处于图片的中心;
pic.style.left = x - 50 + 'px';
pic.style.top = y - 40 + 'px';
})
</script>
</body>
</html>
<body>
<script>
// 键盘事件对象中的 keyCode 属性可以得到相应键的 ASCII 码值;
// 1、我们的 keyup 和 keydown 事件不区分字母大小写;例如:a 和 A 得到的都是65;
// 2、我们的 keypress 事件,区分字母大小写;例如:a 得到的都是 97 和 A 得到的都是 65;
document.addEventListener('keyup', function (e) {
console.log(e);
console.log('up:' + e.keyCode);
if (e.keyCode === 65) {
alert('按下了a键')
} else {
alert('没有按下a键')
}
})
document.addEventListener('keypress', function (e) {
console.log(e);
console.log('press:' + e.keyCode);
})
</script>
</body>
<body>
<input type="text">
<script>
/*
1、核心思路:检测用户是否按下了s键,如果按下s键,就把光标定位到搜索框里面;
2、使用键盘事件对象里面的keyCode判断用户按下的是否是s键;
3、搜索框获得焦点:使用js里面的 focus() 方法;
*/
var search = document.querySelector('input')
document.addEventListener('keyup', function (e) {//此处用keydowm会把s填入输入框
console.log(e.keyCode);
if (e.keyCode === 83) {
search.focus();
}
})
</script>
</body>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模拟京东快递单号查询</title>
<style>
body,
html {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, .2);
box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before { /* 倒三角形 */
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<!--
案例分析:
(1)、快递单号输入内容时,上面的大号字体盒子(con)显示(这里面的字号更大);
(2)、表单检测用户输入:给表单添加键盘事件;
(3)、同时把快递快递单号里面的值(value)获取过来赋值给con盒子(innerText)作为内容;
注意:keydown 和 keypress 在文本框里的特点:他们两个事件触发的时候,文字还没有落入文本框中;keyup 事件触发的时候,文字已经落入文本框里面了;
-->
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="请输入您的快递单号" class="jd">
</div>
<script>
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
jd_input.addEventListener('keyup', function () {
if (this.value === '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
})
//当我们失去焦点,就隐藏这个con盒子
jd_input.addEventListener('blur', function () {
con.style.display = 'none'
})
//当我们获得焦点,就显示这个con盒子
jd_input.addEventListener('focus', function () {
if (this.value !== '') {
con.style.display = 'block'
}
})
</script>
</body>
</html>