JavaScript基础与API(上)

浏览器执行

浏览器分成两个部分:渲染引擎和JS引擎。

渲染引擎:用来解析html、css,俗称内核,比如chorme的blink,老版本的webkit

JS引擎:称为JS解析器,读取网页中的JS代码,对它处理后运行

JS是高级编程语言,浏览器读到scrip时,JS引擎将JS代码转为二进制机器语言。机器语言能识别就能执行这个代码。JS引擎执行代码时会逐行解释每一句源码,转为机器语言,然后交给计算机执行,所以JS归为脚本语言,会逐行解释执行。

编译型语言和解释型语言:

编程语言  ->  解释器翻译(编译器在代码执行前进行编译)  -> 机器语言(二进制)

编程语言  ->  解释器翻译(解释器在运行时进行及时解释,立即执行)  -> 机器语言(二进制)

JS组成

ECMAScript(JS语法) 、DOM(页面文档对象模型)、BOM(浏览器对象模型)【api】

ECMAScript规定了JS的编程语法和基础核心知识,是所有浏览器厂商共用遵守的一套JS语法工业标准。

JS书写

分为三种:行内、内嵌和外部。

行内:

<body>

    <input type="button" value="唐伯虎" onlick="alert('唐伯虎')">

</body>

 

内嵌式:

<scrip>

    alert('唐伯虎');

</scrip>

 

外部:

js文件:alert('唐伯虎');

引入:

<script src="my.js"></script>

 

注意:js推荐用单引号,html推荐用双引号

行内式写法:可读性差、引号容易出错,在引号多层嵌套匹配时,容易弄混、特殊情况下使用。

内嵌式:常用

外部:适用于js代码量比较大的情况,引用JS的scrip标签中间不可以写代码。

JS输入输出语句

方法一:alert():浏览器弹出警示框,归属浏览器

方法二:console.log():浏览器控制台打印输出信息,归属浏览器

这是程序员能看到的,按F12在console看到。

方法三:prompt():浏览器弹出输入框,用户可以输入,归属浏览器

 prompt()取出来的是字符型。

JS变量

1.声明变量并赋值()

var 变量名1=变量值1,变量名2=变量值2;

比如:

<script>

        var username=prompt('请输入用户名');

        alert(username);

    </script>

2.声明变量的特殊情况

(1)只声明变量,不赋值=>   undefined未定义的

(2)不声明,不赋值,直接用=> 报错

(3)不声明,只赋值 =>  age=10;console.log(age)   输出10;

underfined和数字相加,显示NaN

JS数据类型

js变量数据类型只有程序在运行过程中,根据=右边的值来确定。JS是一种弱类型或动态语言。

数据类型分类:

简单数据类型:Number(数字型,包含整型和浮点型,默认0)、String(字符串类型,要带引号)、Boolean(布尔值类型,默认false)、Undefined(默认underfined)、Null(默认null)

复杂数据类型:object

8进制需要在数字前加个0

16进制需要在数字前加0x

Number.MAX_VALUE

Number.MIN_VALUE

Infinity:无穷大,大于任何值

-Inifinity:无穷小

NaN:代表一个非数字

isNaN():判断是否是数字,是:false;不是:true

string.length:获取字符串长度

stringa+stringb=拼接后的新串;拼接前将类型转为字符串再拼接。

引引加加:console.log('hello' '++age' 'world');

typeof 变量:得到变量是什么类型的。

数据类型转换

1.其他类型转为字符串:

toString()

String(变量)  【强转】

+拼接字符串

 

2.其他类型转为数字型

parseInt(string) :        将string转为整型

parseFloat(string):     将string转为浮点型

Number():   将string类型转为数值型

js隐式转换(-*/)  :比如console.log('12'-0);

 

3.其他类型转为布尔类型

Boolean():代表空、否定的值会被转为false,比如''、0、NaN、null、undefined

                    其余转为true

运算符

==:在判断时候会自动转类型,比如console.log('12'==12);  => true

===  !== :全等,要求值和数据类型都一致 ;不全等

逻辑与:表达式1&&表达式2

如果表达式1为真,返回表达式2【逻辑或相同,也有短路】

表达式1为假,返回表达式1

流程控制有三种结构:顺序、分支、循环。 

 

数组

数组就是一组数据的集合

1.通过new 的方式创建数组

 var arr=new Array();

2.利用数字字面量创建数组(使用最多)

var arr=[];

可以通过修改arr.length来实现扩容。没有声明的变量默认值undefined

 

函数

声明方式一:

function getSum(num1,num2){

   return num1+num2;

}

getSum(1,2);

声明方式二:(匿名函数)

var sum=function(num1,num2){

  console.log(num1+num2);

};

sum(1,2);

注意:

如果实参的个数=形参的个数,正常输出结果

实参个数>形参个数,取形参个数

实参个数<形参个数,那剩下的形参就是undefined;1+undefined=NaN

如果函数没有return,返回undefined

如果无法确定多少个参数传递时,用arguments来获取,它实际上是当前函数的内置对象。arguments对象中存储了传递的所有实参。

 

作用域

全局作用域:整个script标签或一个单独的js文件。如果在函数内部没有声明直接赋值的变量也属于全局变量。

局部作用域:在函数内部;函数的形参也可以看成局部变量。

全局变量只有浏览器关闭的时候才会销毁,比较占用内存资源

局部变量,当我们程序执行完就会销毁。

ES6的时候新增了块级作用域{},if{} for{}

预解析

JS代码通过JS解析器执行,解释器运行JS代码时候,分为两步:预解析和代码执行。

1.JS解释器会把JS里面所有的var 、function提升到当前作用域的最前面。

2.代码执行,按照代码的书写顺序从上往下执行

预解析分为变量预解析(变量提升)和函数预解析(函数提升)

(1)变量提升,就是把所有变量声明提升到当前作用域的最前面,不提升赋值操作

(2)函数提升,就是把所有的函数声明提升到当前作用域最前面,不调用函数

 

对象

创建对象的三种方式:

1.用字面量创建对象

对象的字面量是{}

var obj={

   username:'lkq',

  age:18,

  sex:'男',

  sayHi:function(){

    console.log('hi~');

   }

};

调用属性:

obj.username;

obj['username'];

2.用new Object创建对象

var obj=new Object();

obj.username='lkq’;

obj.sayHi=function(){

  console.log('Hi');

}

3.用构造函数创建对象

  构造函数就是把对象一些公共的属性和方法抽取出来,封装到函数中去。

1.new构造函数在内存中创建一个空的对象

2.this指向刚才创建的空对象

3.执行构造函数里面代码,为这个空对象添加属性和方法

4.返回这个对象

function 构造函数名(属性){

  this.属性=值;

 this.方法=function(){}

}

new 构造函数名(属性);

function star(username,age,sex){

 this.name=username;

 this.age=age;

 this.sex=sex;

}

var lkq=new star('lkq',18,'男');

遍历对象

for(var k in obj){

  console.log(k);//属性名

  console.log(obj[k]);//属性值

}

内置对象

js中对象分为三种,自定义对象、内置对象、浏览器对象。

内置对象就是js语言自带的一些对象,这些对象供开发者使用,提供一些常用基本必要的功能。

查阅文档:https://developer.mozilla.org/zh-CN/

Math

console.log(Math.PI);

console.log(Math.max(1,3,99));//如果里面有其他类型,无法转换,返回NaN

Math.abs():绝对值

Math.floor():向下取整(去掉小数)

Math.ceil():向上取整(取最接近最大的整数)

Math.round():四舍五入

Math.random():返回一个浮点数,范围在【0,1)

得到两数之间的随机整数
function getRandom(min,max){
 min=Math.ceil(min);
 max=Math.floor(max);
 return Math.floor(Math.random()*(max-min))+min;
}
得到两数之间的随机整数,包括两个数
function getRandom(min,max){
  min=Math.ceil(min);
  max=Math.floor(max);
  return Math.floor(Math.random()*(max-min+1))+min;
}

Date

var date=new Date();//没有参数,返回系统的当前时间

var date=new Date('2020-10-1 12:12:12');//常用

var date=new Date(2020,10,1);//会返回11月,比写的大一月

方法名说明代码
getFullYear()获取当年dateobj.getFullYear()
getMonth()获取当月(0-11)dateobj.getMonth()
getDate()获取当天日期dateobj.getDate()
getDay()获取星期几(周日0-周六6)dateobj.getDay()
getHours()获取当前小时dateobj.getHours()
getMinutes()获取当前分钟dateobj.getMinutes()
getSeconds()获取当前秒钟dateobj.getSeconds()

 

date.valueOf():距离1970.1.1总的毫秒数

date.getTime():同上

简单写法:var date=+new Date();

Date.now():H5新增的总的毫秒数

倒计时:

思路:输入的时间(开卖的时间)-现在时间=剩余的时间,但是不能拿时分秒相减,比如05分-25分,就变成了负的了。

用时间戳来做,输入的总毫秒数-现在时间总毫秒数=剩余时间的毫秒数。

再把剩余时间转换成时分秒

var day=parseInt(总秒数/60/60/24) ;//得到天数

var hour=parseInt(总秒/60/60%24);//小时

var minites=parseInt(总秒/60%60);//分钟

var second=parseInt(总秒%60);//秒

function countDown(time){
  var nowTime=+new Date();
  var inputTime=new Date(time);
  var times=(inputTime-nowTime)/1000;
  var d=parseInt(总秒数/60/60/24) ;//得到天数
  var h=parseInt(总秒/60/60%24);//小时
  var m=parseInt(总秒/60%60);//分钟
  var s=parseInt(总秒%60);//秒
  return d+'天'+h+'时'+m+'分'+s+'秒';
}

数组对象

检测是否是数组:instanceof 和Arrays.isArray(arr)

例子:var arr[]; console.log(arr instanceof Array);

 

添加删除数组元素:

方法名说明返回值
push(参数1...)末尾添加一个或多个元素返回新的长度
pop()删除数组最后一个元素,把数组长度-1,无参数、修改原数组返回删除元素的值
unshift(参数1...)向数组的开头添加一个或更多元素,注意修改原数组返回新的长度
shift()删除数组的第一个元素,数组长度-1,无参数、修改原数组返回第一个元素的值

数组排序:

方法名说明是否修改原数组
reverse()颠倒数组中元素的顺序,无参数该方法会改变原来的数组,返回新数组
replace('被替换字符','替换为的字母')只会替换第一个字符 
sort()对数组中的元素进行排序该方法会改变原来的数组,返回新数组

arr.sort(function(a,b)){ //升序排列,逆序return b-a;

   return a-b;

}

数组索引:

方法名说明返回值
indexOf()数组中给定元素的第一个索引存在返回索引号,不存在返回-1
lastIndexOf()在数组中的最后一个索引存在返回索引号,不存在返回-1

数组去重:

思路:遍历数组,拿着旧数组元素去新数组中查找,如果没有就添加,没有就不加。

利用indexOf()知道元素是否存在

function unique(arr){
  var newArr=[];
  for(var i=0;i<arr.length;i++){
     if(newArr.indexOf(arr[i])==-1){
       newArr.push(arr[i]);
     }else
     continue;
  }
 return newArr;
}

数组转为字符串

方法名说明返回值
toString()把数组转换成字符串,逗号分隔每一项返回一个字符串
join('分隔符')把数组中所有元素转为一个字符串,用指定分隔符分隔返回一个字符串
方法名说明返回值
concat()连接两个以上的数组,相当于+返回一个新数组
slice()数组截取slice[begin,end)返回被截取的新数组
substr(star,leng)从start开始,len取个数 
substring(start,end)和slice()基本相同,但是不接受负值 
splice()数组删除splice(第几个开始,删除个数)返回被删除的新数组

字符串不可变:值不可变,虽然看上去内容可以改变,实际上地址变了。

查找字符串中某个字母出现的位置及次数

思路:先找第一个字母出现位置,然后只要indexOf()返回的不是-1,就继续往后查找。

找到以后,后面的查找利用找到的参数+1,继续找。

var str="aasafdsfdsfds";

var index=str.indexOf('o');

while(index!=-1){

  console.log(index);

  index=str.indexOf('o',index+1);

}

 

根据位置返回字符:

方法名说明使用
charAt(index)返回指定位置的字符str.charAt(0)
charCodeAt(index)获取指定位置处的ascii码str.charCodeAt(0)
str[index]获取指定位置处字符 

 

判断字符串中出现次数最多的字符,并统计次数

var str="sfdsfdssdfdfgrsa";

var o={};

for(var i=0;i<str.length;i++){

   var chars=str.charAt(i);

   if(o[chars]){

      o[chars]++;

  }else{

   o[chars]=1;

  }

//遍历对象

 var max=0;

 var ch='';

for(var k in o){

  if(o[k]>max){

      max=o[k];

      ch=k;

   } 

}

console.log(ch);

console.log(max);

 

数据类型

简单数据类型和复杂类型

简单数据类型叫做基本数据类型或者值类型 (null属于object),放到栈中,栈中存放的是值。

复杂类型叫引用类型(通过new 出来的,比如Array()、Object()、Date()等),放到堆中,地址存放栈中,地址指向堆

 

简单类型传参:

函数的形参可以看成一个变量,当我们把一个值类型变量作为参数传给函数的形参时,是把变量在栈空间的值复制了一份给形参,在方法内对形参做任何修改,都不会影响到外部变量。

复杂类型传参:

形参和实参其实保存的是一个堆地址,所以操作的同一个对象。

 

Web API

是浏览器提供的一套浏览器功能和页面元素的API(BOM和DOM)

 

DOM

是一个接口,处理可扩展标记语言(HTML或XML)。简单理解就是处理页面、处理文档的接口。

W3C定义了一系列的DOM接口,通过DOM接口可以改变网页的内容、结构和样式。

文档:一个页面就是一个文档,DOM里用document表示。

元素:页面中所有的标签,DOM用element表示

节点:网页中所有的内容(标签、属性、文本、注释等),DOM中用node表示

DOM把以上内容看成对象,DOM在实际开发中主要用来操作元素的。

 

如何获取页面中的元素?

1.根据元素ID获取

getElementById()方法获取带有ID的元素对象

【script标签要写在id的后面,因为页面文档从上往下加载,所以得先有标签】

<div id="time">2020-9-27</div>

<script>

   var timer=document.getElementById(time);//返回的是一个DOM的element对象

  console.dir(timer);//打印的是我们返回的元素的对象,能更好地查看里面的属性和方法

</scrip>

2.根据标签名获取

getElementsByTagName():返回带有指定标签名的对象的集合

<ul>

   <li>hello</li>

   <li>hello</li>

   <li>hello</li>

</ul>

<ul id="nav">

   <li>world</li>

   <li>world</li>

   <li>world</li>

</ul>

<script>

   var list=document.getElementsByTagName('li');

  console.log(list);//以伪数组方式存储,得到的是一个对象的集合。得到的元素对象是动态的。

  var nav=document.getElementById('nav');

  var navList=nav.getElementsByTagName('li');//得到某个元素里面的某个标签

  console.log(navList);

</script>

3.通过HTML5新增的方法获取

1.document.getElementsByClassName('类名');//根据类名返回元素对象集合

2.document.querySelector('选择器');//根据选择器返回第一个元素的对象,比如 .box、#nav、li

3.document.querySelectorAll('选择器');//根据指定选择器返回所有元素

4.特殊元素获取

获取body元素:

var bodyEle=document.body;

获取html元素:

var htmlEle=document.documentElement;

 

事件基础

事件:被js检测到的行为,简单理解就是触发——响应的机制。

事件由三部分(三要素)组成:事件源(事件被触发的对象)、事件类型(怎么触发?鼠标点击-onclick?鼠标经过?键盘按下?)、事件处理程序(通过一个函数赋值的方式完成)。

<body>

  <button id="btn">hello</button>

  <script>

    var btn=document.getElementById('btn');

    btn.οnclick=function(){

     alert('world');

    }

   </script>

</body>

常见的鼠标事件:

鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
onmouseout鼠标离开触发
onfocus获得鼠标焦点触发
onblur失去鼠标焦点触发
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发

操作元素

利用DOM操作可以改变元素内容、属性等。

修改元素内容:

element.innerText(从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉)

element.innerHTML(从起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行)

<body>

   <button>显示当前系统时间</button>

   <div>某个时间</div>

   <p>1122</p>

  <script>

    var btn=document.querySelector('button');

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

   btn.οnclick=function(){

    div.innerText=getDate();

   }

  function getDate(){

   var date=new Date();

   var year=date.getFullYear();

   var month=date.getMonth()+1;//月份从0开始

   var dates=date.getDate();

   var arr=['星期日‘,‘星期一’,‘星期二’,‘星期三’,‘星期四’,‘星期五’,‘星期六’];

   var day=date.getDay();//周天是0,

 return '今天是'+year+'年'+month+'月'+dates+'日'+arr[day];

 }

 //不添加事件的写法:

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

   p.innerText=getDate();

 </script>

</body>

 

innerText和innerHTML的区别:

1.innerText不识别html标签,innerHTML识别,是W3C推荐

比如:

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

 div.innerHTML='<strong>今天是:</strong>2020';

2.innerText会去除空格和换行,innerHTML会保留

 

常用元素的属性操作:

1.src、href

2.id、alt、title

eg:实现点击刘德华按钮,显示刘德华图片,点击张学友按钮,切换到张学友图片

<body>

   <button id="ldh">刘德华</button>

   <button id="zxy">张学友</button>

  <img src="images/ldh.jpg" alt="">

  <script>

    //1.获取元素

    var ldh=document.getElementById('ldh');

    var zxy=document.getElementById('zxy');

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

   //2.注册事件 处理程序

    zxy.οnclick=function(){

     img.src='images/zxy.jpg';

     img.title="张学友";

    }

    ldh.οnclick=function(){

     img.src='images/ldh.jpg';

     img.title="刘德华";

    }

  </script>

</body>

 

案例:在不同的时间,显示不同的问候语

<body>

    <img src="images/s.gif" 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/s.gif';

       div.innerHTML='上午好';

    }else if(h<18){

      img.src='images/x.gif';

      div.innerHTML='下午好';

   }else{

     img.src='images/w.gif';

    div.innerHTML='晚上好';

   }

   </script>

</body>

表单元素的属性操作

比如type、value、checked、selected、disabled

案例:点击按钮后,输入框内容改变

<body>

   <button>按钮</button>

   <input type="text" value="输入内容">

   <script>

     var btn=document.querySelector('button');

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

    btn.οnclick=function(){

     // input.innerHTML这个是普通盒子里比如div标签里面的内容,采用innerHTML

    //表单里的值是通过value来修改的

    input.value='被点击了';

    input.disabled=true;//想让这个按钮点击一次后,禁用。this.disabled=true效果同。this指的是事件函数的调用者=btn

     }

   </script>

</body>

 

 案例:点击按钮将密码框切换为文本框,可以查看密码明文

(一个按钮两个状态,点击一次切换文本框,再点击一次切换密码框)

<style>

    .box{

     position:relative;

     width:400px;

     border: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>

<body>

    <div class="box">

    <label for="">

        <img src="images/close.png" alt=""  id="eye">

     </label>

    <input type="password" name="" id="pwd"> 

   </div>

   <script>

     var eye=document.getElementById('eye');

     var pwd=document.getElementById('pwd');

     var flag=0;

     eye.οnclick=function(){

         if(flag==0){

           pwd.type='text';

           flag=1;

          }else{

            pwd.type='password';

           flag=0;

          }

     }

</body>

 

样式属性操作:

通过JS修改元素的大小、颜色、位置等样式。

1.element.style; //行内样式操作,用这个方法修改,产生的是行内样式,权重比较高

2.element.className;//类名样式操作,修改样式较多可以用这个方法,className会直接更改元素类名,会覆盖原先类名

(如果想保留原先的类名,就用多类名选择器 this.className='first change';)

通过方法一:

<style>

   div{

     width:200px;

     height:200px;

     background-color:pink;

    }

</style>

<body>

    <div></div>

    <script>

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

     div.click=function(){

        this.style.backgroundColor='purple';//属性采取驼峰命名法

        this.style.width='250px';

      }

    </script>

</body>

通过方法二:

<style>

.change{

   background-color:purple;

   ....

}

</style>

<body>

    <div>文本</div>

    <script>

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

     test.οnclick=function(){

        this.className='change';

    }

   </script>

</body>

 

案例:点击x,关闭图片(利用display的显示block和隐藏none)

<style>

   省略.box 和.box img

    .close-btn{

      position:absolute;

      top:-1px;

      left:-16px;

      width:14px;

     height:14px;

     border:1px solid #ccc;

     line-height:14px;

     cursor:pointer;

  }

</style>

<body>

   <div class="box">

   淘宝二维码

  <img src="images/tap.png" alt="">

  <i class="close-btn">x</i>

  <script>

     var btn=document.querySelector('.colse-btn');

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

     btn.οnclick=function(){

       box.style.display=none;

     }

  </script>

</body>

案例:循环精灵图(利用for循环修改精灵图的背景位置)

<body>

    <div>

     <ul>

        <li></li>

        <li></li>

      </ul>

   </div>

   <script>

    var list=document.querySelectorAll('li');

    for(var i=0;i<list.length;i++){

     var index=i*44;

     list[i].style.backgroundPosition='0 -'+index+'px';

     }

    </script>

</body>

 

案例:搜索栏点击,默认字没了,点别的地方默认字出现(获得焦点onfocus,失去焦点onblur)

如果失去焦点,且表单内容为空,就给它还原默认字。如果获得焦点,判断是否是默认字,是就清空内容。

<body>

    <input type="text" value="手机"></input>

    <script>

    var text=document.querySelector('input');

    text.οnfοcus=function(){

       if(this.value=='手机')

         this.value='';

      this.style.color='#333';//获得焦点把文本框文字颜色变黑

    }

    text.οnblur=function(){

     if(this.value=='')

          this.value='手机';

      this.style.color='#999';//失去焦点把文本框文字颜色变浅色

     }

    </scrip>

</body>

 

案例:密码框提示信息:密码较短,最短支持6个字符

首先判断的事件是表单失去焦点onblur,如果输入正确,就提示正确信息,小图标变为绿色。

如果输入不是6-16位,提示错误信息,小图标变红x。

.wrong{

   color:red;

   background-image:url(images/wrong.png);

}

<body>

      <div class="register">

          <input type="password" class="pwd">

          <p class="message">请输入6-16位密码</p>

     </div>

    <script>

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

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

     pwd.οnblur=function(){

       if(pwd.value.length<6||pwd.value.length>16){

           message.className='message wrong';

           message.innerHTML='您输入的位数不对,要求6-16位';

      }else{

        message.className='message right';

        message.innerHTML='输入的正确';

     }

   }

  </script>

</body>

排他思想:

假设5个按钮,点了哪个按钮,这个按钮就变红色,再点别的按钮,这个按钮恢复颜色,点击的按钮变红色。

<body>

   <button>按钮1</button>

  <button>按钮2</button>

  <button>按钮3</button>

  <button>按钮4</button>

  <script>

     var btns=document.getElementsByTagName('button');

     for(var i=0;i<btns.length;i++){

       btns[i].οnclick=function(){

        //先把所有按钮颜色去掉,再将当前点击的这个按钮颜色置为红色

        for(var j=0;j<btns.length;j++)

           btns[i].style.backgroundColor='';

         this.style.backgroundColor='red';

       }

   </scrip>

</body>

案例:为浏览器换皮肤

body{

   background:url(images/1.png) no-repeat center top;

}

<body>

   <ul class="browser">

       <li><img src="images/1.jpg"></li>

       <li><img src="images/2.jpg"></li>

       <li><img src="images/3.jpg"></li>

    </ul>

    <script>

       var imags=document.querySelector('.browser').querySelectorAll('img');

      for(var i=0;i<images.length;i++){

         images[i].οnclick=function(){

         document.body.style.backgroundImage='url('+this.src+')';

      }

     </script>

</body>

 

案例:表格隔行变色,让鼠标经过某一行,那一行就变色。

(鼠标经过onmouseover,鼠标离开onmouseout)

思路:让鼠标经过tr行,当前的行变背景颜色,鼠标离开,去掉当前的背景颜色

           thead里不需要变色,我们需要的是tbody的行变色

.bg{

     background-color:blue;

   }

<body>

     <table>

         <thead>...

         <thead>

        <tbody>

              <tr>

                <td>003526</td>

                <td>农银金穗3个月定期开房债券</td>

                <td>1.075</td>

              </tr>

          </tbody>

         </table>

          <script>

              var trs=document.querySelector('tbody').querySelectorAll('tr');

              for(var i=0;i<trs.length;i++){

                     trs[i].οnmοuseοver=function(){

                          this.className='bg';

                      }

                    trs[i].οnmοuseοut=function(){

                        this.className='';

                     }

             }

          </script>

</body>

案例:表单的全选和取消

1.全选和取消全选:让下面所有的复选框的checked属性(选中状态)跟随全选按钮。

2.下面所有复选框选中后,全选按钮也选中,有一个没选择,全选不选中

<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>

                </tbody>

           </table>

         </div>

        <script>

              var j_cbAll=document.getElementById('j_cbAll');

              var j_tbs=document.getElementById('j_jb').getElementByTagName('input');

              j_cbAll.οnclick=function(){

                  for(var i=0;i<j_tbs.length;i++){

                     j_tbs[i].checked=this.checked;

                   }

            }

           for(var i=0;i<j_tbs.length;i++){

                 j_tbs[i].οnclick=function(){

                      var flag=true;//控制全选按钮是否选中

                    for(var j=0;j<j_tbs.length;j++){

                         if(!j_tbs[j].checked){

                             flag=false;

                          }

                     }

                   j_cbAll.checked=flag;

              }

          }       

       </script>

</body>

获取属性的值

1.element.属性【获取的是内置属性值(即元素本身自带的属性)】

2.element.getAttribute('属性');【主要获得自定义属性(程序员自己定义的属性)】

设置属性值

1.element.属性='值';【设置内置属性的值】

2.element.setAttribute('属性','值');【主要针对自定义属性】

案例:tab栏切换(★)

比如点了商品介绍,只能显示商品介绍模块内容,不能显示其他内容,隐藏掉.

上面的选项卡,点击了一个,当前这个底色红色,其余不变。

给所有小li添加自定义属性,属性值从0开始编号,让模块与选项卡一一对应。

current{

    background-color:red;

 }

.item{

   display:none;

 }

<body>

      <div class="tab">

          <div class="tab_list">

           <ul>//上面长方形盒子

               <li class="current>商品介绍</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>

     </div>

     <script>

       var lists=document.querySelector('.tab_list').querySelectorAll('li');

      var items=document.querySelectorAll('.item');

       for(var i=0;i<lists.length;i++){

        lists[i].setAttribute('index',i);//设置编号

         lists[i].οnclick=function(){

        //上面的选项卡模块

           for(var j=0;j<lists.length;j++)

              lists[i].className='';

           this.className='current';

          //下面的显示内容模块

          var index=this.getAttribute('index');

          for(var k=0;j<items.length;i++)

               items[k].style.display='none';

          items[index].style.display='block';

        }

   </script>

</body>

H5新增自定义属性

自定义属性的目的:为了保存并使用数据,有些数据可以保存到页面中不必保存到数据库中。

1.设置自定义属性

H5规定自定义属性:date-开头作为属性名并赋值

比如:<div date-index="1">或element.setAttribute('date-index',1);

2.获取自定义属性

兼容性获取:element.getAttribute('date-属性名');

H5新增element.dataset.属性名或者element.dateset['属性名'] (ie11才支持)

【dateset是一个集合,里面存放了所有以date开头的自定义属性,注意驼峰命名】

<div date-list-name="andy">

 div.dateset['listName'];

节点操作

目的:获取元素

1.利用DOM提供的方法获取元素

document.getElementById()

document.getElementByTagName()

document.querySelector()等

缺点:繁琐、逻辑性不强

2.利用节点层级关系获取元素

利用父子兄的关系获取元素。

优点:逻辑性强

缺点:兼容性稍差

 【网页中所有内容都是节点,HTML DOM树中的所有节点都可以通过js进行访问,所有HTML节点都能被修改,创建或删除】

【一般情况下,节点至少有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)三个基本属性】

【元素节点的nodeType=1,属性节点的nodeType=2,文本节点的nodeType=3(包含文字、空格、换行)】

实际开发中,主要操作元素节点。

1.父级节点

node.parentNode(得到的是离元素最近的父级节点,找不到就返回null)

2.子节点

(1)parentNode.childNodes(标准)(它的所有子节点包括元素节点和文本节点——换行 空格等,可以通过nodeType判断是否是元素节点)

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

for(var i=0;i<ul.childNodes.length;i++){

     if(ul.childNodes[i].nodeType==1)

         console.log(ul.childNodes[i]);

  }

缺点:如果想只获得元素节点,还需要专门处理,一般不用这个方法。

(2)parentNode.children(非标准)(获得所有子元素节点,常用)

(3)parentNode.firstChild(获得第一个子节点,不管是文本节点还是元素节点)

         parentNode.lastChild(获得最后一个子节点)

(4)parentNode.firstElementChild(获得第一个子元素)

         parentNode.lastElementChild(获得最后一个子元素),这两个方法有兼容性问题,ie9以上

        解决方法:

       用(2)var childs=ol.children;

                    childs[0],childs[childs.length-1]

案例:下拉菜单

鼠标经过li,ul显示,离开ul隐藏。

<body>

    <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>

   </ul>

   <script>

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

        var lists=nav.children;//获取的是li

       for(var i=0;i<lists.length;i++){

          lists[i].οnmοuseοver=function(){

               this.children[1].style.display='block';//选的li的第1个孩子(从0开始)是ul

           }

           lists[i].οnmοuseοut=function(){

              this.children[1].style.display='none';

          }

       }

   </script>

</body>

3.兄弟节点

(1)node.nextSibling(得到当前元素的下一个兄弟节点,包含文本节点)

         node.previousSibling(得到上一个)

(2)node.nextElementSibling(得到当前元素的下一个兄弟元素节点)

         node.previousElementSibling,这两个方法有兼容性问题,ie9以上支持

解决办法:封装一个兼容性函数

  function getNextElementSibling(element){

     var el=element;

     while(el==el.nexSibling){

        if(el.nodeType==1)

           return el;

     }

     return null;

  }

 

1.创建节点

document.createElement('tagName');//动态创建元素节点

2.添加节点

node.appendChild(child)(将一个节点添加到指定父节点的列表末尾)

node.insertBefore(child,指定元素)   (将一个节点添加到父节点的指定子节点前面)

=》

想给页面添加一个新的元素:1.创建元素 2.添加元素

案例:发布评论

思路:点击发表以后,动态创建一个li,添加到ul里面。

创建li的同时,把文本域里面的值通过li.innerHTML赋值给li

<body>

    <textarea name="" id="">123</textarea>

    <button>发布</button>

       <ul>

       </ul>

     <script>

        var btn=document.querySelector('button');

        var text=document.querySelector('textarea');

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

        btn.οnclick=function(){

             if(text.value==''){

               alert('请输入内容');

                return false;

             }else{

              var li=document.createElement('li');

               li.innerHTML=text.value;

               ul.insertBefore(li,ul.children[0]);

             }

      </script>

</body>

3.删除节点

node.removeChild(child)【删除父节点的某个子节点,返回删除的节点】

4.复制节点

node.cloneNode()【返回调用该方法节点的一个副本】

注意:如果括号参数为空或false,就是浅拷贝,只克隆复制节点本身,不克隆里面的子节点。

node.cloneNode(true):就是深拷贝,复制标签里的内容

 

事件

1.注册事件(绑定事件)

给元素添加事件,称为注册事件或绑定事件;

注册事件有2种方式:传统方式和方法监听注册方式

传统注册事件:on开头的,onclick等;

特点:注册事件的唯一性。同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面的注册处理函数

 

方法监听注册方式

addEventListener(type,listener,useCapture),IE9前不支持

type:事件类型字符串,比如click

listener:事件处理函数,事件发生时,会调用这个监听函数

特点:同一元素同一事件可以注册多个监听器,按注册顺序依次执行

 

attachEvent(eventNNameWidthOn,callback);IE9前支持的

第一个参数:事件类型字符串,要带on

第二个参数:事件处理函数,当目标触发事件时回调函数被调用

 

2.删除事件(解绑事件)

1.传统

eventTarget.οnclick=null;

2.方法监听注册方式

eventTarget.removeEventListener(type,listener,useCapture)

eventTarget.detachEvent(eventNameWithOn,callback)

DOM事件流

事件流描述的是从页面中接收事件的顺序。

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是事件流。

DOM事件流分为3个阶段:

1.捕获阶段(从上往下,从大到小)

2.当前目标阶段

3.冒泡阶段(从小到大或从里到外)

事件冒泡:IE最早提出,事件开始时由具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程

注意:JS代码只能执行捕获或者冒泡其中的一个阶段

          onclick和attachEvent只能得到冒泡阶段

         addEventListener(type,listener,useCapture):第三个参数是true---在事件捕获阶段调用事件处理程序

                                                                                                    false---在事件冒泡阶段调用事件处理程序

事件对象

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

div.οnclick=function(event){

}

1.这里的event就是一个事件对象,写到我们监听函数小括号里,当形参来看

2.事件对象只有有了事件才会存在,它是系统自动创建的,不需要我们传递参数

3.事件对象是我们事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击里就包含了鼠标的相关信息,鼠标坐标;

4.这个事件对象我们可以自己命名

5.事件对象也有兼容性问题,ie6 7 8通过window.event

事件对象的 常见属性和方法

事件对象属性方法说明
e.target返回触发事件的对象,标准
e.srcElement返回触发事件的对象,非标准,ie6-8用
e.type返回事件的类型,比如click
e.cancleBubble阻止冒泡,非标准
e.returnValue阻止默认事件,非标准
e.preventDefault()阻止默认事件,标准
e.stopPropagation()阻止冒泡,标准

 

阻止事件冒泡

冒泡有一定坏处也有一定好处

比如:我点击子盒子,我只想让子盒子传播点击事件,不想让父盒子也传播到

标准写法:

利用事件对象里面的stopPropagation()方法

非标准:IE6-8

利用事件对象cancelBubble属性,让它=true

兼容性写法:

if(e&&e.stopPropagation){

   e.stopPropagation();

}else{

   window.event.cancelBubble=true;

}

事件委托

是事件冒泡的应用,是带来的好处

事件委托的原理:

不是给每个子节点单独设置事件监听器,而是给父节点设置事件监听器,然后利用事件冒泡影响设置每个子节点

事件委托的作用:

只操作一次dom,提高程序性能

常用鼠标事件

1.contextmenu禁用右键菜单

 document.addEventListener('contextmenu',function(e){

})

2.selectstart禁用选中文字

 document.addEventListener('selectstart',function(e){

})

鼠标事件对象MouseEvent

鼠标事件对象说明
e.clientX返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY返回鼠标相对于浏览器可视区的Y坐标
e.pageX返回鼠标相对于文档页面的X坐标,ie9支持
e.pageY返回鼠标相对于文档页面的X坐标,ie9支持
e.screenX返回鼠标相对于电脑屏幕的X坐标
e.screenY返回鼠标相对于电脑屏幕的X坐标

 

常用键盘事件

键盘事件触发条件
onkeyup某个键盘被松开时触发
onkeydown某个键盘按键被按下时触发
onkeypress某个键盘按键被按下时触发,但不识别功能键,比如ctrl shift 箭头等 

BOM浏览器对象模型

BOM就是浏览器对象模型,提供独立于内容而与浏览器窗口进行交互的对象,核心对象是window

window对象的常见事件

window.onload,页面加载事件,当文档内容完全加载完成会触发该事件

或者window.addEventListener('load',function(){});

注意:有了这个事件,就可以把JS代码放到页面元素上面;window.onload是传统注册事件,只能写一次,若有多个以最后一个window.onload为准。addEventListener()没有限制

 

document.addEventListener('DOMContentLoaded',function(){}):当DOM加载完成时触发事件,不包括样式表、图片、flash等

IE9才支持,如果页面图片很多,从用户访问到onload需要很长时间,交互效果不能实现,影响用户体验。这时用DOMContentLoaded事件比较合适。

 

window.onresize调整窗口大小事件,只要浏览器窗口大小发生变化就会触发

或window.addEventListener('resize',function(){})

 

两种定时器

1.setTimeout()

语法:window.setTimeout(调用函数,延迟时间(单位ms))

注意:window可以省略,延迟时间省略默认0

停止计时器:window.clearTineout(timeoutId)

2.setInterval()——重复调用一个函数,每隔这个时间就调用一次回调函数

语法:window.setInterval(调用函数,间隔的毫秒数)

注意:每隔多少毫秒自动调用这个函数,且重复调用的是一个函数

停止计时器:window.clearInterval(interbalId)

 

JS执行机制

HTML5提出用Web Worker允许建立多个线程,于是JS出现了同步和异步

同步就是需要等待结果返回才能继续执行

异步是不需要等待结果返回就能继续执行

本质区别:各个流程的执行顺序不同

比如:

console.log(1);

setTimeout(function(){

 console.log(3);

},0)

console.log(2);

最后执行顺序是1  2  3

 

JS为了防止任务有等待时间长的问题,将任务分为两类:同步任务和异步任务

同步任务都在主线程上执行,形成一个执行栈。【setTimeout是同步任务,但是参数fn是回调函数,属于异步任务】

异步任务是通过回调函数实现的。一般异步任务有三种类型:1.普通事件,click、resize等;2.资源加载,如load、error等 ;3.定时器,包括setTimeout和setInterval等

 

JS执行机制:

1.先执行栈中的同步任务

2.遇到异步任务(回调函数),就把它放到任务队列中

3.一旦栈中所有同步任务执行完成,系统就会按次序读取任务队列中的异步任务,所以被读取的异步任务结束等待状态,进入执行栈,开始执行。

 

注意:document.οnclick=function(){}  ---如果不点击,是不会出现在任务队列中的

          setTimeout(fn,2000)-----2秒到了,才会出现在任务队列中

事件循环机制:

同步任务会放到执行栈中执行,异步任务(普通事件click、资源加载load、定时器)会被放到任务队列中执行。JS会先执行 执行栈中的同步任务,遇到异步任务就把它放到任务队列中,栈中所有同步任务执行完成,就会依次读取任务队列中的异步任务,把它放到执行栈执行,执行完后还会去任务队列中看有没有异步任务,有就再放入执行栈执行,如此反复就叫做事件循环机制。

 

location对象

window对象提供location属性,用来获取或设置窗体的url,并且可以用于解析url。因为这个属性返回的是一个对象,所以这个属性也叫location对象

 

location对象的属性

location对象属性返回值
location.href获取或设置整个URL
location.host返回主机(域名)www.baidu.com
location.port返回端口号,未写就返回空字符串
location.pathname返回路径
location.search返回参数
location.hash返回片段,#后面常见于链接锚点

 

案例:有个登录页面,有个提交表单,action提交到index.html页面。提交后跳转页面,并将参数加入url

第二个页面,可以用第一个页面的参数,实现一个数据不同页面之间的传递效果,利用location.search提取参数,

第二个页面只需要?后面的参数,用substr()从?截取到末尾,再利用split('=')分割key 、value。

var params=location.search.substr(1);

var arr=params.split('=');

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

div.innerHTML=arr[1];

 

location对象的方法:

location对象方法返回值
location.assign()跟href一样,可以跳转页面(也叫重定向页面)
location.replace()替换当前页面,因为不记录历史,不能后退页面
location.reload()重新加载页面,相当于F5刷新,若参数true,就强制刷新

 

navigator对象

navigator对象包含有关浏览器的信息,有很多属性,常用userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。

history对象

与浏览器历史记录进行交互,该对象包含用户(在浏览器窗口中)访问过的url。

history对象方法作用
back()可以后退
forward()前进功能
go(参数)参数1,前进一个页面,-1,后退一个页面

 

 

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值