前端笔记知识点整合之JavaScript(八)关于元素&计算后的样式
一、获取元素方法(js选择器)
1.1概述
得到id元素的方法
document.getelementbyid() |
得到一个元素。事实上,还有一个方法可以得到标签元素,并且得到的是多个元素:
document.getelementsbytagname(); |
全线浏览器兼容的,得到元素的方法,就这两个:
document.getelementbyid() 通过id得到元素
document.getelementsbytagname(); 通过标签名得到元素们
还有更多的得到元素的方法:
document.getelementsbyclassname();通过类名得到元素
document.queryselector(); 通过选择器得到元素
document.queryselectorall();通过选择器得到元素,得到的是一组元素
document.getelementsbyname(name) 通nama属性名获取元素
这些不是全线浏览器兼容,ie8以上开始兼容。
1.2 getelementsbytagname
getelementsbytagname就是通过标签名得到元素,得到的是页面上所有的该标签元素,得到的是数组。数组有下标,下标0开始,最后一项length-1。通过标签名获得所有标签名这个标签。类似于css中的标签选择器。选择的是一组元素。
get 得到
elements 元素们
by 通过
tagname 标签名字
var ops = document.getelementsbytagname("p"); console.log(ops); // ops.style.backgroundcolor = "skyblue"; //错误写法,因为得到的是一根数组,必须用下标获取元素 ops[0].style.backgroundcolor = "skyblue";//获取下标为1的标签 ops[1].style.backgroundcolor = "skyblue";//获取下标为2的标签 ops[2].style.backgroundcolor = "skyblue";//获取下标为3的标签 ops[3].style.backgroundcolor = "skyblue";//获取下标为4的标签 ops[4].style.backgroundcolor = "skyblue";//获取下标为5的标签 ops[ops.length-1].style.backgroundcolor = "skyblue";//获取最后的标签
既然是数组,就可以通过循环语句批量控制。
var ops = document.getelementsbytagname("p"); //循环给所有p标签 for(var i = 0;i < ops.length;i++){ console.log(i) ops[i].style.backgroundcolor = "skyblue"; }
html标签从上到下执行,依次是0,1,2,3,4
<div> <div> <p>0</p> <div> <p>1</p> </div> <p>2</p> </div> <p>3</p> </div> <p>4</p> //页面上只有一个p标签,也必须用数组[]得到 document.getelementsbytagname('p')[2].style.color = "red";
1.3连续打点调用get
先去选择一个html标签,然后选择这个html标签中所有的p元素
连续打点调用get方法,控制范围,选中父亲下的什么什么元素。
document.getelementsbytagname('div')[0].getelementsbytagname('p')[1].style.color = "red"; |
错误写法:不要多写document,只要开头有一个就可以了。
document.getelementsbytagname('div')[0].document.getelementsbytagname('p')[1].style.color = "red"; |
实际应用:先用id名去缩小范围,内部的多选择使用标签选择器。
document.getelementbyid('box').getelementsbytagname('p')[1].getelementsbytagname('span')[1].style.color = 'red'; |
表格隔行变色:
var tr = document.getelementbyid("table").getelementsbytagname('tr'); //不管个数是多少,编号从0开始 for(var i = 0;i < tr.length;i += 2){ //从0开始,每次加2,所以都是偶数 tr[i].style.backgroundcolor = "pink"; } for(var i = 1;i < tr.length;i += 2){ //从1开始,每次加2,所以都是奇数 tr[i].style.backgroundcolor = "skyblue"; }
1.4批量添加事件添加
如果一些相同的元素,添加相同事件,事件函数内部的代码几乎相同,可以批量选择元素添加事件。
注意:找出数组中每一项,定义事件函数,用for循环中的变量。闭包可能会程序造成影响。
循环给所有p标签添加事件,并且弹出对应的编号:
var ops = document.getelementsbytagname('p'); for(var i = 0;i < ops.length;i++){ ops[i].onclick = function(){ alert(i); //循环结束后都还执行函数,所以值 } }
但是,对编号的影响,闭包的影响又出现了。
所以每个盒子点击后都是5,而不是0,1,2,3,4。
闭包的影响:匿名函数定义时,都已经记住了自己认识i,但是认识i不是表示把i的值复制一份保存,所以匿名函数执行时(就是事件触发时),i的值变为循环结束的值了。
解决方法1:使用iife关住当时定义时的作用域,点击事件发生时,执行对应的事件函数,事件函数会去找自己定义时的作用域。定义时a已经被传递了参数,值就已经存储起来了。
var ops = document.getelementsbytagname('p'); for(var i = 0;i < ops.length;i++){ (function(a){ ops[a].onclick = function(){ alert(a); } })(i); //把每次循环i的值传递给函数局部变量a }
解决方法2:获取的元素,本身封装了大量的属性和方法,还能自定义一些新属性并赋值,自定义属性后可以打点调用。
任何对象都可以自定义属性,并赋值:
math.aaa = 9999; window.aaa = 8888; array.bbb = 12345; console.log(math.aaa) console.log(window.aaa) console.log(array.bbb)
var ops = document.getelementsbytagname('p'); for(var i = 0;i < ops.length;i++){ ops[i].index = i; //自定义属性,并且把循环i的值赋值保存到属性中,名称自定义的 ops[i].onclick = function(){ alert(this.index); //this关键字就代表事件源本身 } }
解决方式:每个元素对象添加一个自定义属性,用属性存储循环变量,在事件函数内部与都有一个特殊关键字,叫this,this会指向事件源本身,它能完全替代事件触发的那个事件源对象。
事件源:谁触发事件,谁就是事件源(谁就是this)
1.5对应和排他思想
保留自己排除别人。
实际运用到代码中,批量控制给所有人添加一个相同样式,然后再给被操作的元素添加特殊样式。
做到了先排除所有人,然后再保留自己的特殊样式。
对应模型:点击第一排p,第二排对用编号的p变色。
// 方法1:编号,循环添加事件监听,给第一排所有p并且绑定点击事件 for(var i = 0;i < box1.length;i++){ box1[i].index = i; box1[i].onclick = function(){ console.log(this.index) box2[this.index].style.backgroundcolor = "red"; } }
//方法2:iife for(var i = 0;i < box1.length;i++){ (function(i){ // console.log(i) box1[i].onclick = function(){ box2[i].style.backgroundcolor = "red"; } })(i); }
排他思想:点击p的时候,就自己变红色,其他所有o都变灰色
var aps = document.getelementbyid('box').getelementsbytagname("p"); var biaoti = document.getelementbyid("biaoti"); //循环添加监听 for(var i = 0;i < aps.length;i++){ aps[i].index = i; //自定义编号 aps[i].onclick = function(){ //每点击一个p并且,实际上两件事 //第一件事:让所有人(包括自己)都变灰色 for(var j = 0;j < aps.length;j++){ //aps[j].style.backgroundcolor = "#ccc"; aps[j].classname = ""; //清空类型 } //第二件事:让自己都变红色 //this.style.backgroundcolor = "#f40"; this.classname = "current"; //添加类名 } }
轮播图:
var imglist = document.getelementbyid('imglist').getelementsbytagname('li'); var navlist = document.getelementbyid('navlist').getelementsbytagname('li'); var leftbtn = document.getelementbyid('btn1'); var rightbtn = document.getelementbyid('btn2'); var index = 0; //全局信号量,是ul的li下标,下标为几,就显示第几个li //右按钮 rightbtn.onclick = function(){ index++;//信号量自加 //后验收 if(index > imglist.length-1){ index = 0; //回到第一张 } slide();//调用函数 } //左按钮 leftbtn.onclick = function(){ index--;//信号量自减 //后验收 if(index < 0){ index = imglist.length-1; //回到第一张 } slide();//调用函数 } //封装函数 function slide(){ //排他:将所有人的隐藏(类名清空),再让自己加current类名(谁有类名谁就显示) for(var i = 0;i < imglist.length; i++){ //第一步:让所有图片li标签隐藏 imglist[i].classname = ""; //让所有ol的li都清空 navlist[i].classname = ""; } //让自己显示,其他li隐藏 //给当前编号的ul的li添加类名,显示图片 imglist[index].classname = "current"; //给当前编号的ol的li添加类名,显示小圆点 navlist[index].classname = "current"; } //下面小圆点如果点击,应该让index对应的发生变化 for(var i = 0;i < navlist.length;i++){ navlist[i].index = i; //自定义属性 navlist[i].onclick = function(){ index = this.index; //把当前被点击的li编号重新赋值给全局变量(修改全局) // index得到后,执行函数 slide(); //调用函数 } }
选项卡:
var tab_li = document.getelementbyid('tab-hd').getelementsbytagname("li"); var tab_ul = document.getelementbyid('tab-bd').getelementsbytagname("ul"); //批量给li添加鼠标移入事件 for(var i = 0; i < tab_li.length;i++){ tab_li[i].index = i; //自定义属性,存储i的值 tab_li[i].onmouseenter = function(){ //排他思想: //第一步:先清空所有li元素的类名 for(var j = 0; j < tab_li.length;j++){ tab_li[j].classname = ""; //清空li的类名 tab_ul[j].classname = ""; //清空ul的类名 } //第二步再给自己添加类名 this.classname = "current"; //给当前鼠标移入的li添加类名 tab_ul[this.index].classname = "current"; //给对应编号的ul添加类名 } }
二、得到计算后的样式
2.1高级浏览器和低级浏览器的不同写法
现在我们只能得到行内的样式,事实上dom提供了可靠的api,得到计算后的样式(内嵌式和外链式)。
w3c制定的标准api,所有现代浏览器(包括ie9,但不包括之前的版本)支持window.getcomputedstyle()方法,该方法接收一个要进行样式计算的元素,并返回一个样式对象。样式对象提供了getpropertyvalue()的方法,用于检索特定css样式属性的计算样式。getpropertyvalue()方法接收css属性名称,而不是驼峰式的名称。getpropertyvalue()可以不写,直接用[]方括号来代替检索属性也可以。
get得到,computed计算后,style样式
get得到,property属性,vaule值
这种方式获取和设置的都是行内样式,无法获取内嵌和外链的css样式:
console.log(obox.style.width); |
window.getcomputedstyle(obox); //得到当前div元素所有的css样式 window.getcomputedstyle(obox).getpropertyvalue("width"); //获取计算后的样式 |
所有的window对象的方法,都可以不写window
window.alert(); |
等价于:
alert(); |
得到计算后的样式,可以直接使用getcomputedstyle()方法,不用写window。
还要注意,引号里面是css属性,不是驼峰命名法。
getcomputedstyle(obox).getpropertyvalue("padding-left") |
getpropertyvalue()方法看着就不爽,所以可以用“[]”来代替它
getcomputedstyle(obox)["padding-left"]; |
计算后的综合结果,就是这个元素此时的状态:
getcomputedstyle(obox)["background"]; getcomputedstyle(obox)["background-color"]; //样式计算后结果是得到rgb的值 getcomputedstyle(obox)["background-image"]; getcomputedstyle(obox)["border"];
上面的方法ie6、7、8一律不兼容!!!
dom提供给js的非常牛,一个元素此时的状态,可以完全被得到,好用的属性,但是不兼容。所以ie6、7、8不兼容getcomputedstyle()方法,写另外一套写法:附加在元素身上的currentstyle属性,它和style点语法一样,使用驼峰命名法。
ie6、7、8支持以下写法:
注意:currentstyle得到样式,必须用驼峰命名法,写法和obox.style.width这种一样
obox.currentstyle.paddingleft |
可以不写点语法,使用“[]”,但是也必须是驼峰命名。
obox.currentstyle['paddingleft'] |
alert(obox.currentstyle.width); alert(obox.currentstyle.height); //不写高度得到的是auto,不能获取被内容撑开的高度 alert(obox.currentstyle.backgroundcolor); //颜色值会原样输出,pink
颜色值在高级浏览器中是rgb(),低版本浏览器是原样输出
总结: 高级浏览器: window.getcomputedstyle(obox).getpropertyvalue("padding-left"); getcomputedstyle(obox).getpropertyvalue("padding-left"); getcomputedstyle(obox)["padding-left"]; ie6/7/8浏览器 obox.currentstyle.paddingleft obox.currentstyle["paddingleft"];
2.2兼容写法
ie6、7、8低级浏览器,不认识getcomputedstyle视为错误
chrome等高级浏览器,不认识currentstyle视为错误
所以,现在就要进行一个兼容性写法,新玩家会认为,要检测浏览器版本,如果版本是ie6、7、8那么……。
实际上,老司机都不这么做。我们不关心你的浏览器版本是什么,我只关心你浏览器的能力。
所以要进行能力检测,可以在不同浏览器中得到兼容性的写法,输出css属性的值:
如果能使用这个方法,方法作为if语句的判断条件就会返回true,不能使用就返回false。
if(window.getcomputedstyle){ //条件满足为真,说明当前浏览器认识getcomputedstyle()方法 alert(getcomputedstyle(obox)["background-color"]); }else{ //条件不满足,说明当前浏览器不认识getcomputedstyle()方法,认识currentstyle alert(obox.currentstyle.backgroundcolor); }
封装一个兼容性的函数获取一个元素某个css属性值的方法。
api:传入两个参数,第一个是元素对象,第二个是css属性名
返回值:是这个传入元素对象的css属性值
function getstyle(obj,property){ if(window.getcomputedstyle){ //高级连起来,要把用户输入的css属性中检测一下是否为驼峰,如果是就转为连字符写法 //强制把用户输入的大写字母,变为小写字母加“-” // paddingleft 替换 padding-left // 正则替换: property = property.replace(/([a-z])/g,function(match,$1){ return "-" + $1.tolowercase(); }) //返回计算后的样式 return getcomputedstyle(obj)[property]; }else{ //ie只认识驼峰,要防止用输入短横,如果输入短横,要把短横改为大写字母 //padding-left替换paddingleft property = property.replace(/-([a-z])/g,function(match,$1){ return $1.touppercase(); }) //返回计算后的样式 return obj.currentstyle[property]; } } alert(getstyle(obox,"padding-left")); alert(getstyle(obox,"backgroundcolor"));
2.3关于opacity
opactiy取值0.0~1.0,而滤镜取值0~100。
尽管ie8和早期版本不支持opacity,通过style.opacity或者ele.currentstyle.opacity属性取值时,返回的依然是opacity值,即使浏览器完全忽略了opatity值。这是一个好事儿,当我们能够保证opactiy、filter中设置的属性是一致的,则javascript读取opactiy值就算是兼容的。
支持opacity的浏览器,总会将.6这种写法规范为0.6 。 而不支持opacity的浏览器则会返回原有的形式.5。这是一个小坑,进行比较的时候需要注意。
设置opacity的时候,我们需要同时设置filter属性,filter中的数值是opacity的100倍。
查了100倍
var obox = document.getelementbyid("box"); // alert(obox.style.opacity); //js没有兼容性问题 // alert(obox.currentstyle.opacity); //低版本没有兼容性问题 var opacity = 0.5; obox.style.opacity = opacity; obox.style.filter = "alpha(opacity="+(opacity * 100)+")";
ps:尽量让它越来越规范,前期的文章都是本人的学习时的笔记整理,希望看完后可以指点一二,提提意见多多交流;
笔记流程:html>css>javascript>jquery>html5/css3>移动端>ajax>面向对象>canvas>nodejs>es678>vue>react>小程序>面试问题
意见请留言,邮箱:scarf666@163.com