WEB第七天

WEB第七天

一、 DOM事件监听

1.1 添加事件监听

<p>
    <span>点我试试</span>
</p>
let p_e = document.getElementsByTagName('p')[0]
let span_e = p_e.firstElementChild  // 第一个子标签元素

let click_span = (ev)=>console.warn('span 被点击');
span_e.addEventListener('click', click_span);

(ev)=>console.warn(‘span 被点击’) 是ES6中匿名函数的写法, 相当于:

function (ev) {
    console.warn('span 被点击') 
}

如果给span父标签也增加点击事件监听 ,则可以先捕获子标签的事件,然后再处理子标签的事件。默认情况下,是冒泡方式,即先处理子标签的事件,再处理父标签的事件。

p_e.addEventListener('click', function (ev) {
    console.error('p标签被点击');
}, false);

addEventListener()第三个参数的boolean表示是否优先捕获事件。默认为false即冒泡。

1.2 删除事件监听

span_e.removeEventListener('click', click_span);

也可以在适当的事件中,去除事件监听。

p_e.addEventListener('click', function (ev) {
    console.error('p标签被点击');

    // 'click' 事件类型, click_span监听函数的对象
    this.firstElementChild.removeEventListener('click', click_span);
});

注意:如果事件监听的对象是匿名函数,是无法的删除的。

1.3 自定义选项卡

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">
    <title>自定义选项卡</title>
    <link rel="stylesheet" href="css/tab.css">
</head>
<body>
    <div id="tab">
        <ul id="tab-head">
            <li class="active">主页</li>
            <li >精品推荐</li>
            <li>818活动</li>
        </ul>
        <ul id="tab-body">
            <li>
                <div style="height: 100%;background-color:red;color:white">
                    <h1>主页</h1>
                </div>
            </li>
            <li class="hidden">
                <h3>精品推荐</h3>
                <span>&gt; 123</span> <br>
                <span>&gt; 345</span><br>
                <span>&gt; 1111</span><br>
                <span>&gt; 12333</span><br>
            </li>
            <li class="hidden">818活动</li>
        </ul>
    </div>

    <script src="js/tab.js"></script>
</body>
</html>

css样式文件:

ul,li{
    list-style: none;
    margin: 0;
    padding: 0;
}

#tab-head li{
    float: left;
}

ul:after{
    content: "";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
}
#tab{
    width: 600px;
    height: 400px;
    background-color: skyblue;
    padding: 0px;
}
#tab-head{
    height: 40px;
    background-color: yellowgreen;
}
#tab-head li{
    padding: 10px;
}

#tab-head .active{
    background-color: greenyellow;
}
#tab-body{
    margin: 0px;
}
#tab-body h1{
    margin: 0px;
}

#tab-body li{
    width: 100%;
    height: 360px;
}

#tab-body .hidden{
    display: none;
}

js文件

function $(element_id) {
    return document.getElementById(element_id)
}

window.onload = function () {
    // 当文档加载就绪之后,执行的函数
    let head_tabs = $('tab-head').children;
    let body_tabs = $('tab-body').children;

    let currentIndex = 0;
    for(i in head_tabs){
        // 获取头的每个选项卡的标题
        let hTab = head_tabs[i];
        hTab.index = i  // 设置选项卡的索引
        hTab.onclick = function (ev) {
            // this 指向的是当前事件来源(点击的标签)
            if(this.index !== currentIndex){
                console.log(this.index)
                head_tabs[currentIndex].removeAttribute('class');
                this.setAttribute('class', 'active')


                //显示对应的内容
                body_tabs[currentIndex].setAttribute('class', 'hidden');
                body_tabs[this.index].removeAttribute('class');

                currentIndex = this.index
            }
        }
    }
};

提示说明:

  • window.onload 是当空前窗口的监听函数,表示当前网页文档加载完成(文档就绪)后调用的函数。

  • 获取一个父标签元素下的所有子元素节点: $(‘tab-head’). children 返回所有#tab-head的标签的所有子元素标签, 即所有li标签。

  • 在标签的事件函数中,this表示事件发生在什么标签上,即事件源。this即表示点击某一标签的元素对象。

  • 可以动态地添加元素对象的属性, 有两种方式添加:

    • 对象.属性= 属性值
    • 对象[属性] = 属性值
  • 标签事件类型: mouseover(), click(), focus(), blur()

二、面向对象

2.1 创建对象

  1. 使用Object来创建

    let stu = new Object();
    stu.name = 'disen';
    stu.age = 20;
    
  2. 使用 {} 创建

    let stu2 = {
        name: 'jack',
        age: 20
    }
    // 动态地添加属性
    stu2.city = '西安';
    stu2['phone'] = '110';
    
  3. 使用构造函数

    function Student(id, name, city){
        // 使用this关键字,初始化对象的属性
        // this表示通过Student()构造函数创建的对象
        this.id = id;
        this.name = name;
        this.city = city;
    }
    
    let s1 = new Student(1, 'dula', '北京');
    // s1对象初始化时新增了id, name, city 三个属性
    s1.id // 1
    s1 // {id: 1, name: "dula", city: "北京"}
    

    默认情况下,对象和对象之间不共享属性和方法。如果像Python类的定义,让多个对象共享相同的属性或方法时,需要使用对象的元型属性。

2.2 对象的元型prototype

prototype是任何对象都具有的属性,表示类的方法或属性,让多个相同类的对象共享属性或方法。

给上面的构造函数 Student类,增加元型属性:

Student.prototype.say = function(){
     console.log(this.id, this.name, this.city)
}

接下来,创建两个对象,可以分别调用say()函数,显示 的结果是不一样的。

// 通过构造函数创建类的对象时,必须是使用new关键字
let s1 = new Student(1, 'disen', '西安');
let s2 = new Student(2, 'jack', '北海');

s1.say() // 1  disen 西安
s2.say() // 2  jack  北海

2.3 JSON对象与数组

JSON(JavaScript Object Notation - js对象的简述), 只描述对象的数据属性,即去除了对象的行为方法。json对象包含两种类型, 即是json对象 {}, json数组 [ ]。

2.3.1 JSON对象

普通json对象

let p1 = {
    id: 1,
    name: 'jack'
};

带有jsno数组的对象

let p2 = {
    id: 2,
    name: 'disen',
    loves: ['音乐','程序', '电影']
}

带有其它对象的对象

let p3 = {
    id: 3,
    name: 'lucy',
    father: {
    		 name: 'disen',
    		 age: 40,
    		 address: {
    		      name: '西安市高新六路',
    		      city: '陕西省西安市'
    		 }
    }
}
2.3.2 json数组对象
let cates = [
		{
		    title: '家电'
		    top: [
          {
            name: '热销',
            url: '/rx',
            icon: '/imgs/rx.png'
          },
          {
            name: '818活动',
            url: '/a818',
            icon: '/imgs/a818.png'
          },
        
        ]
		},{
		    title: '手机'
		    top: [
          {
            name: '热销',
            url: '/rx',
            icon: '/imgs/rx.png'
          },
          {
            name: '818活动',
            url: '/a818',
            icon: '/imgs/a818.png'
          },
        
        ]
		}
		
]

2.4 json对象的序列化与反序列化

json格式的数据,主要用于前后端接口交互的数据格式之一,如前端将json 对象的数据传给后端 ,则需要做以下几件事件:

  • 序列化, 将json对象序列化json格式的字符串,即将属性和属性值转成key:value, key使用字符串表示的。

    let p3_str = JSON.stringify(p3);
    typeof p3_str === 'string'  //true
    
  • 将请求头的Content-Type改为 application/json

如果后端请求成功后,响应的数据是json数据时(响应头中Content-Type参数值是 application/json),前端需要将json格式的字符串进行反序列化,之后以对象的属性方式来访问json数据。

let person = JSON.parse(p3_str);
person.id  // 3

2.5 综合案例-加载分类

创建本地的json数据文件, cate.json

{
  "total": 4,
  "data": [
    {
      "name": "手机",
      "url": "http://www.baidu.com/s?wd=手机"
    },
    {
      "name": "平板",
      "url": "http://www.baidu.com/s?wd=平板"
    },
    {
      "name": "智能手表",
      "url": "http://www.baidu.com/s?wd=智能手表"
    },
    {
      "name": "AI音箱",
      "url": "http://www.baidu.com/s?wd=AI音箱"
    }
  ]
}
  1. 加载商品类型

    fetch('cate.json')
        .then(response=>response.text())
        .then(result=>{
             // 解析
             console.log(result)
        })
    
  2. 解析商品类型的数据,并生成DOM标签

    声明创建li标签元素对象的函数

    function createCategory(name, url, element_name='li') {
          let element = document.createElement(element_name)
    
          let a = document.createElement('a')
          a.setAttribute('href', url)
          a.innerText = name
    
          element.appendChild(a)
          return element
    }
    

    html的内容, 显示分类的位置

    <ul id="cate">
    </ul>
    

    解析js代码

    fetch("cate.json")
      .then(respone=>respone.text())
      .then(result=>{
          // 将json格式的文本数据转成json对象
          let respData = JSON.parse(result);
          let data = respData.data; // Array []
    
          let ul_e = document.getElementById('cate')
          for(let i in data){
              let category = data[i] // Object {}
    
              ul_e.appendChild(createCategory(category.name, category.url))
          }
      });
    

三、正则的使用(Regular Expression)

3.1 正则的创建

  1. // 创建, 语法: /正则表达式/img

    img可以组合使用,分别使用也可以, i 忽略大小写,m多行, g 全局搜索

    let phone_regexp = /1[3-57-9]\d{9}/ig  
    
  2. RegExp类创建

    let name_min_len = RegExp('\\w{6,}', 'img')  // 转成 /\w{6,}/gim
    

3.2 正则的使用

  1. test()方法

    test()方法的返回结果是true或false, 一般在if条件中使用

    let phone = '1110'
    if(phone_regexp.test(phone)){
    		console.log('phone is ok!')
    }else{
    	  console.log('phone is error!')
    }
    

    如果正则表达式中,存在分组,可以通过 RegExp.$1…99 方式提取分组的内容。

    let format = 'yyyy-mm-dd';
    let year_regexp = /(y+)/ig
    if(year_regexp.test(format)){
        // format字符串存在y字符
        console.log(RegExp.$1) // 显示正则中第一个分组获取的字符串: yyyy
    }
    
  2. exec()方法

    exec()匹配正则中的数据, 分组中的匹配数据结果,通过RegExp.$1…99来提取。

  3. String相关的方法

    format.match(/\w+/)

    format.search( /\w{6}/ig )

    format.replace(regexp, ‘newstr’)

    format.split(regexp)

四、日期时间与定时器

4.1 日期时间类-Date

  1. 创建Date类对象,Date对象中包含年、月(0-11)、日、周、时、分、秒、毫秒

    <div id="currentDate"></div>
    <script>
        function showDate() {
            let date = new Date()
            let date_str = "yyyy-mm-dd HH:MM:SS"
            date_str =  date_str.replace(/y+/, date.getFullYear()) //四位 年
                                .replace(/m+/, date.getMonth()+1) // 月 0-11
                                .replace(/d+/, date.getDate())  // 日
                                .replace(/H+/, date.getHours()) // 小时
                                .replace(/M+/, date.getMinutes()) // 分钟
                                .replace(/S+/, date.getSeconds()) // 秒
    
            document.getElementById('currentDate').innerHTML=date_str
        }
    
        window.onload = function () {
            showDate()
        }
    </script>
    

    另外,获取当前时间的方式:Date.now()

  2. 使用日期时间格式的字符串生成Date对象

    new Date('2019-10-12')
    new Date('2019-10-12 17:24:30')
    new Date('2019/10/12 17:24:30')
    new Date('10 12 2019 17:24:30')  // 月 日 年 
    new Date('12,10 2019 17:24:30')  // 月,日 年 
    new Date('12/10 2019 17:24:30')  // 月/日 年 
    new Date('12/10/2019 17:24:30')  // 月/日/年 
    

4.2 扩展-自定义格式化Date

可以使用Date.prototype原型的方式设置格式化日期的函数,如 format

Date.prototype.format = function (format_str) {
        let o = {
            "(y+)": this.getFullYear(),
            '(m+)': this.getMonth() + 1,
            '(d+)': this.getDate(),
            '(H+)': this.getHours(),
            '(M+)': this.getMinutes(),
            '(S+)': this.getSeconds(),
            '(s+)': this.getMilliseconds()
        }

        for (key in o) {
            if (RegExp(key).test(format_str)) {
                if (key === '(y+)')
                    format_str = format_str.replace(RegExp.$1,
                            String(o[key]).substr(4 - RegExp.$1.length))
                else if(key == '(s+)')
                     format_str = format_str.replace(RegExp.$1,
                           String(o[key]).substr(0, RegExp.$1.length))
                else {
                    let key_len = RegExp.$1.length;
                    let val_len = String(o[key]).length;
                    format_str = format_str.replace(RegExp.$1,
                         key_len == 1 ? o[key] : ("00" + o[key]).substr(val_len))

                }

            }
        }

        return format_str;
  };

format函数必须返回格式之后的字符结果。

let date = new Date()
date_str = date.format('yyyy-mm-dd HH:MM:SS sss')  // 2019-08-06 18:07:10 998

4.3 setInterval()定时器

let id = setInterval(function(){}, interval_ms) 
clearInterval(id)
setInterval(function(){
		let date = new Date()
		date_str = date.format('yyyy-mm-dd HH:MM:SS sss') 
		document.getElementById('currentdate').innertHTML = date_str
}, 1000) 
var interId = 0;
  window.onload = function () {

      interId = setInterval(function () {
          let current_datetime = new Date()
          document.getElementById('currentDate').innerHTML = current_datetime.format('yyyy-mm-dd HH:MM:SS')
      }, 1000)
}

4.4 setTimeout()延迟器

五、Ajax异步请求

Ajax是JS异步请求的全称, 包含请求对象XMLHttpRequest、FormData及请求资源与数据解析等一系列操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值