• Java成王之路】EE初阶第二十一篇: 前端三剑客 JavaScript(WebAPI)


    目录

    WebAPI 背景知识

    什么是 WebAP

    什么是 API 

    API 参考文档 

    什么是 DOM 

    DOM 树

    页面结构形如:

    DOM 树结构形如 

    获取元素 

    基本用法 

    事件初识 

    事件三要素 

    操作元素 

    1.获取/修改元素内容

    获取元素属性

    修改元素属性 

    获取/修改表单元素属性 

    修改样式属性 

    操作节点 

    删除节点 

    结合上述操作写几个案例 

    猜数字

    表白墙

     


    WebAPI 背景知识

    什么是 WebAP

    前面学习的 JS 分成三个大的部分

    ECMAScript: 基础语法部分

    DOM API: 操作页面结构

    BOM API: 操作浏览器

    WebAPI 就包含了 DOM + BOM.

    什么是 API 

    API 是一个更广义的概念. 而 WebAPI 是一个更具体的概念, 特指 DOM+BOM 所谓的 API 本质上就是一些现成的函数/对象, 让程序猿拿来就用, 方便开发.相当于一个工具箱. 只不过程序猿用的工具箱数目繁多, 功能复杂

    API 参考文档 

    Web API 接口参考 | MDN (mozilla.org)

    什么是 DOM 

    DOM(Document Object Model)就叫文档对象模型.

    意思就是写的html是一个文档文件,同时html里面包含了很多标签,每个标签都可以视为是一个Object,里面有属性有方法就叫Object.

    DOM API 功能就是操作 DOM.

    也就是操作 HTML 页面中的各种元素(属性 + 方法)

    DOM 树

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

    页面结构形如:

    DOM 树结构形如 

    重要概念:

    文档: 一个页面就是一个 文档, 使用 document 表示.

    元素: 页面中所有的标签都称为 元素. 使用 element 表示.

    节点: 网页中所有的内容都可以称为 节点(标签节点, 注释节点, 文本节点, 属性节点等). 使用 node 表示. 

    获取元素 

    一个DOM树上面有很多很多对象,到底要操作谁?

    先选中对象,然后再操作对象.

    DOM API 中提供了很多能够用来选中对象/元素的函数

    querySelector / querySelectorALL(两个功能最强大的)

    基本用法 

    document 就表示 "文档"

    是每个项目都自带的一个默认的对象.

    这个相当于是一个"全局变量"

    可以在代码的任意位置来访问到 document.

     querySelector 参数是一个 "字符串"

    这个字符串是一个CSS选择器

    "div" 标签选择器

    可能存在多个 div .

    querySelector 就会返回多个被选中元素中的第一个(第一个出现的元素)

    querySelectorALL就会把选中的多个元素以数组的形式,全都返回.

    如果要是在document上调用这俩方法,相当于从这个页面的全局来查找复合要求的元素.

    如果是在某个具体的 dom 对象上调用这俩方法,相当于从这个元素里面来查找符合要求的元素.

    尤其是一个复杂的前端页面,尤其是这个页面是多个组/多人协同开发的时候.

    以搜狗为例:

    搜狗的搜索结果页,就包含了自然搜索结果 + 广告搜索结果.

    最终的页面,相当于两份 thml 的内容拼接在一起.

    其中自然搜索结果是一伙人来实现的.

    广告搜索结果是领一伙人来实现的

    广告这边,开发某个功能,需要修改一些样式.

    假设,广告搜索这边,搞了个CSS类名, .aa

    碰巧,自然搜索这边,也搞了个CSS类名, .aa

    如果广告搜索这边通过 querySelectorAll按照 .aa 一查找,就可能把自然搜索这边的元素给找到了,进一步的就可能把人家的样式给改坏了

    使用 document.querySelector 存在上述问题.

    但是和自然搜索那边约定好了,广告这边的html都在一个固定的父元素标签内部.......

    此时就可以针对这个父元素标签来进行querySelector,就只在子元素里面找,自然不会影响到别人的代码了

    效果

     console.log 在打印 元素 对象的时候,会自动的把打印的内容转成对应的 html 片段,方便程序猿来观察

     效果

     效果

    当前的结果里面NodeList里面只有一个元素 

    事件初识 

    关于"事件"

    一些复杂的程序,往往要涉及到一些"组件之间的通信"

    事件机制(event)就是一种非常典型也非常常见的组件之间通信的机制.

    典型的例子,就是一个图形化的程序(带界面的程序)

    事件三要素 

    1. 事件源: 哪个元素触发的

    2. 事件类型: 是点击, 选中, 还是修改?

    3. 事件处理程序: 进一步如何处理. 往往是一个回调函数.

    简单案例:

    创建一个按钮

    事件的种类也很多,click是最常见的鼠标点击. 

    操作元素 

    1.获取/修改元素内容

    盒模型:

    1.外边框

    2.边框

    3.内边距

    4.内容

    这个内容可能是一个文本,可能是一个图片,也可能是个链接,也可能是一组复杂的html.

    一段 html 片段.

    关键就是在于元素 innerHTML 这个属性

    效果

     通过这个操作就可以得到元素里面的内容 

    效果

     通过这个操作就可以修改元素里面的内容 

    innerHTML 不光可以赋值为一个文本,还可以赋值为一个 html 片段

    效果

    一个简单的案例:

    搞两个按钮,一个显示框,这里显示一个数字

    通过点击两个按钮,一个让整数 + 1,一个让整数 - 1

    获取元素属性

    src属性表示图片路径是什么

    alt属性表示图片挂了显示什么

    title属性表示光标放上去显示什么

    在HTML中指定的属性,最终都会体现在 JS 中.

    举例:

    效果

    通过console.log直接打出来的是html的片段,但是我们想知道这里面的属性啊,因此打印我们还有另外的办法

    效果

     

    HTML中的元素,就会在JS中有一个对应的对象,通过querySelector,就能把对象给获取出来.

    这个对象中包含了很多很多的属性.

    之前在HTML中指定的属性,都在这个 JS 对象中有所体现.

    如果 直接修改JS对象的属性,也就会直接影响到HTML中的显示效果.

    对象再加点的方式就可以把对应的属性单独获取到

     

    修改元素属性 

    在 JS  中,比较两个字符串内容相等,就直接使用 == 来比较 

     

    效果

     

    获取/修改表单元素属性 

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

    value: input 的值.

    disabled: 禁用

    checked: 复选框会使用

    selected: 下拉框会使用

    type: input 的类型(文本, 密码, 按钮, 文件等)

    举例:

    切换按钮的文本.

    效果:

    点一下按钮,如果是播放就会切换成暂停,暂停就会切换成播放.

     举例:

    全选/取消全选按钮

     

    1. <body>
    2. <div class="parent">
    3. <h3>请选择你的老婆:h3>
    4. <input type="checkbox" class=" girl"> 貂蝉 <br>
    5. <input type="checkbox" class=" girl"> 小乔 <br>
    6. <input type="checkbox" class=" girl"> 安其拉 <br>
    7. <input type="checkbox" class=" girl"> 妲己 <br>
    8. <input type="checkbox" class=" all"> 全都要 <br>
    9. div>
    10. <script>
    11. //1.先把要操作的元素都准备好
    12. let all = document.querySelector(".all");
    13. let girls = document.querySelectorAll('.girl');
    14. //2.实现点击all就选中所有的选项
    15. all.onclick = function(){
    16. //循环每个gril,把checked 属性给设置上.
    17. for(let i = 0; i < girls.length; i++){
    18. girls[i].checked = all.checked;
    19. }
    20. }
    21. //3.针对 girls 设置点击操作函数
    22. for(let i = 0; i< girls.length; i++){
    23. girls[i].onclick = function(){
    24. //根据 girls 的选中状态修改 all.checked 的值
    25. //当所有的 girls 都被选中的时候,就把 all.checked 设为 true
    26. //只要有一个 girls 没被选中,就把 all.checked 设为 false
    27. //单独搞一个 checkGirl 函数来完成这个检测过程
    28. all.checked = checkGirl();
    29. }
    30. }
    31. function checkGirl(){
    32. //遍历所有的girl,看他们的 checked 状态
    33. //如果所有的 girl checked 状态都为 true, 最终就返回true(也就是把 all 的 checked 改为 true)
    34. //如果有一个 girl checked 为false,此时就返回 false
    35. for(i = 0; i < girls.length; i++){
    36. if(!girls[i].checked){
    37. return false;
    38. }
    39. }
    40. return true;
    41. }
    42. script>
    43. body>

    效果:

    修改样式属性 

    相关的属性主要有两个:

    1.style 属性,影响到了行内样式(直接嵌入到html元素里面的样式)

    2.className 属性给元素设置一个CSS类名.

    行内样式操作

    CSS中有的属性名,是带横线的(-)的.(属于脊柱命名块)

    background - color

    这种 JS 中没法直接操作.JS的变量名,不支持横线(-).(JS的变量名和普通的语言一样,都是,数字,字母,下划线,$)

    这种情况就可以使用"驼峰的方式" 来进行设置.

    好比:backgroudColor 

    style 属性案例:

    点击文字则放大字体.

    效果

     

    如果修改的样式比较多,就不太适合使用 style 了 .

    可以使用 className

    className 属性案例:

    开启夜间模式

    效果:

     

     

    在JS中,this是一个非常"飘忽不定" 的存在!!

    Java / C++ 的this,指向都是非常明确的.....

    JS 中的 this 指向可能会随时变化.(暂时不去研究它的规则,就敬而远之就可以了)

    操作节点 

    新增节点

    1.创建一个节点

    document.creatElement(标签名);

    2.把节点给挂到DOM树上

    删除节点 

    使用 removeChild 函数删除子节点.

    和新增节点一样,要先拿到父结点,然后在拿到待删除节点。
    最后,通过 removeChild 就能删除 节点了。

    JS 也是带有垃圾回收机制的(简单了解即可)

    删除节点简单案例:

     

    结合上述操作写几个案例 

    猜数字

    预期效果:

     

    完整代码

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>猜数字title>
    8. head>
    9. <body>
    10. <button id="reset">重新开始一局游戏button>
    11. <br>
    12. 请输入要猜的数字:<input type="text" id="number">
    13. <button id="guess">button>
    14. <br>
    15. 已经猜的次数:<span id="count">0span>
    16. <br>
    17. <span>结果:span><span id="result">span>
    18. <script>
    19. // 1. 先把需要用到的元素先获取到.
    20. let resetButton = document.querySelector('#reset');
    21. let numberInput = document.querySelector('#number');
    22. let guessButton = document.querySelector('#guess');
    23. let countSpan = document.querySelector('#count');
    24. let resultSpan = document.querySelector('#result');
    25. //2.生成一个随机的整数 范围[1 - 100]
    26. let guessNum = Math.floor(Math.random() * 100) + 1;
    27. //3.给 guessButton 设置点击事件.
    28. let guessCount = 0;//表示猜的次数
    29. guessButton.onclick = function(){
    30. // 1.先更新猜的次数的显示
    31. guessCount += 1;
    32. countSpan.innerHTML = guessCount;
    33. // 2.把输入框的内容取出来,和待猜的元素进行对比,返回"高了","低了"
    34. // 3.能够再界面上显示高低的结果
    35. let userNum = parseInt(numberInput.value);
    36. if(userNum == guessNum){
    37. //猜对了
    38. resultSpan.innerHTML = '猜对了';
    39. resultSpan.style.color = 'green';
    40. }else if(userNum > guessNum){
    41. //猜高了
    42. resultSpan.innerHTML = '猜高了';
    43. resultSpan.style.color = 'red';
    44. }else{
    45. //猜低了
    46. resultSpan.innerHTML = '猜低了';
    47. resultSpan.style.color = 'blue';
    48. }
    49. }
    50. //4.给 resetButton 设置点击事件
    51. resetButton.onclick = function(){
    52. //1.重新生成随机数
    53. guessNum = Math.floor(Math.random() * 100) + 1;
    54. //2.把猜的次数设为0
    55. guessCount = 0;
    56. countSpan.innerHTML = guessCount;
    57. //3.把猜的结果也清空
    58. resultSpan.innerHTML = '';
    59. //4.把用户的输入框,也清空
    60. numberInput.value = '';
    61. //上面的操作固然能完成清空,但是还有更狠的一招!!!
    62. //还可以直接刷新页面!!!只要刷新页面,前面创建的 DOM 树,各种 JS 的变量 ...都推到重来了
    63. //页面刷新对于 JS 就相当于 Java 一样
    64. //location 和 document 类似,都是浏览器提供的全局变量
    65. //documen 控制DOM 结构的
    66. //location 控制 浏览器跳转的.
    67. //location 不算 DOM api,而是算 DOM api
    68. location.reload();
    69. }
    70. script>
    71. body>
    72. html>

    表白墙

    预期效果

     

    完整代码

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>告白墙title>
    8. head>
    9. <body>
    10. <style>
    11. *{
    12. /* 首先先去除浏览器样式 */
    13. /* 将 内外边距设置为0,设置盒子模型为向内挤压 */
    14. margin: 0;
    15. padding: 0;
    16. box-sizing: border-box;
    17. }
    18. .containner{
    19. width: 100%;
    20. }
    21. h3{
    22. /* 文本居中 */
    23. text-align: center;
    24. /* 上下边距为 20px,左右边距为0 */
    25. padding: 20px 0;
    26. font-size: 24px;
    27. }
    28. p{
    29. text-align: center;
    30. color: #666;
    31. padding: 10px 0;
    32. }
    33. .row{
    34. width: 400px;
    35. height: 50px;
    36. /* 上下外边距为零,左右外边距自适应 */
    37. /* 就是元素水平居中操作 */
    38. margin: 0 auto;
    39. /* 弹性布局 */
    40. display: flex;
    41. /* 水平居中 */
    42. justify-content: center;
    43. /* 垂直居中 */
    44. align-items: center;
    45. }
    46. .row span{
    47. width: 60px;
    48. font-size: 17px;
    49. }
    50. .row input{
    51. width: 300px;
    52. height: 40px;
    53. line-height: 40px;
    54. font-size: 20px;
    55. text-indent: 0.5em;
    56. outline: none;
    57. }
    58. .row #submit{
    59. width: 360px;
    60. height: 40px;
    61. font-size: 20px;
    62. line-height: 40px;
    63. margin: 0 auto;
    64. color: white;
    65. background-color: orange;
    66. border: none;
    67. border-radius: 15px;
    68. outline: none;
    69. }
    70. /* 当鼠标点击按钮的时候,会改变按钮颜色 */
    71. .row #submit:active{
    72. background-color: grey;
    73. }
    74. style>
    75. <div class="container">
    76. <h3>表白墙h3>
    77. <p>输入后点击提交,会将信息显示在表格中p>
    78. <br>
    79. <div class="row">
    80. <span>谁: span>
    81. <input type="text">
    82. div>
    83. <div class="row">
    84. <span>对谁: span>
    85. <input type="text">
    86. div>
    87. <div class="row">
    88. <span>说什么: span>
    89. <input type="text">
    90. div>
    91. <div class="row">
    92. <button id="submit">提交button>
    93. div>
    94. div>
    95. <script>
    96. let submitBtn = document.querySelector('#submit');
    97. submitBtn.onclick = function(){
    98. // 1、获取 3个input 文本框中的数据
    99. let inputs = document.querySelectorAll('input');
    100. let from = inputs[0].value;
    101. let to = inputs[1].value;
    102. let say = inputs[2].value;
    103. if(from == ''|| to == '' || say == ''){
    104. // 用户填写的数据,并不完整。所以不提交。
    105. return;
    106. }
    107. // 2、生成一个新的 div,内容就是 三个 input 文本框的内容拼接
    108. // 再把这个 元素,挂在DOM树上。
    109. let newDiv = document.createElement('div');
    110. newDiv.innerHTML = from + "对" + to +"说:" + say;
    111. newDiv.className = 'row';
    112. // 将新建节点,挂在 container 这个节点下面
    113. let container = document.querySelector('.container');
    114. container.appendChild(newDiv);
    115. }
    116. script>
    117. body>
    118. html>

    表白墙这样的程序,所提交的数据,只是保存在当前的页面中.

    一般页面刷新/关闭了,此时数据就不再了.

    (这样的数据不具备持久性)

    如何能让这个数据持久的保存起来?

    核心办法就是把这些数据提交到服务器上,然后服务器把这些数据存在  文件/数据库  中.

     

     

  • 相关阅读:
    css3动画+svg实现水球进度条
    firewall 命令简单操作
    程序员的心得体会
    apollo配置中心
    项目(模块1:用户登陆流程分析)
    Linux图形显示DRM子系统环境实践
    解决git无法上传大文件(50MB)
    DPDK的VFIO
    Linux 环境删除Conda
    【部署篇】Docker配置MySQL容器+远程连接
  • 原文地址:https://blog.csdn.net/m0_64397675/article/details/126240578