2021年3月

obj.style这种方式既可以读取样式属性,也可以写样式属性,但它操作的样式属性只能是行内样式,如果要访问内嵌或者链式样式,则不可以使用这种写法。
要访问内嵌或者链式样式,可以使用getComputedStyle()currentStyle属性的方式来访问样式。
需要注意的是:getComputedStyle()currentStyle属性只能读样式属性,不能写样式属性。

getComputedStyle()

getComputedStyle()可访问指定元素的指定css属性的结果样式,访问格式如下:


// 1
getComputedStyle(需访问样式属性的元素).样式属性


//2
getComputedStyle(ele)[attr]
getComputedStyle(需访问样式属性的元素)[样式属性]

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>获取结果样式</title>
		<style>
			div {
				width: 400px;
				height: 300px;
				background: #E15671;
			}
		</style>
	</head>
	<body>
		<div></div>
		
		<script>
			// 获取元素封装方法
			function $(str){
				return document.querySelector(str);
			}
			
			//这样写相当于获取标签的一个属性,但标签里又没有,就会出现undefined
			//let w = $('div').width;
			//console.log(w); // undefined
			
			//获取的是行间样式,如果没有行间样式,获取出来的就为空
			let w = $('div').style.width;
			console.log(w);  //
			
			// 获取的是结果样式,就是获取最终显示效果的样式,外链,内嵌,行间会有优先级
			// let w2 = window.getComputedStyle($('div')).width;
			// let w2 = window.getComputedStyle($('div'))['width'];
			// window下的方法都可以不用写window
			// getComputedStyle(ele)[attr]
			let w2 = getComputedStyle($('div'))['width'];
			console.log(w2);
			
			// 对于复合样式,如果是要获取某一样式,最好是单一属性来访问,比如背景颜色backgroundColor
			// let b2 = getComputedStyle($('div'))['background'];
			// console.log(b2);  //rgb(225, 86, 113) none repeat scroll 0% 0% / auto padding-box border-box
			
			let b2 = getComputedStyle($('div'))['backgroundColor'];
			console.log(b2); // rgb(225, 86, 113)
		</script>
	</body>
</html>

currentStyle

该属性只对IE游览器有效,对Chrome等游览器不可以,其主要是用于兼容IE6 7 8 的。


// 1
需访问样式属性的元素.currentStyle.样式属性

//  2
需访问样式属性的元素.currentStyle(样式属性)

要使用getComputedStyle()currentStyle属性访问样式一般需要进行游览器兼容处理


// IE8以下支持的方法
var oDiv = document.querySelector('div');
			
// el.currentStyle(attr)
// 用if去判断el.currentStyle是否存在
if(oDiv.currentStyle){
    // IE8
    oDiv.currentStyle('width');
}else{
    // Chrome
    getComputedStyle(oDiv)['width'];
}

封装兼容getComputedStyle()和currentStyle


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>获取结果样式</title>
		<style>
			div {
				width: 400px;
				height: 300px;
				background: #E15671;
			}
		</style>
	</head>
	<body>
		<div></div>
		
		<script>
			// // IE8以下支持的方法
			var oDiv = document.querySelector('div');
			
			// // el.currentStyle(attr)
			// // 用if去判断el.currentStyle是否存在
			// if(oDiv.currentStyle){
			// 	// IE8
			// 	oDiv.currentStyle('width');
			// }else{
			// 	// Chrome
			// 	getComputedStyle(oDiv)['width'];
			// }
			
			// 封装 兼容getStyle
			// 由上面的if可以知道,获取样式需要填两个数据
			// el 元素
			// attr 样式名称
			// 然后复制写好的判断,替换下元素与属性
			// 需要注意的是,我们的目的是通过getStyle来获取结果样式
			// 所以我们还要加上return,使用return把结果返回给函数调用者
			
			function getStyle(el,attr){
				if(el.currentStyle){
					return el.currentStyle(attr);
				}else{
					return getComputedStyle(el)[attr];
				}
			}
			
			// 调用
			let w3 = getStyle(oDiv,'width');
			let h3 = getStyle(oDiv,'height');
			
			console.log(w3);  // 400px
			console.log(h3);  // 300px
		</script>
	</body>
</html>

三目运算符(三元运算符)

类似于if…else…
条件?a:b;


// if

let a =true
// if(a){
//     console.log(1);  // 1
// }else{
//     console.log(2);
// }


// 条件直接写?条件允许时执行问号后面的代码:条件不允许时执行冒号后面的代码;
// a?console.log(1):console.log(2);  // 1

// 
// console.log( a?1:2 )


// 简化之前
// function getStyle(el,attr){
// 	if(el.currentStyle){
// 		return el.currentStyle(attr);
// 	}else{
// 		return getComputedStyle(el)[attr];
// 	}
// }
	
// 简化之后
// 三目 - 条件内js语句不超过1句		
function getStyle(el,attr){
    return el.currentStyle?el.currentStyle(attr):getComputedStyle(el)[attr];
}


var div = document.querySelector('div');

// 封装
		
function $(str){
    var div = document.querySelector(str);		
    return div;
}

// 简化
// 去掉变量,直接返回

function $(str){
    return document.querySelector(str);
}


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        div{
            width: 100px;
            height: 100px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        function $(str){
            return document.querySelector(str);
        }

        $('div').style.backgroundColor = 'yellow';

    </script>
</body>
</html>

return语句在函数定义中的作用有两个:一是返回函数值,二是中止函数的执行。
return可以返回包括基本数据类型、对象、函数等任意类型的值。


function fn(){

    console.log(123)

    // 每一个函数 都有一个return
    // 默认return 的值是undefined
    // 后面如果有值,会把值返回给函数调用者
    return [1,2,3];
}

let n = fn();

console.log(n) // (3) [1, 2, 3]

//return语句返回函数
function outeFunc(){
let b = 0;
return function(){
    b++;
    console.log("内部函数中b="+b);
    }
}
	   
let func = outeFunc();
func(); // 内部函数中b=1

当在函数体中使用return语句时,函数将会停止执行。


function fn(){
    console.log(1)
            
    // 阻断函数向下执行
    // return 只能存在于函数内部
    return;

    console.log(2)
}

console.log(3); //3

fn();  // 1

return 只能存在于函数内部。


function fn(){
    console.log(1)
            
    if(1){
        return;
    }
    // 阻断函数向下执行
    // return 只能存在于函数内部

    console.log(2)
}

// 语法错误
// if(1){
//         return;
//     }


console.log(3)

fn();

函数声明

自定义函数分为两类,有名函数和匿名函数。
有名函数的定义也叫函数声明,基本语法:


//function 函数名(){
// 需要执行的代码
//}

// 命名函数
function fn(){
 alert(1)
}

 // 调用该函数
fn();

匿名函数的定义有两种形式,函数表达式形式和事件注册形式。
函数表达式的基本语法:
函数表达式将匿名函数赋给一个变量,这样调用的匿名函数就可以通过这个变量来调用。


//let 变量名 = function (){
// 需要执行的代码
//}

// 函数表达式
var fn2 = function(){
    console.log(123);
};

事件注册式的基本语法:


//文档对象.事件 = function(){
//    console.log(123)
//};

btn.onclick = function(){
    console.log(123);
}

函数传参

实参与形参

所有的数据类型都可以当参数传递进去,多个参数用逗号隔开。


// n,f 形参 - 形式上定义的参数名,形参与实参一一对应
function fn(n,f){

    alert(n);  //1

    console.log(f);  //2
}

// 1,2 实参 - 实际传递的参数
fn(1,2);

//fn([1,2,3],function(){ alert('aaa') })

arguments 不定参

arguments其实就是传递给函数的实参集合。
它类似数组Array的对象,存放在arguments中的每一个实参,可以用arguments[下标]的格式来访问,对于arguments中存放的实参个数则可以使用arguments.length获得,除了length属性和通过索引值引用之外不能用任何数组的方法。


function fn(){
    // arguments 获取一组实参 伪数组
    console.log(arguments[1]);  //2

    // 实参的长度
    console.log(arguments.length);  //5

}

fn(1,2,3,4,99);

// arguments 不定参应用 实参的累加和
function fnSum(){
    var sum = 0;
    for(var i=0;i<arguments.length;i++){
        sum+=arguments[i];
    }
    console.log(sum);
}

fnSum(1,2,3,4,5,6,7,8,9);  //45


arr = ['100px', 'abc' - 6, [], -98765, 34, -2, 0, '300', , function() {
            alert(1);
        }, null, document, [], true, '200px' - 30, '23.45元', 5, Number('abc'), function() {
            alert(3);
        }, 'xyz' - 90];

用以上一组数据,来筛选分类出以下4类
1.所有的数字
2.可以转成数字的
3.最大值为
4.NaN所在的位置是

所有的数字



// 先声明一个空数组来存找到符合条件的数
let n1 = [];

// 既然要在数组里找符合条件的数,就可以先用循环把它遍历出来
for (let i = 0; i < arr.length; i++) {
    // 然后用if去判断谁符合要求
    // arr[i] 可以拿到循环里的当前的数值
    // 判断它是不是数字
    // 判断它是不是数字 typeof(arr[i]) == 'number' 

    if (typeof(arr[i]) == 'number') {
        // 符合条件的数就写入创建的数组里
        n1.push(arr[i]);
    }
}

console.log(n1);
// NaN,-98765,34,-2,0,NaN,5,NaN,NaN

到这里,获取出来的数,不仅有数字,还有类型属于数字的(NaN),但我们这里要的是纯数字,而不是是个数字类型就获取
修改一下if判断把NaN剔除掉


// 先声明一个空数组来存找到符合条件的数
let n1 = [];

// 既然要在数组里找符合条件的数,就可以先用循环把它遍历出来
for (let i = 0; i < arr.length; i++) {
    // 然后用if去判断谁符合要求
    // arr[i] 可以拿到循环里的数
    // 判断它是不是数字 并且 不是NaN
    // 判断它是不是数字 typeof(arr[i]) == 'number' 
    // 判断它不是NaN
    // NaN的判断方法 isNaN(arr[i),这样写只是判断它是个NaN,既然是要判断它不是NaN,可以用取反的方法!isNaN(arr[i)

    // 判断数据类型是不是number 并且值不是NaN
    if (typeof(arr[i]) == 'number' && !isNaN(arr[i])) {
        // 符合条件的数就写入创建的数组里
        n1.push(arr[i]);
    }
}

console.log(n1);
// (5) [-98765, 34, -2, 0, 5]

可以转成数字的


let n2 = [];

for (let i = 0; i < arr.length; i++) {
    // 先用parseFloat判断当前的数值可不可以转成数字  parseFloat(arr[i])
    // 并且不是NaN就转 !isNaN()

    // 判断这个数值可不可以通过parseFloat转成数字 - (不会出现NaN的情况)
    if (!isNaN(parseFloat(arr[i]))) {
        n2.push(arr[i]);
    }
}

console.log(n2);
// (8) ["100px", -98765, 34, -2, 0, "300", "23.45元", 5]

最大值


// Infinity 正无穷  -Infinity 负无穷
// 先声明一个值,假设它是最大的,
// 注意一下不要用Infinity去做,这样的话,就真成最大的值了,应该用-Infinity,这样只要任何一个值超过这个-Infinity,变量max里的值就会呗替换
let max = -Infinity;

for (let i = 0; i < arr.length; i++) {
    // 判断条件里不要直接用arr[i] 去比,因为arr[i]代表的是当前的数值,而数组里还有的不是数字,这样就没法用来做大小余判断了
    if (Number(arr[i]) > max) {
        max = arr[i];
     }
}
console.log(max);  //300

NaN的位置


let n4 = [];

for (let i = 0; i < arr.length; i++) {
    // 如果只判断isNaN的话,而isNaN 内部 会先将值 通过number方法转成数字 再去执行
    // 比如Number(function(){}) 用Number转一个函数出来的结果肯定是NaN,如果这是NaN,再用isNaN包起来的话,它不就是一个true
    // 为了避免类似函数一类的东西放到里面去判断,就还需要一个只有是number类型的判断条件

    // 判断数据通过isNaN方法得出布尔值 并且 数据类型必须是number(NaN也属于number)
    if (isNaN(arr[i]) && typeof arr[i] == 'number') {
        n4.push(i);
    }
}
console.log(n4);
// (4) [1, 14, 17, 19]