【Web前端】

JavaScript(WebAPI)

WebAPI背景知识

什么是WebAPI

JS可以分成三个部分

  • ECMAScript:基础语法部分
  • DOM(Document Object Model):操作页面结构
  • BOM(Broswer Object Model):操作浏览器
    WebAPI就包含了DOM+BOM
    这个是W3C组织规定的(和制定ECMAScript标准的大佬们不是一伙人)

什么是API

API是一个更广义的概念,而WebAPI是一个更具体的概念,特指DOM+BOM
所谓的API本质上就是一些现成的函数/对象,让程序员拿来就用,方便开发。

相当于一个工具箱,只不过程序员用的工具箱数目繁多,功能复杂。

DOM基本概念

什么是DOM

W3C标准给我们提供了一系列的函数,让我们可以操作:

  • 网页内容
  • 网页结构
  • 网页样式

DOM树

一个页面的结构是一个树形结构,称为DOM树

树形结构在数据结构阶段会介绍,既可以简单理解成类似于“家谱”这种结构

页面结构形如:
【Web前端】_第1张图片

重要概念:

  • 文档:一个页面就是一个文档,使用document表示
  • 元素:页面中所有的标签都可以称为元素,使用element表示
  • 节点:网页中所有的内容都可以称为节点(标签节点、注释节点、文本节点、属性节点等)。使用node表示

这些文档等概念在JS代码中就对应一个个的对象, 所以才叫做“文档对象模型”。

获取元素


这部分工作类似于CSS选择器的功能

querySelector
let element = document.querySelector(selectors);
  • selector包含一个或者多个要匹配的选择亲戚的DOM字符串。该字符串必须是有效的,CSS选择器字符串;如果不是,则印发SYN_ERR异常
  • 表示文档中与指定的一组CSS选择器匹配的第一个元素的html元素Element对象
  • 如果您需要与指定选择器匹配的所有元素的列表,则应该使用querySelectorAll()
  • 可以在任何元素上调用,不仅仅是document。调用这个方法的元素将作为本次查找的根元素。

选择器

  • 类选择器(.className)

  • ID选择器(.ID)

  • 全局选择器(*)

  • 关系选择器
    子代关系选择器(article > p)
    邻接兄弟(p+img)
    通用兄弟(p~img)
    符合关系选择器(ul > li[class=“a”])

  • 伪类选择器(:hover :acitive)

  • 属性选择器
    【Web前端】_第2张图片

具体使用可以参照下面代码:

【Web前端】_第3张图片

querySelectorAll

使用querySelectorAll用法和上面类似

<div class="box">abcdiv>
<div id="id">defdiv>
<script>
	 let elems = document.querySelectorAll('div');
	 console.log(elems)
script>

事件初始

基本概念

JS要构建动态页面,就需要感知到用户的行为
用户对于页面的一些操作(点击、选择、修改)操作都会在浏览器中产生一个个事件,被JS获取到,从而进行更复杂的交互操作

浏览器就是一个哨兵,在侦查敌情·(用户行为),一旦用户有反应(触发具体动作),哨兵就会点燃烽火 台的狼烟(时间),后方就可以根据狼烟来决定下一步的对敌策略。

事件三要素

HTML DOM事件

  • 事件源:哪个元素触发的
  • 事件类型:是点击、选中还是修改?
  • 时间处理程序:进一步如何处理,往往是一个回调函数

onclick事件

    <button id="btn">点我一下div>

    <script>
       let btn = document.querySelector('#btn')
       btn.onclick=function(){
        alert("hello world");
       }
    script>
  • btn按钮就是事件源
  • 点击就是事件类型
  • function这个匿名函数就是事件处理程序
  • 其中btn.onclick = function()这个操作就称为注册事件/绑定事件
    注意:这个匿名函数相当于一个回调函数,这个函数不需要程序员主动来调用,而是交给浏览器,由浏览器自动在合适的时机(触发点击操作时)进行调用。

onkeydown事件

    <input type="text">

    <script>
        //事件源
       let input = document.querySelector('input')
       input.onkeydown=function(event){
        console.log('键盘正在按下');
        let a = event.keyCode;
        let b = String.fromCharCode(a);
        console.log(b)

       }
    script>

可以看到运行结果不能区分大小写,所以我们的onkeypress就是为了解决这个问题
【Web前端】_第4张图片

onkeypress事件

    <input type="text">

    <script>
        //事件源
       let input = document.querySelector('input')
       input.onkeypress=function(event){
        console.log('键盘正在按下');
        let a = event.keyCode;
        let b = String.fromCharCode(a);
        console.log(b)

       }
    script>

【Web前端】_第5张图片
onkeyup事件

    <input type="text" onkeyup="myOnKeyUp()">

    <script>
        //事件源
       let input = document.querySelector('input')
       input.onkeypress=function(event){
        console.log('键盘正在按下');
        let a = event.keyCode;
        let b = String.fromCharCode(a);
        console.log(b)
       }
       function myOnKeyUp(){
            console.log('按键被抬起')
        }
    </script>

【Web前端】_第6张图片

onkeydown

    <input type="text">

    <script>
        //事件源
       let input = document.querySelector('input')
       input.onkeydown=function(event){
	        if(event.shiftKey)
	        {
	            console.log('shift按键被按下')
	        }
	        if(event.altKey)
	        {
	            console.log('alt按键被按下')
	        }
       }
    </script>
    

【Web前端】_第7张图片

获取/修改表单元素属性

表单(主要是指input标签)的以下属性都可以通过DOM来修改

  • value:input的值
  • disable:禁用·
  • checked:复选框会使用
  • selected:下拉框会使用
  • type:input的类型(文本、密码、按钮、文件等)
<input class="btn" type="button"  value="播放" onclick="onClick()">
<script>
    let btn = document.querySelector('.btn')
    //判断按钮的值为播放,就变成暂停;暂停就变成播放
    function onClick()
    {
        if(btn.value == "播放"){
            btn.value = "暂停"
        }
        else{
            btn.value = "播放"
        }
    }
</script>

点击计数

    <input class='input' type="text" value="0">
    <input class='add' type="button" value="+1" onclick="ADD()">
    <input class='sub' type="button" value="-1" onclick="SUB()">

</body>
<script>
    let btn = document.querySelector('.input')
    let input = document.querySelector('.input')
    //判断按钮的值为播放,就变成暂停;暂停就变成播放
    function ADD(){
        let input=document.querySelector(".input")
        input.value=parseInt(input.value)+1
    }
    function SUB(){
        let input=document.querySelector(".input")
        input.value=parseInt(input.value)-1
    }

复选框的应用

    <input class='all' type="checkbox" onclick='selectAll()'> 选中全部<br>
    <input class='select' type="checkbox">选项1<br>
    <input class='select' type="checkbox">选项2<br>
    <input class='select' type="checkbox">选项3<br>
    <input class='select' type="checkbox">选项4<br>


</body>
<script>
    // let btn = document.querySelector('.input')
    // let input = document.querySelector('.input')
    // //判断按钮的值为播放,就变成暂停;暂停就变成播放
    // function ADD(){
    //     let input=document.querySelector(".input")
    //     input.value=parseInt(input.value)+1
    // }
    // function SUB(){
    //     let input=document.querySelector(".input")
    //     input.value=parseInt(input.value)-1
    // }
    let all=document.querySelector('.all')
    let select=document.querySelectorAll('.select')
    function selectAll(){
        for(i=0;i<select.length;i++)
        {
            select[i].checked = all.checked;
        }
    }
    for(i=0;i<select.length;i++)
    {
        select[i].onclick=function(){
            all.checked=isSelectAll(select)
        }
    }
    function isSelectAll(select){
        for(i=0;i<select.length;i++){
            if(select[i].checked==false){
                return false
            }
        }
        return true
    }
</script>

获取/修改样式属性

CSS中指定元素的属性,都可以通过JS来修改

行内样式操作

element.style.[属性名]=[属性值];
element.style.cssText=[属性名+属性值]

“行内样式”,通过style直接在标签上制定的样式,优先级很高
适用与改的样式少的情况

类名样式操作

element.className=[css 类名]

点击文字就放大字体
这种方式修改只影响到特定样式,其他内联样式的值不变

    <div style="font-size: 10px;">哈哈哈div>
body>
<script>
    let element=document.querySelector('div');
    element.onclick=function(){
        let size=parseInt(element.style.fontSize); 
        size+=10;
        // element.style.fontSize =size +'px';
        element.style.cssText="font-size:"+size+'px'
    }
script>

黑夜模式&&白天模式切换

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <style>
        .light{
            background-color: white;
            color:black;
            width:100%;
            height:100%;
        }
        .dark{
            background-color: black;
            color:white;
            width:100%;
            height:100%;
        }
        *{
            width:100%;
            height:100%;
        }
    style>
head>
<body>
    <div class="light" onclick="changeStyle()">
        这是一段话<br>
        这是一段话<br>
        这是一段话<br>
        这是一段话<br>
        这是一段话<br>
        这是一段话<br>
        这是一段话<br>
        这是一段话<br>
    div>
body>
<script>
    function changeStyle(){
        let element=document.querySelector('div')
        if(element.className=='light'){
            element.className="dark"
        }
        else{
            element.className="light";
        }
    }
script>
html>

操作节点

新增节点

分成两个步骤

  1. 创建元素节点
  2. 把元素节点插入到dom树中
1.创建元素节点

使用createElement方法创建一个元素,option参数暂不关注

let element=document.createElement(tagName[,option]);
2.插入节点到dom树中

1)使用appendChild将节点插入到指定节点的最后一个孩子之后

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <div>
        <p>这是一个p标签p>
        <p>这是一个p标签p>
        <p>这是一个p标签p>
        <p>这是一个p标签p>
    div>
body>
<script>
    let element=document.createElement("h3")
    element.innerHTML="这是我们创建的一个新节点"
    let div=document.querySelector("div")
    div.appendChild(element)
script>
html>

运行结果:
【Web前端】_第8张图片

2)使用InsertBefore将节点插入到指定节点之前

let insertNode=parentNode.insertBefore(newnode,referenceNode);
  • insertNode 被插入节点(newNode)
  • parentNode 被插入节点的父节点
  • newNode 用于被插入的节点
  • referenceNode newNode将要插在这个节点之前
    如果referenceNode为null则newNode将被插入到子节点的末尾
    注意1:如果针对一个节点插入两次,则只有最后一次生效(相当于把元素移动了)
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <div>
        <p class="p1">这是一个p标签p>
        <p class="p2">这是一个p标签p>
        <p class="p3">这是一个p标签p>
        <p class="p4">这是一个p标签p>
    div>
body>
<script>
    let element=document.createElement("h3")
    element.innerHTML="这是我们创建的一个新节点"
    let div=document.querySelector("div")
    div.appendChild(element)

    let newNode=document.createElement('h3')
    newNode.innerHTML="这是我们创建的另一个新节点"
    div.insertBefore(newNode,document.querySelector('.p1'))
    div.insertBefore(newNode,document.querySelector('.p2'))
    div.insertBefore(newNode,document.querySelector('.p3'))
    div.insertBefore(newNode,document.querySelector('.p4'))
script>
html>

【Web前端】_第9张图片
注意2:一旦一个节点插入完毕,在针对刚刚的节点对象进行修改,能够同步影响到DOM树中的内容

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <div>
        <p class="p1">这是一个p标签p>
        <p class="p2">这是一个p标签p>
        <p class="p3">这是一个p标签p>
        <p class="p4">这是一个p标签p>
    div>
body>
<script>
    let element=document.createElement("h3")
    element.innerHTML="这是我们创建的一个新节点"
    let div=document.querySelector("div")
    div.appendChild(element)

    let newNode=document.createElement('h3')
    newNode.innerHTML="这是我们创建的另一个新节点"
    div.insertBefore(newNode,document.querySelector('.p1'))
    div.insertBefore(newNode,document.querySelector('.p2'))
    div.insertBefore(newNode,document.querySelector('.p3'))
    div.insertBefore(newNode,document.querySelector('.p4'))

    // element.innerHTML="我在修改这个标签"
script>
html>

【Web前端】_第10张图片
任务清单页面

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <style>
        *{
            margin:0px;
            padding:0px;
            box-sizing: border-box;

        }
        .nav{
            width:800px;
            height:100px;
            margin:0 auto;
            display:flex;
            align-items: center;
        }
        .nav input{
            width:600px;
            height:60px;
            border-radius: 5px 0 0 5px;


        }
        .nav button{
            width:200px;
            height:60px;
            background-color: orange;
            color:white;
            font-size:20px;
            border:orange;
            border-radius: 0 5px 5px 0;
        }
        .nav button:active{
            background-color: grey;
        }
        .container{
            width:800px;
            display: flex;
            margin:0px auto;

        }
        h3{
            background-color: grey;
            color:white;
            text-align: center;
            width:400px;
            height:60px;
            padding-top:15px;
        }
        .row{
            width:400px;
            display:flex;
            align-items: center;
        }
        .row span{
            width:200px;
            font-size:20px;
            margin-left:5px;
        }
        .row button{
            width:50px;
            height:40px;
            font-size:20px;
            margin-top:10px;
        }
        .done{
            width:50%;
            height:100%;
        }
        span{
            width:100px;
        }
    style>
head>
<body>
    <div class="nav">
        <input type="text"><button onclick="newJob()">新建任务button>
    div>
    <div class="container">
        <div class="todo">
            <h3>未完成h3>
            <div class="row">
                <input type="checkbox" name="" i="">
                <span>吃饭span><button>删除button>
            div>
        div>
        <div class="done">
            <h3>已完成h3>
        div>
    div>
body>
<script>
    function newJob(){
        //获取数据
        let input=document.querySelector('.nav input')
        let input_info=input.value
        if(input_info==''){
            return
        }

        //获取todo
        let todo=document.querySelector('.todo')
        //创建一个div
        let div=document.createElement('div')
        //创建一个checkbox
        let checkbox=document.createElement('input')
        checkbox.type="checkbox"

        //创建一个span(文本内容是刚才输入的信息)
        let span=document.createElement('span')
        span.innerHTML=input_info
        //创建一个button
        let button=document.createElement('button')

        button.innerHTML="删除"
        div.appendChild(checkbox)
        div.appendChild(span)
        div.appendChild(button)
        //更新样式
        div.className='row'
        //将div插入到todo这个div中
        todo.appendChild(div)

        let deleteButtons=document.querySelectorAll('.row button')
        for(i=0;i<deleteButtons.length;i++)
        {
            deleteButtons[i].onclick=function(){
                let parent=this.parentNode;
                let grandParent=parent.parentNode;
                grandParent.removeChild(parent);

            }
        }
        let checkbox_buttons=document.querySelectorAll('.row input')
        //绑定点击事件
        for(i=0;i<checkbox_buttons.length;i++)
        {
            let row=document.querySelector('.row')
            let done;
            checkbox_buttons[i].onclick=function(){
                if(this.checked==true){
                    done=document.querySelector('.done')
                    done.appendChild(row)


                }else{
                    done=document.querySelector('.todo')
                }
                // console.log(typeof(row))
            }
        }
    }
script>
html>

效果:【Web前端】_第11张图片

你可能感兴趣的:(前端)