在自定义对象中,大部分是比较复杂的,一般用于高级开发中。常用的对象如下:
array(数组)对象:
普通对象:
| 属性名 |属性值 |
| name | jiojidoj |//属性名任意
数组对象
| 索引 | 元素 |
| 1 | 456 |//索引为数字,并且按顺序排列,从零往后延伸
构造函数创建数组对象:
var array=new Array();
//向数组中添加元素
数组[索引]=元素(值)
//获取数组长度
数组长度:array.length//是最大索引+1;
非连续的数组,会空置很多数组的位置;除非必要不然不要创建非连续的数组;
如果修改了length属性,就会增加计算数组的长度,空间就会变大。如果减少数组长度,空间会减小,会删除后面的元素。
向数组的最后一个索引添加元素:arr[arr.length]=值;
使用字面量创建数组对象:
var arr=[
]
//数组时中括号创建,对象是大括号创建。
使用字面创建数组时,可以在创建时,就可以创建数组元素。
索引是从0开始计算的。
var arr =new Array(123,456,789);
也可以通过构造函数创建数组对象。
var arr=[10]//创建只有值为10的数组;
var arr=new Array(10)创建一个长度为10的数组;
一般数组的长度在里面没有什么限制,可以在js中添加数组长度。
数组中的元素可以是任意的数据类型(包括对象);
调用数组中的函数arr[索引]();
调用对数组中的对象arr[索引].属性名或者arr[索引].方法名()
数组里还可以放数组:二维数组、三维数组等都可以实现;
数组对象的四个方法:
push():该方法可以向数组末尾添加一个或多个元素,并返回新数组的长度。
可以将想要添加的元素,作为方法的参数传递给数组;
该方法会将数组的新的长度返回;
向较于arr[arr.length]这个可以一次添加多个值;
pop():该方法会删除数组的最后一个元素。并将删除元素作为返回值返回。
unshift():向数组开头添加一个或多个元素,并且返回数组新的长度。向前面插入元素之后,其他元素的索引会依次调整。
shift():删除数组开头的第一个元素,并将删除元素作为返回值返回。
数组的遍历:
所谓数组的遍历,就是将数组中元素都取出来。
for(var i=0;i console.log(arr[arr.length]); } 遍历数组找到满足条件的元素,放到新的数组中返回; function getAdult(arr){ var newArr=[]; var p=arr[i]; for(var i=0;i if(条件){ newArr.push(p); } } return newArr; } forEach();这个方法是支持ie8以上的浏览器;如果需要兼容ie8就不要使用forEach,移动端就不用紧。 forEach()需要函数作为参数; arr.forEach(匿名函数);//如果使用普通函数的话会污染作用域,所以使用匿名函数最为方便;数组中有几个元素就执行几次函数。 每次浏览器都会将浏览器以实参的形式传递到函数中。浏览器会在回调函数创建三个参数,第一个参数是当前正在遍历的元素,第二个参数是遍历的索引号,第三个参数是整个数组对象。 arr.forEach(function(value,index,array){}); slice和splice: slice ()可以用来提取数组中的元素。 slicu(start,end)//start,开始位置end,结束位置; arr.slice(1,3);该方法不会改变原数组,而是将截取到的元素封装到一个新的数组中返回参数; 在start开启索引在end关闭索引。 如第二个参数可以省略不写,表示截下剩余全部; 索引也可以传递负值,表示从数组末尾倒数几个数开始或者关闭索引。 splice()用于删除,添加数组中的指定元素。它会对原数组有影响; 多个参数: 第一个表示删除开始索引; 第二个表示删除的数量;只是添加元素的话可以直接将第二个元素设置为0; 第三个参数开始及其以后,;会作为新元素插入到开始索引(第一个参数)的前面; 去除数组的重复元素:splice (嵌套for循环); for(var i=0;i console.log(arr[i]); for (var j=i+1;j if(arr[i]==arr[j]{ arr.splice(j,1); j--;//后面元素顶上来,会跳过删除的元素后面一个元素;需要再比一次;} ) } } concat()连接两个或者多个数组,返回新的数组,不会对原数组产生影响; join():这个方法可以将数组直接转换成字符串,不会对原数组产生影响,而是将转换的结果作为返回值返回。、 在join传递第一个参数,会将数组元素作为这个参数作为数组元素之间的连接返回,如果不指定,默认使用逗号,作为连接符; reverse()颠倒数组的顺序,翻转数组,该方法会直接修改原数组。 sort()也会影响原数组,它默认会按照unicode编码排序; 所以如果想对纯数字的数字进行排序,这种默认的情况就不行了,它会将123,首先用第一个字符做排序,123,1234,2,23; sort(function(a,b){return a-b;}) //a表示在前的元素,b为在后的元素,如果返回值大于0,就会交换位置,如果返回等于0,不换位,如果返回负值则不交换位置。a-b>0可见的这是升序排列; 函数方法call和apply;这是函数对象的方法;fun函数结构fun()函数功能; fun.call(); fun.apply(); fun(); 都是调用函数: 在调用call和apply可以将一个对象指定为第一个参数; fun.call(obj),也就是说函数的对象是obj; call()/apply()可以修改这个函数的this; fun()不行; fun.call(对象,参数,参数)这里的参数是原函数所要传递的参数; fun.apply(对象,[参数,参数])参数需要封装到数组中; call()和apply()的区别在于是否需要封装到数组中; arguments: 在调用函数是,浏览器默认会传入两个隐含的参数,一个是this,另一个就是封装实参的对象arguments; arguments:是一个类似于数组的对象,它也可以通过索引来操作对象,也可以获取长度,在调用函数时,我们传递的实参都会在arguments中保存; arguments[0]第一个实参,我们即使不定义形参也可以调用实参 arguments还有一个属性:arguments.callee这个属性的对应的函数对象,就是当前这个函数对象; Date对象: 在js中使用date对象来表示一个时间; 创建一个Date对象: var d=new Date(); 如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行的时间; //创建一个指定时间 var d2= new Date("15/10/2020 16:20:59"); //年份需要填写完整的位数,不然ie浏览器会出错 var date=d2.getDate();//获取当前对象为几号;1——31; var day= d2.getDay();//获取当前对象为周几; 0——6;0表示周日 var month=d2.getMonth()://获取当前时间返回的月份0——11;0表示1月 var year=d2.getFullYear();//返回当前对象的年份; var time =d2.getTime();//获取当前时间的时间戳,指的是从格林威治1970年1月1日0点0分0秒到现今所经历的毫秒数;方便保存,不然在计算机硬件中各种进制的数需要耗费大量的资源;一般时间都是从时间戳转换过来的; 注意这里的是格林威治时间,一般设置时间是本地时间的多少年多少月,如果设置1970年1月1日0时0分0秒会有时区的间隔; 利用时间戳测试代码的执行性能: var d=new Date(); var start=d.getTIme(); 代码 var end=d.getTime(); 代码消耗约end-start秒 Math对象: Math和其他的函数不同,他不是构造函数,它属于一个工具类不用创建对象,它里面封装了数学运算相关的属性和方法; Math.PI表示圆周率;相对于自己写的要更精确一点; abs()可以用于一个数的绝对值; ceil()对数进行上上舍入;也就是向上取整;小数位只要有值就会自动进一; floor()对数进行向下取整;小数部分就会舍去; parseInt对字符串,floor()是对数值的效率更高; round()对一个数进行四舍五入取整; random()可以生成一个0到1的随机数; //生成一个x到y的随机数:如果只是rando,()*(y-x)但是不可能生成x和y的,可以使用Math.round(x+Math.random()*(y-x));就可以创建0和10的啦; max()/min()最大值最小值。 pow(2.3)2的3次方; sqrt()平方根 包装类: 在js中提供三个包装类,可以将基本数据类型数据,转换成对象;对象比基本数据类型功能要强大一些; String()转换成string对象 Number()转换成number对象 Boolean()转换成boolean对象 var x=new String(2) 基本对象比基本数据类型更加强大; 注意:在实际应用中一般不使用基本数据类型对象,在进行比较时,可能会出现意想不到的错误。对象保存对象空间的索引,而且对象转换成布尔值都是true; 当我们对一些基本数据类型的值去调用属性和方法时;浏览器会临时使用包装类将其转化成对象,然后在调用对象的属性和方法,调用完之后再转换成基本数据类型; var s=1223; s=s.toString(); s.hello=hei;//加进去属性之后,对象就直接被销毁了;所以s.hello的值为undefined; 基本数据类型能调用对象的属性和方法; 字符串的方法: 在底层中字符串是字符数组保存的,所以可以使用length属性查找对应的字符; charAt():返回字符串中的指定位置的字符,根据参数的索引获取指定的字符; charCodeAt():返回字符串中的指定位置的字符编码; fromCharCode():根据字符编码获取字符; String.fromCharCode() concat():将两个字符串拼接一个新字符串返回,不会对原字符串做出修改; indexOf()该方法可以检索一个字符串中是否含有指定内容;如果有返回指定内容首次出现的索引; 注意indecOf()的第二个参数可以指定开始查找位置,意思是说只要检查到第二个参数大于之前使用的indexOF返回的值,就能查到字符在字符串中出现的所有位置。 lastIndexOf();从后往前查找,返回值和indexOf()相同 第二个参数也是可以选的。 slice();同样不会影响原字符串; substring()和slice()用法相同,但是substring()里面的参数不接受,自动转化成负值,而且能够自动调整参数的位置。 substr()和splice类似:参数第一个参数是开始截取位置,第二个参数是截取长度; split()将字符串拆分成数组和join()功能相反,将会根据字符串拆分数组, 参数表示按照什么符号拆分数组,一般为“,”;不会影响原字符串 str.split(","); toUpperCase()转换成大写,不会改变原字符串 toLowerCase()转换成小写,不会改变原字符串 正则表达式: 检查用户输入的对不对(格式,符号等);比如检查电子邮件的格式; 邮件设置的规则:通过正则表达式来实现; 计算机根据正则表达式是否符合规则,或者将符合规则的内容提取出来; 创建正则表达式的对象; var reg=new RegExp("正则表达式","匹配模式"); 构造函数创建正则表达式: var str="检查对象"; reg.test(str); 检查str test()用来检查字符串是否符合正则表达式的规则;符合返回true否则返回false; 匹配模式可以作为第二个参数: i是否区分大小写; g是否是全局匹配; 使用字面量创建正则表达式: var 变量=/正则表达式/匹配模式; 使用字面量创建会更简单,而构造函数会更加灵活; /a|b/搜索a或b; | /[a-z]/搜索a到z任意小写字母。 []包裹的内容都是或的关系 /[A-z]/任意字符 /a[b-e]c/搜索abc acc adc aec /[^ab]/搜索除了a或b ^ 字符串和正则相关的方法: split(): 将字符串拆分成数组; 根据任意字母去拆分,方法中可以传递一个正则表达式去拆分字符串; split([A-z]);这个方法及时不全部匹配也都是全局的 search()可以搜索字符串中是否含有指定内容;如果搜索到内容则返回搜索内容的索引,否则返回-1;这个只能查找第一个,即使设置全局匹配也没用 match()根据正则表达式,将符合条件的内容都提取出来。 默认情况下match()会搜索到第一个内容,找到后就停止检索; 我们可以设置正则表达式为全局匹配模式,这样就能匹配所有内容, 可以给正则表达式设置多个匹配模式,且顺序无所谓; match()会将匹配的结果封装到一个数组中返回,即使值查询到一个结果; 提取一些有用的信息; replace()可以将字符串中指定的内容替换成新的内容; replace()第一个是替换的内容,默认只替换一个,可以设置全局匹配;如果想删除,可以通过空串替换; str.replace(a,b); 正则表达式的语法: 量词,我们可以通过量词来设置一个内容出现的次数;{n}搜索它前面一个字符出现n次 var reg=/a{n}/;//搜索a出现n次; var reg1=/(ab){n}/; abababab,搜索这种形式的n次,使用小括号对前面内部所有字符搜索n次; {1,3}出现一次到三次;{m,n}出现m到n次;{m,}m次以上; +至少一个,相当于{1,} *表示0个或多个 ?表示0个或1个 ^中括号中表示除了,在外部表示以什么为开头; $表示结尾 . 表示任意字符就连@都能检查到,这样就没有办法检测它本身就是一个单纯的点,可以使用转义字符 \. 表示单纯的点;还有如\也需要写\\,在字符串中也需要使用两个\\ 当然这是使用字面量创建的; 如果是在构造函数时,由于她的参数是字符串,外面还有一层正则表达式,如果想写一个\.表示单纯的点 那么就需要写\\.; 如果是^a$表示a即使开头也是结尾,所以只能有1个a;如果表示以a开头以a结尾^a|a$; 创建一个表达式检测字符串是否是一个合法的手机号; 1.不能以一开头 2.第二位3到9; 3.三位以后任意数字且只用9个; ^1[3-9][0-9]{9}$ //$这里的表示结束,这里的^和$就限制了字符串必须完全符合正则表达式的要求,不然使用test就有很大挑战如"feuhiah13098909389jiodn"返回 true 使用test() \w任意字母、数字、_ \W除了字母、数字、_ \d任意数字 \D除了数字 \s空格 \S除了空格 \b单词边界 \B除了单词边界\ 单词\ 单词边界: 当搜索/child/ 而字符串中有children时,它两不是一个单词,但是如果没有单词边界,这无法判断到底是child本身,还是包含children; 需要使用/\child\/ 去除字符串中的空格: 可以使用空串来替换空格: str.replace(/\s/g,"");//去除所有空格; ^\s开头一个空格;需要写开头多个空格\s*$,需要使用全局模式 str.replace(/^\s*|\s*$/g,""); 邮件的正则表达式: 一般格式:[email protected] 还有特殊符号的.jiod@jiofa(网址字母或者数字).com.cn 任何字母数字下划线。任意字母数字下划线@任意字母数字.任意字母{2到5位}.任意字母{2到五位}; / ^\w{3,} (\.\w+)* @ [A-z0-9]+ (\.[A-z]{2,5}) {1.2} $/; DOM简介:文档对象模型 js通过dom 操作html文档,只需要了解dom就能随心所欲的修改web页面; 文档表示的是就是整个的HTML网页文档 对象表示将网页中的每一个部分转换为一个对象 模型:使用模型来表示对象之间的关系,这样方便我们获取对象 文档 html head body titile meta { 大量模型 } HTML DOM树 : (Node)节点是构成网页中的基本组成部分;nodeName nodeType nodeValue 文档节点:整个html文档 document 9 null 元素节点:html文档中的html标签 标签名 1 null 属性节点: 元素的属性 属性名 2 属性值 文本节点: 文本内容 #text 3 文本内容 可以通过nodeType区分不同的节点类型; 通过DOM树可以查找不同的节点:节点可以通过修改改变文档的内容; 事件的简介: 就是用户和浏览器交互的行为;点击按钮、关闭窗口、移动鼠标; 我们可以在事件对应的属性中设置一些js代码,这样事件就能被触发,代码就会被执行; οnclick="alert("hello第一次见面")" var btn=document.getElementById("button"); btn.οnclick=function(){ }; //绑定一个单击事件绑定的函数,我们称为单击响应函数; 文档的加载 由于代码是一行一行执行的,如果js的触发事件在btn前面(此时btn没有定义,这时候会发生错误),所以需要将代码放在获取的节点后面,这样就可以确保页面加载完毕后执行,这样不容易产生错误; onload事件是在整个页面加载完成时触发; window.οnlοad=function(){alert("nihao");} 如果非要将js代码放在前面或者需要将代码到页面加载之后执行,可以将执行代码放到window.οnlοad=function(){ 代码 }中 但是先加载js不使用,就有点浪费网络资源了,最好写在下面。不过写在上面也有好处,就是很好改js容易维护。根据需求来写。而且有些代码需要在加载页面之前就要启动也需要写在前面; dom查询: document.getElementById(""); 通过id属性获取的一个对象 document.getElementsByTagName("") 通过标签名获取一组对象(返回一个类数组对象,但不是一个数组)可以通l过length属性查询它的长度,通过获取对象的[索引]访问不同的数组对象; document.getElementsByName(""); 通过name属性获取一组对象(也是返回一个类数组对象,但不是一个数组)可以通过length查询它的长度,通过获取对象的[索引]访问不同的数组对象; innerHTML:可以通过这个属性获得元素内部的html代码;对于自结束标签没有意义; 属性的获取:获取元素.属性就能访问相应属性.id name value这种直接元素.属性名只有class不能采用这种方式,读取class时需要使用元素.classname;(本来是不想让用户来获取class的) info="一共有"+arr.length+"页,这是第"+index+1+"页";//这里是的+是拼串操作,如果想要加1需要将index+1用括号包裹起来 info="一共有"+arr.length+"页,这是第"+(index+1)+"页"; 获取元素节点的子节点: 通过元素节点调用 元素节点.getElementsTagName()方法//之前的对象是文档对象,是从整个页面查询的。这个是在元素节点下面找; 返回当前节点的指定标签名后代节点; childNodes属性(一组元素,类数组对象)://可以通过索引确定子节点,修改内容 表示当前节点的所有子节点;包括文本、注释、属性的所有节点 元素(子元素)间的空白被当成文本节点,注意在ie8及其以下没有将空白当成文本节点。一般标签之间都留有默认的空白。 children属性://可以通过索引确定子节点,修改内容 获取当前元素的所有子元素(一组元素,类数组对象):它不包括文本节点、注释节点;更合理一点; firstChild属性:表示当前节点的第一个子节点;ie8不支持 获取当前节点的第一个子节点:包括文本节点; firstElementChild: 获取当前节点的第一个子节点:不包括文本节点; lastChild属性:表示当前节点的最后一个子节点;ie8不支持 获取当前节点的最后一个子节点:包括文本节点; lastElementChild: 获取当前节点的第一个子节点:不包括文本节点; 获取父节点和兄弟节点: parentNode:父节点,获取父节点 子节点.parentNode() previousSibing:前一个兄弟节点:也可能获取到空白文本节点 previousElementSibing:前一个兄弟元素节点; nextSibing:后一个兄弟节点:也可能获取到空白文本节点 nextElementSibing:后一个兄弟元素节点; 一直获取按钮这个一个重复性的工作,可以使用定义解决这个问题; 绑定单击响应函数: function myClick(idStr,fun){ var btn=getElementById(idStr); btn=fun; } idStr:表示传递的id fun:单击响应函数 innerText属性:可以获取元素内部的文本内容:它会自动将内部html标签去除; 文本节点的文本内容就是nodeValue:可以通过子节点.nodeValue查看文本内容,相较于innerHTML,innerText要麻烦很多,知道意思就行。 全选/全不选: var checkAllBox=document.getElementById("checkedAllBox"); checkAllBox.οnclick=function(){ for(var i=0;i items[i].checked=this.checked;//根据自身是否选中决定其他元素是否选中 } } 其他元素全选,让全选按钮点亮;或者其他元素没有全选让全选灭掉; for(var i=0;i checkAllBox.checked=ture; for(var j=0;j if(!items[i].checked){ checkAllBox.checked=false; break;//不用继续判断剩余的按钮了 } } } dom查询的剩余方法: 获取body本身; 方法一:document.getElementByTagname()[0]; 方法二:document.body 获取html: document.documentElement; 获取all; var all=document.all; all.length=6 var all=document.getElementByTagName("*"); all代表页面中的所有元素; 还有一种是获取class属性的,但是这种方法不支持ie8及其以下;(获取一组元素节点对象) var box1=document.getElementByClassName("box1"); 获取box1中的div document.querySelector(.box1 div); 可以根据选择找相应的对象,功能特别强大;这个方法在ie8中可以使用,虽然没有上面的方法,可以使用这种方式查找; 使用这个方法只会返回一个元素(即便有多个满足条件);这是一种局限; document.querySelectorAll(.box div);这个也支持ie8,但是不同的是,它会将查询到的所用元素节点封装到一个数组中 即使只有一个元素节点,它也会返回一个数组; dom增删改查: 创建元素节点:createElement(); document.createElement();它需要一个标签名做参数,将会根据该标签名创建元素的节点对象; 并且将创建的对象作为返回值返回。 var li=document.createElement("li"); 创建文本节点:createTextNode(); document.createTextNode();它需要一个文本内容来作为参数,创建相应的文本节点。并将新的节点返回。 var text=document.createTextNode("dkop"); 向父节点中添加子节点:父元素.appendChild(); li.appendChild(text); 获取页面存在父元素: city.appendChild(li);在页面添加节点; removeChild();删除指定子节点; 父节点.removeChild(子节点) 子节点.parentNode.removeChild(子节点),删除自己;更常用 replaceChild();使用新节点替换旧节点 父节点.replaceChild(新节点,旧节点) insertBefore() 在指定子节点前插入新的节点;这个方法是父节点调用的 city.insertBefore(li,li); 父节点.insertBefore(新节点,旧节点) 也可以通过: innerHTML增删改等相关操作,且比较简单;但是这种方法会比上面一种消耗更大,相当于将整个父节点和它所有的兄弟节点都发生了更改。 上一种只对自己有影响。 添加删除记录: 超链接默认是为了跳转,有时候需要刷新页面的时候会将事件绑定在a元素上; //删除 function delA(){ var allA=document.getElementsByTagName("a"); for(var i=0;i all[i].οnclick=function(){ var tr=this.parent.parent;//这里不能使用allA[i],因为响应函数在被调用的时候才会执行,而这里for循环已经执行完毕了,也就是i为allA.length+1;这是后调用allA[i]就没有结果了。 var name=document.getElementsTagName("td")[a]; var flag=confirm("确认删除"+name+"吗?"); if(flag){ tr.parent.removeChild("tr"); } } } } //添加员工; var btn=document.getElementById("addbutton"); btn.οnclick=function(){ //如果提交按钮在表单中,还需要在内部先取消默认按钮; var name=document.getElementById("name"); var text=document.getElementById("text"); var salary=document.getElementById(salary"); var tr=createElement("tr"); var a=createElement("a"); a.href="javascript:void()" var ntd=createElement("td"); var nte=createElement("td"); var nsal=createElement("td"); var ndel=createElement("td"); var cname=createTextNode(name); var ctext=createTextNode(text); var csal=createTextNode(salary); var cdel=createTextNode("delete"); ntd.appendChild(cname); nte.appendChild(ctext); nsal.appendChild(csal); a.appendChild("cdel"); ndel.appendChild(a); tr.appendChild(ntd); tr.appendChild(nte); tr.appendChild(nsal); tr.appendChild(ndel); //获取table: var tab=documentElement('tab")//这天添加的是table里tbody外,而一般浏览器会添加一个tbody;这样就和之前的元素节点放在不同的地方了; // tab.appendChild(tr); //所以需要准确的添加到tbody中 var tbod=tab.getElementByTagName("tbody"); tbod.appendChild(tr); 修改之前的单击响应函数,因为这是重新添加的内容; delA(); 为可简化代码:可以修改成innerHTML输入:但是注意这里修改的不是tbody这个父节点;而是先添加一个子节点tr再向其中使用innerHTML属性,这样就不会影响整个tbody; var tr=document.createElement("tr"); tr.innerHTML=" 但是这里的超链接对象没有被创建,没有绑定单击响应函数便没有办法删除。 可以使用。 var a=tr.getElementsByTageName("a"); a.οnclick=delA; 操作内联样式: var box1=document.getElementById("box1"); box1.style.width=120px; box1.style.background-color=red;//这里的background-color中-在js中是不合法的,所以需要将-后面的字符改成大写。 例如: borderTopWidth: backgroundColor: 我们通过js中style属性修改的样式是内联样式,有较高的优先级;所以之前说不要在样式中使用!important; 通过style属性能读取内联样式,但是不能读到样式表中的样式。(能修改,不能读取) 读取元素的样式: 可以使用 元素.currentStyle.样式名 //获取当时显示的样式。如果没有该样式会显示默认值 但是这种方式只有ie支持:其他浏览器不支持; 在其他浏览器可以使用:getComputedStyle()这个只有ie8以下不支持,其他浏览器都支持 这是window的一种方法;需要两个参数 第一个需要获取样式的元素,第二个可以传递一个伪元素,一般设置为null 使用需要getComputedStyle(obj,null).width; 这个方法会返回一个对象(封装了当前元素的样式) 通过该对象.样式名; 可以查看他的当前样式,如果获取的样式没有任何样式,则会返回当前的真实的值,而不是默认值;如果没有设置 width他不回复auto而是具体的值; 设置一个兼容的函数: function getStyle(obj,name){ //没有必要判断浏览器的版本,只要看有没有getComputedStyle方法,由于该方法返回的是一个对象,所以有那么必然是true,但是如果直接写getComputedStyle判断该变量的话需要从全局中寻找,最终还是会报错。所以这么写不行;但是加了window就会将这个方法变成window的一个属性,也就不会报错 if(window.getComputedStyle){ return getComputedStyle(obj,null)[name];//对象的调用方法有两种一种是对象名.属性 还有一种是类似于数组的索引对象名[索引]} else{ return obj.currentStyle[name];} return -1; } 简化: function getStyle(obj,name){ return window.getComputedStyle?getComputedStyle(obj,null)[name]:obj.currentStyle[name]; } 通过上面两个获取的对象是不能修改的,只能通过style属性去修改样式的值; 其他样式相关属性: clientWidth:返回可见宽度(包括内容区和内边距不包括外框和外边距) clientHeight:返回可见高度(包括内容区和内边距不包括外框和外边距) 以上参数是直接返回数字,可以进行计算,不带有px;由于这是计算值(多个值混合的),所以这些属性是只读的; offsetWidth:返回元素整个宽度 offsetHeight:返回元素整个高度 offsetParent:定位父元素,如果父元素没有开启定位,就会返回祖先元素body,它返回的是离当前元素最近的开启定位的祖先元素;可以用于指导修改样式; offsetLeft:相对于定位元素的水平偏移量 offsetTop:相对于定位元素的垂直偏移量 scollHeight:滚动高度; scollWidth:滚动宽度; scollLeft:滚动条到左侧的距离; scollTop:滚动条到顶端的距离; scollHight-scollTop=clientHeight;这样表示滚动条拖动到底部;有时候需要让用户拉动到底部才能操作其他内容;比如刷新网页,协议勾选等; 如果设置表单项disabled="disabled"表示表单项不可用; 可以设置将滚动条滚动到底是才能到底时disabled="false";需要使用的标签是下一步按钮和checkbox; 当滚动条滚动时触发检测滚动条是否滚动到底(onscoll); 创建事件: p标签上''info"绑定滚动条; var info=document.getElementById("info"); var inps=document.getElementsByTagName("input"); info.onscoll=function(){ if(info.clientHeight==scollHeight-scollTop){ inps[0].style.disabled=false; inps[1].style.disabled=false; } } 事件对象:当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进相应函数; 在事件对象中封装了当前时间相关的一切信息,比如键盘的输入鼠标的移动,鼠标的点击,窗口的变化等等; onmousemove:鼠标移动事件; 元素节点.οnmοusemοve=function(event){ var x=event.clientX; var y=event.clientY; } clientX:鼠标指针的水平位置距离左边,但是ie8的event保存在window中所以需要使用window.event.clientX,火狐不支持这种方式 client是相当于浏览器的可见窗口 clientY:鼠标指针的垂直位置距离上边,但是ie8的event保存在window中所以需要使用window.event.clientY,火狐不支持这种方式 client是相当于浏览器的可见窗口 pageX:是获取鼠标相对于当前位置的横坐标,不兼容ie8 pageY:是获取鼠标相对于当前位置的纵坐标,不兼容ie8 解决事件对象兼容性问题: 解决方法和上面的getComputedStyle类似; if(!event){ event=window.event; } 简化: event=event||window.event; 大多数浏览器有event所以使用event作为主要window.event作为防止出错的备案; div跟随鼠标移动: pageX/pageY不支持ie8; 一般使用 clientY=scollTop+Top+"px"; clientX=scollLeft+Left+"px"; 等式左边clientX/clientY用来设置鼠标; 等式右边设置可以移动的对象; chrome认为浏览器的滚动条是body的 firefox认为浏览器的滚动条是html的; scollTop=document.body.scollTop||document.getElement.scollTop; scollLeft=document.body.scollLeft||document.getElement.scollLeft; 事件的冒泡(bubble): 所谓的冒泡就是事件向上传导,当后代的事件被触发,向上的祖先元素的事件也会被触发。 先触发后代,然后是父元素,最后是祖先元素。 在开发中,冒泡大多数都是有用的。比如如果在一个顶范围内自由移动,可以通过冒泡从其他元素上经过。 如果不希望发生冒泡,可以通过事件取消冒泡直接event.concelBubble=true;注意之前要使用事件的兼容;这个表达式没有兼容性问题; 事件的委派: 之前我们给每一个超链接绑定单击响应事件,需要使用for循环遍历,而绑定之后的添加的新的超链接还需要重新绑定;这样实在太麻烦,影响性能; 我们希望只绑定一次事件即可,即使元素是后来添加的。 我们可以尝试将事件共同的祖先元素。而这个方法就是事件的委派。这样当我们后代元素触发时,会自动通过冒泡触发祖先元素,从而触发事件,通过减少事件的委派次数,提高程序的性能。 event.targent表示事件触发的对象 但是这个祖先元素可能包含不想触发事件的元素。可以通过在触发元素上绑定一个class属性假设为link;最后通过祖先元素触发事件进行判断: if(event.target.className=="link"){触发此事件};但是这里的link有隐患,如果其中一个有多个classs属性,那么就和"link"不等,导致事件触发失效,可以使用正则表达式解决此类问题。/^[link]{1}|\slink\s|\slink$/; 事件的绑定: 通过响应函数只能当对同一个元素进行绑定同一个响应函数,绑定多个的话,后一个函数会将前一个覆盖掉; 可以通过 btn.addEventListener("click")// 这种方式可以为一个元素相同事件,绑定多个响应函数,它会按照事件绑定的顺序进行;它里面的this对象是触发事件的对象 参数:事件,事件的字符串,不用on;回调函数,当事件被触发是会调用;是否在捕获阶段触发事件,需要一个布尔值,一般为false; 去除事件: removeEventListener("btn"); 这种方法不支持ie8及其以下的浏览器; 可以使用attachEvent();这种方法也可以同时绑定多个事件,但是它是按照后绑定的先执行;它里面的this是window 两个参数:事件,字符串需要on;回调函数 dispatchEvent("btn");去除事件 兼容函数: function bind(obj,eventStr,callback){ //需要统一方法 //需要统一event //需要统一this //执行顺序,也可能需要统一 if(obj.addEventListener) {obj.addEventListener(eventStr,callback,false);} else{ //解决this的方法,通过匿名函数call()指定obj;匿名函数是window调用的但是callback是obj调用的 //obj.attachEvent("on"+eventStr,callback); obj.attachEvent("on"+eventStr,function(){callback.call(obj);}) } } 事件的传播流程: 事件的传播,对于事件的传播网景公司和微软有不同的理解; 微软公司认为事件应该从内而外传播,也就是说事件应该在冒泡阶段执行; 网景公司认为事件应该从外往内传播的,也就是从祖先元素传递到内部阶段,这就是事件的捕获阶段; w3c采用两种方案,将事件传播分为三个阶段; 1.捕获阶段:在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是此时不会对事件进行触发; 2.目标阶段:事件捕获到目标; 3.冒泡阶段:事件从目标开始向祖先元素触发事件; 如果希望在捕获事件阶段就触发事件,可以是第三个参数设置为true;ie8及其以下没有捕获这个阶段。 拖拽: 拖拽的步骤: 当鼠标按下时,元素可以被拖动;onmousedown 当鼠标移动时,元素跟着鼠标指针移动;onmousemove 当鼠标鼠标松开时,元素会停留在当前位置onmouseup var box1=document.getElementById("box1"); box1.οnmοusedοwn=function(event){ box1.setCapturn&&box1.setCapture(); //box1.οnmοusemοve=function(event){ }; //box1.οnmοuseup=function(event){ box1.οnmοuseοver=null; }; //上面的这个事件是给box1绑定的,会有一定的bug,比如当鼠标移动到兄弟元素上,那么就会失去这个事件的触发;所以需要将事件绑定在document上; var ol=event.clientX-box1.offsetLeft; var ot=event.clientY-box1.offsetTop; document.οnmοusemοve=function(event){ //需要将鼠标指针相对于box1位置不会发生变化;之前使用clientX=Left;只能获取鼠标指针在box1左上角的位置; //需要从点击事件时就求出偏移量(鼠标到box1左上角的位置); var left=event.clientX-ol; var top=event.clientY-ot; box1.style.left=left+"px"; box1.style.top=top+"px"; }; document.οnmοuseup=function(event){ document.οnmοuseοver=null;//此时这个事件并没有取消,所以还会被触发,所以需要取消该事件:document.οnmοuseup=null; document.οnmοuseup=null; }; return false; }; //这里还有一个问题,就是当我们去在一个页面去拖拽内容时,浏览器会默认去搜索引擎搜索内容;如果不希望发生这个行为,可以通过return false取消这个行为; //但是这对ie8不起作用:设置box1设置setCapture()(点击任何按钮都会默认点击元素,移动只会移动它一个);但是这只是捕获一次,但是当鼠标再次点击,也会触发该事件,所以需要在onmouseup中取消捕获,releaseCaptrue();但是这在chrome中会报错;可以使用元素.setCapturn&&元素.setCapture(); 提取专门的拖拽函数: function dray(obj){ //box1改为obj;给目标设置一个开启定位,就可以运行了; } 滚轮事件: onmousewheel:鼠标滚轮的时间,会在滚轮滚动的触发该事件,但是火狐不触发该事件; wheelDelta:鼠标滚动的方向,向上滚是正值,向下滚是负值,很多浏览器这个属性返回值不同,所以不用考虑值的大小,火狐中detail向上是-3负值,向下是3正值; if(event.wheelDelta>0||event.detail<0){向上滚动}else{向下滚} //当浏览器有滚动条时,如果在指定元素上滚动会触发浏览器的默认行为;,这会使浏览器窗口和元素一起发生滚动,需要取消默认行为; 在触发某个事件函数中添加event.preventDefault();当移动到指定元素,浏览不会发生滚动事件;这个属性ie8不支持 event.preventDefault&&event.preventDefault();有就使用; 键盘事件: 键盘事件一般绑定在获取焦点的对象,或者文档事件; onkeydown:键盘事件被按下; onkeyup:键盘事件被松开; 对于事件来说当键盘一直被按下,它会一直触发事件;第一次和第二次触发的时间稍微长一点,防止误触发; 可以通过keycode获取按键编码;也就是说判断哪个按键被按下了; 同时按下的按键怎么判断呢? 这样?if(event.keycode===19&&event.keycode===85),这是明显错误的,没有一个值能够既等于19又等于85,可以通过单独的键盘事件判断是否同时按键; altkey ctrlkey shiftkey 这三个是单独的触发的: 在文本框中输入内容是文本框中的默认行为;可以通过return false;取消默认行为;,可用于指定用户输入内容功能,不然无法显示; 键盘移动: 37左 38上 39右 40下 判断键盘事件可以用swith语句来判断事件,绑定操作; //设置变量speed可以修改变量的速度; var speed=10; //加速; if(event.keyctrl){speed=30;} switch(event.keycode) { case 37: box1.style.left=box1.offsetLeft-10(speed)+"px"; break; case 38: box1.style.top=box1.offsetTop-10(speed)+"px"; break; case 39: box1.style.right=box1.offsetRight+10(speed)+"px"; break; case 40: box1.style.bottom=box1.offsetBottom+10(speed)+"px"; break; } 但是这个也有个缺陷,之前说过浏览器为了防止误触发,在第一次到第二次触发的时间间隔更长。需要使用定时调用来修改; BOM:浏览器对象模型; BOM可以让js操作浏览器的,在bom中定义了一组对象,用来完成对浏览器的操作; BOM对象: Window对象: 代表浏览器的整个窗口,同时window也是网页的全局对象; Navigator:代表当前浏览器的信息,通过该对象可以识别不同的浏览器; Location:代表当前地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面; History:代表浏览器的历史记录,可以通过该对象中操作浏览器的历史记录 由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页; 而且该对象访问当前访问有效; Screen:代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的信息;做移动端,响应式都需要使用; Navigator对象: appName:获取当前浏览器名称,除了ie9及其以下,都比较正常,而现在都会显示netscape;(通常是主流浏览器) 这里的大量属性,已经不能使用了。 以前由于ie的特殊性,很多资源不能调用,导致一些网站给ie的资源不如其他浏览器,而这也是识别ie的手段之一,后来ie就向大多数浏览器妥协,于是越来越像普通浏览器; 弃用了许多特殊的属性;就连appName也变成了netscape; 一般使用userAgent来判别浏览器信息; userAgent就是一组字符串,不同的浏览器有不同的浏览器信息; 而这里面也有很多重复的内容;但也有区分信息,可以使用正则表达式来区分浏览器中有无浏览器信息; var ua=Navigator.userAgent; if(/firefox/i.test(ua){ //是否为火狐浏览器 }else if(/chrome/i.test(ua)){} else if(/mise/i.test(ua)){测试ie10及其以下} // ie11之后ie浏览器消除了这个方式 我们可以通过浏览器中特有的对象来判断是否是ie浏览器; 如果ActiveXObject有则判断是ie; //if(window.ActiveXObject){这是ie浏览器;},这个也不行;,使用in来判断;它采取返回是false,一般ie采用返回true if("ActiveXObject" in window){}//通过判断属性中有没有这个属性;有返回true; History对象: 操作浏览器向前,向后翻页; histoty.length:表示访问当前浏览器中历史记录的数量(单次访问的数量,不在具体的浏览器的数量),关闭时消失; back():回退,可以用来回到上一个页面; forward():前进,可以跳转到下一个页面; go(n):跳转到当前页面第n个页面, n为正值前跳,n为负值后跳; Locatiion对象: 如果直接打印location则可以获取当前地址栏上的信息;(完整的路径); location="";如果直接修改完整的路径或者相对路径,则页面会自动跳转到该页面;并且生成相关的历史记录; location的对象属性,将地址分为好几个部分,可以之后学习了解; location的方法: assign(): location.assign():和赋值的方式是一个样的。 reload();从新加载当前页面,作用和刷新按钮一样; ctrl+f5:强制清空缓存; location.reload(true);强制清空缓存;没有true不强制; replace()使用新的页面替换当前页面;跳转不能回退;不会生成历史记录; 定时器简介: for循环当调用一条语句的时候,不能看到具体的细节,如果希望程序每间隔一段时间调用一次, 就需要使用setInterval()定时调用,这个可以使函数每隔一段时执行一次, 第一个参数为回调函数,这个函数每隔一段时间调用一次,第二个参数是间隔的时间,单位毫秒; 它会以数字作为返回值,这个数字代表这个定时器的唯一标识 var x=setInterval(function(){},1000); 关闭定时器, clearInterval()方法中需要定时器的标识关闭这个定时器:可以传递这个数字,一般来说直接将定时器赋值给一个指定的变量,然后将变量作为参数来关闭定时器; clearInterval(x);//x可以传入任意一个类型,有效就会停止,无效也不会报错; 切换图片练习; var img=document.getElementById("img1"); var imgArr=[image/01.png,image/02.png,image/03.png]; var index=0; var set1=setInterval(function(){ index++; if(index==imgArr.length){ index=0; } img.src=imgArr[index]; },1000) img.οnclick=function(){ if(set1){ clearInterval(set1); } else{ var set1=setInterval(function(){ index++; if(index==imgArr.length){ index=0; } img.src=imgArr[index]; },1000) } } 开启定时器之后需要及时关闭,不然容易在开启之后,会误创建多个定时器,由于set1被反复赋值,前一个的标识被后一个标识覆盖掉了,从而关闭不掉; 修改div练习: 速度交给定时器控制,方向交给键盘事件判断,然后设置一个键盘松开事件判断重置变量的方向,就能完成连贯的操作; window.οnlοad=function(){ var speed=10; var dir=0; var set1= setInterval(function(dir){ switch(dir){ 判断执行 } },30) document.οnkeydοwn=function(event){ event=event||window.event; var dir=event.keycode; if(event.keyctrl){ speed=50; }}; document.οnkeyup=function(event){ dir=0;speed=10; }; }; 延时调用: setTimeout(参数一,参数二) 这个函数参数一过参数二毫秒调用一次;应用网页上一些广告,过一段事件自动关闭; 这两个可以互相代替的的; clearTimeout()可以清楚延时调用; 小功能: ie浏览器没有设置的值都会返回默认;最好在使用的时候设置一个默认值; 将一个功能集成后,可以设置多个参数,如对象 属性 目标 方向 回调函数等; 其中的回调函数,可以让方法多次调用,更好的 与其他功能集成; callback&&callback()表示有回调函数就调用回调函数。回调函数表示函数执行完毕之后才去调用的。其他的可以模仿这个设置,没有传参该如何执行; 轮播图: 轮播图的横向图片的宽度不要写死了,不然添加新的元素,会让多余的元素自动换行,应该通过计算内部轮播图片的数量定义轮播图的宽度。 创建导航链接随着轮播图一个跳动;这个的宽度和居中也不能写死,不然添加新元素后,它会变样,不居中;使用计算值,添加元素之后整体距离两端的距离(大容器的宽度-导航链接的宽度)除以2就能完成居中了; 对所有的超链接绑定单击响应函数,链接到相应图片; 还需要获取点击超链接的索引; for (var i=0;i //给每一个a超链接绑定一个索引,这样就能知道点击的是哪一个超链接 all[i].num=i; all[i].οnclick=function(){ index=this.name; imgListLeft=index*(-520)+"px"; } } 创建点击动画:动画执行一次向左滑动或者直接滑动到对应的位置,随着动画的执行,超链接的样式也需要发生变化。 创建轮播动画:每隔三秒会执行一次动画向左滑动; 这里的点击动画会和轮播动画产生冲突,可以设置在点击时取消轮播动画,当这个动作执行完成,设置轮播动画定时器,就可以避免这个问题; 这里还有就是到最后一张图片时,它会慢慢的往前滑动,滑动到时,可能就会跳转到下一个图片了,所以在这里需要多设置一个图片不绑定链接,当滑动到最后一张图时,直接以修改索引为第一张图片的索引。不让其参与动画。 类的操作: 通过style属性修改元素的样式,每修改一次,浏览器就需要重新渲染一次页面;当修改多个样式时,一行一行的修改样式,就会消耗大量的浏览器资源,而且在开发中, 这种js修改,还会让原本的文档更加的混乱,要修改样式还得去js中去寻找。 我们需要的做的是, 一行代码修改多个样式; 我们可以通过修改(添加)元素的class属性,来修改文本的样式,这样一来我们只需要修改一次,就能修改多个样式,浏览器只需要重新渲染一次。这种方式可以使表现和动作分离;(先在css中定义需要修改的样式; box.className+=" b2"//b2前面有一个空格,不然的话会将两个字符串拼接在一起,从而导致原有的class属性实现,如class="b1"拼接之后有class="b1b2",需要空格隔开; 定义一个函数,用来向一个元素中指定的class属性值添加属性; function addClass(obj,cn){ if(hasClass(obj.cn)){ obj.className+=" "+cn;}//这样会产生重复的class } function removeClass(obj,cn){ if(hasClass(obj,cn)){ var reg=new RegExp("\\b"+cn+"\\b"); obj.className=reg.replace(cn,""); } } function hasClass(obj,cn){ //判断obj中是否有class; var reg=/^(cn){1}\s|\s(cn){1}\s|\s(cn){1}$}/; //这种方式是没有办法设置变量,需要使用构造函数; var reg=new RegExp("\\b"+cn+"\\b");\b表示单词边界,表示cn是独立的; return reg.test(obj.className); } function toggleClass(obj,cn){ //判断有删除,没有添加; var reg=new RegExp("\\b"+cn+"\\b"); if(hasClass(obj,cn)){ obj.className+=" "+cn; else{ obj.className=reg.replace(cn,"");} } 二级菜单: 实现的相同动画的方法,最好也是相同的,这样可以节省很多代码; 动画过渡的参数,可以先从控制台上输出从而获取; 动画过渡的结束之后,可能还会残留内联样式导致下一次调用动画会失败; JSON: 服务器和客户端之间,需要存在通信;而服务器和客户端的语言不同,虽然js能够读自己的对象,但是服务器不一定认识。 JSON就是特殊格式的字符串,这个字符串任何语言都能识别,并且可以转换成任意语言的对象;这样就可以将js中的对象和其他语言的对象交互; (javascript object notation)JSON的格式和js的对象是一样的,只不过JSON字符串中的属性名必须加双引号; JSON有两种: 一种是对象{}包裹; JSON:var json='{"name":"nihao","sex":"男"}'; 另一种是数组[]包裹; JSON:var json='["name":"nihao","sex":"男"]'; JSON中的允许值 1.字符串 2.数值 3.布尔值 4.对象(普通对象;不包括函数对象) 5.null 6.数组; //undefined不能,还有就是函数不能传; 需要将字符串转换成对象: 在js中提供了一个工具类,就叫JSON;它既可以将JSON转化成对象,也可以将对象转换成JSON; JSON.parse(json);它需要将一个JSON字符串作为参数,会将字符串转换成JSON对象;它返回一个对象/数组; 将js对象转换成JSON; JSON.stringify()可以将一个js对象转换成JSON字符串,需要添加一对象作参数; JSON常用,作为数据交互对象:轻量级,速度较快的数据交换格式; 但是JSON在IE7及其以下的浏览器不支持,所以在这里调用会报错。 如果需要兼容ie6,ie7;需要使用eval()函数,这个函数可以执行字符串形式的代码,并将执行结果返回; 如果执行字符串中含有大括号,它会将大括号当做代码块; 如果不希望将其当做代码块解析,需要将字符串前后江上一个() var obj=eval("("+json+")");通过eval()将JSON很容易转换成字符串; eval()这个函数虽然功能强大,但是也用很大的副作用,如消耗很大,安全隐患; 真要兼容ie7及以下的JSON的操作,则可以通过引入一个外部的js文件来处理;在网上能够搜索到兼容ie6,7的js; 来自尚硅谷2016年视频 笔记(李立超的) 中的员工
name:
text:
salary:
"+name+" "+ ""+text+" "+ ""+salary+" "+ "delete ";
你可能感兴趣的:(javascript,javascript)