循序渐进学 JavaScript <二>

续 <一>

在这里插入图片描述

九、JavaScript常见内置类

9.1 原始类型的包装类

  • 基本数据类型也可以调用属性
    • 在理论上来说它们是没有办法获取属性或者调用方法的
  • 原始类型是简单的值,默认并不能调用属性和方法
  • js 为了可以使其获取属性和调用方法,对其封装了对应的包装类型
    • 普通字符串==》包装类型
  • 常见的包装类型
    • String、Number、Boolean、Symbol、BigInt

9.2 包装类型的使用过程

  • 根据初始值,创建一个原始类型对应的包装类型对象
  • 调用对应的属性或者方法,返回一个新的值
  • 创建的包装类对象被销毁
  • 但是通常 js 引擎会进行优化,跳过包装类的过程在内部直接完成属性的获取或者方法的调用

9.3 Number 类补充

  • 具有自己的属性
    • 类属性
  • 具有实例方法
    • 实例方法:通过对象来调用
    • toFixed()
    • toString()
<script>var num = 19//new Number(num)// integer:整数// 类属性console.log(Number.MAX_SAFE_INTEGER);// 对象方法var num1 = 3.333454// 转化成字符串类型console.log(num1.toString());// 转换为二进制console.log(num1.toString(2));console.log(123..toString());// 保留三位小数console.log(num1.toFixed(2));// 类方法// 字符串转数字类型var str = "123.24"Number(str)//不做区分浮点数和整数Number.parseInt(str)Number.parseFloat(str)// window对象上面console.log(parseInt(str));</script>

9.4 Math 对象

  • 是一个对象类型,不是构造函数
<body><script>console.log(typeof Math);// Math对象的属性console.log(Math.PI);var num = 3.13console.log(Math.floor(num));console.log(Math.ceil(num));console.log(Math.round(num));// random:[0,1)console.log(Math.random());// 需求5~50的随机数// [5,20)var randomNum = Math.floor(Math.random()*45)+5</script>
</body>

9.5 Number、Math 的常见操作

9.5.1 Number 类的操作

  • 类属性
    • Number.MAX_SAFE_INTEGER 最大安全整数
    • Number.MIN_SAFE_INTEGER 最小安全整数
  • 实例方法
    • toString(base),将数字转成字符串,并且按照base进制进行转化
    • toFixed(digits),格式化一个数字,保留digits位的小数,会四舍五入
  • 类方法
    • Number.parseInt(string[, radix]),将字符串解析成整数,也有对应的全局方法parseInt;
    • Number. parseFloat(string),将字符串解析成浮点数,也有对应的全局方法parseFloat;

9.5.2 Math 的常见操作

  • 属性

    • Math.PI:圆周率
  • 常见的方法

    • Math.floor:向下舍入取整
    • Math.ceil:向上舍入取整
    • Math.round:四舍五入取整
    • Math.random:生成0~1的随机数(包含0,不包含1)
    • Math.pow(x, y):返回x的y次幂
  • 公式: [a,b)的随机数

    • y=a,x=b-a, Math.floor(Math.random() * x) + y

9.6 String 类的补充

  • 属性
    • length:获取字符串长度
  • 访问某一个位置对应的字符
  • 遍历
<script>// 属性var message = "lili"console.log(message.length);// 访问某一个位置对应的字符console.log(message[3]);//超出范围:undefinedconsole.log(message.charAt(3));//超出范围:空字符串// 3. 字符串的遍历// 3.1 for普通遍历for(let i =0;i<message.length;i++){console.log(message[i]);}// 3.2 for..of遍历 -> 迭代器:目前就字符串和数组// 对象不支持for...of// string对象内部将字符串变成了一个可迭代对象for(var char of message){console.log(char);}</script>
  • 字符串不能修改
// 4. 修改字符串
// 创建新的字符串,让变量指向了一个新的值
message = "加加加"
// 严格的修改字符串:修改之前的字符串内部
message[1] = "0"
// 所有字符变成大写:生成新的字符串
var message1 = message.toUpperCase()
console.log(message1);
// 变成小写
var message2 = message.toLowerCase()
  • 查找字符串
    • indexOf
    • includes
    • startWith
    • endWith
    • replace
// 判断一个字符串中是否有另外一个字符串
// 5.1 indexOf(searchString,fromIndex)
/*index:搜索到,返回搜索字符串所在的索引位置没有搜索到,返回-1*/
var index = message2.indexOf(name)
console.log(index);
// 存在
if (message2.indexOf(name) !== -1) {console.log("message2中包含name");
} else {console.log("message2中不包含name");
}// 5.2 includesES6新增语法,用来判断包含关系
if (message2.includes(name)) {console.log("哈哈哈哈好好照顾自己~~");
}
// 5.3 startWith:是否以xxx开头
if (message2.startsWith("my")) {console.log("messages以my开头");
}// 5.4 endWith:是否以xxx开头// 5.5 replace:替换字符串("替换谁",正则表达式、代替值、函数)var newMessage = message2.replace("lili", "涵涵")console.log(newMessage);var newMessage2 = message2.replace("lili", function () {// 使用函数返回的值去替代字符串return "kobe"})console.log(newMessage2);// 6. 获取子字符串:slice、substring、substr// slicevar clothes = "衣服包包鞋子"console.log(clothes.slice(3));//截到最后console.log(clothes.slice(1, 3));// substr:浏览器是否支持
  • 获取子字符串:slice
// 6. 获取子字符串:slice、substring、substr
// slice
var clothes = "衣服包包鞋子"
console.log(clothes.slice(3));//截到最后
console.log(clothes.slice(1, 3));
// substr:浏览器是否支持
  • 字符串拼接
// 7. 字符串的拼接
// 7.1 +
var str1 = "lili"
var str2 = "哈啰"
var newStr = str1 + str2
// 7.2 concat:支持链式调用,参数是可变参数...
var newStr2 = str1.concat(str2, newStr)
  • 删除首尾的空格
// 8. 删除首尾空格
console.log("           lili   ".trim());
  • 字符串的切割
// 9. 字符串的切割split:返回值是一个string类型的数组
var infos = "aaa-bbb-ccc-ddd"
// 传入一个分隔符
var items = infos.split("-")
console.log(items);
// join:把数组转为字符串,参数为以什么连接
var str3 = items.join("*")
console.log(str3);
  • 补齐字符串:str.padStart(4, “0”)

9.7 数组 Array

  • 一系列的商品,使用键值对访问并不方便,需要一个有序的集合,里面的元素是按照某一个顺序来排列的,可以通过索引来获取到它----编程语言提供了一种数据结构:数组[]
<body><script>// 1. 创建数组的方式一:字面量的方式var names = ["aaa", "bbb", "ccc"]//字符串类型var products = [{ name: "iphone", price: 99, desc: "九块九" },{ name: "鼠标", price: 199, desc: "哈哈" },{ name: "键盘", price: 989, desc: "六点多" },]//对象类型// 2. 创建数组方式二:类Arrayvar arr1 = new Array()console.log(arr1);var arr2 = new Array("abc", "cba", "nba")//["abc","cba","nba"]console.log(arr2);// 传入一个数字,会默认当成常见一个对应长度的数组var arr3 = new Array(5)//[empty * 5]</script>
</body>
  • 数组的基本操作
 <script>var names = ["aaa", "bbbb", "ccccc"]// 1. 访问数组中的元素console.log(names[0]);console.log(names.at(-1));// 2. 修改数组中的元素names[0] = "why"// 3. 新增数组中的元素names[3] = "kobe"//没有人这么做// 4. 删除数组中的元素delete names[1]//empty,没有人这么做</script>
<script>var names = ["lili", "dameinb", "jiao"]// 在数组的尾部添加和删除元素// push方法names.push("aaaa", "dddd")// pop方法names.pop()// 在数组的头部添加和删除元素:效率非常低// unshift方法names.unshift("sss", "hhh")// shift方法names.shift()// splice方法:处理数组的利器,修改的是原数组// 能够在任意位置添加/删除/替换元素// 参数一:start,从什么位置开始操作函数// 参数二:deleteCount,删除元素的个数// 1. 删除元素names.splice(1,2)// 2. 新增元素:deleteCount=0,后面可以添加新的元素names.splice(1,0,"why","kebe")// 3. 替换元素:先移除,再新增names.splice(1,2,"lisssss","yejie")</script>
  • length 属性
    • length属性是可写的,可以扩容,但是一般不需要扩容
    • 清空数组:arr.length = 0
<script>var names = ["lilio", "xiaoming", "xiaohong"]// 获取数组的长度console.log(names.length);// length属性可写的names.length=10// 会自动对数组进行扩容// 设置的length小于原来的元素个数names.length = 2//会将后面的内容截取掉</script>
  • 数组的遍历
// 数组的遍历// 1. 普通的for循环for (var i = 0; i < names.length; i++) {console.log(names[i]);}// 2. for in:适用于需要获取对应的索引for (var index in names) {console.log(index, names[index]);}// 3. for offor (var item of names) {console.log(item);}
  • 数组方法
    • slice:对数组进行截取
var names = ["abc","ddd","ggg","ytyt"]// 1. slice 方法:不会修改原数组// 与splice 区别:splice修改原有的数组var newNames = names.slice(1)console.log(newNames); 
  • concat:将多个数组拼接在一起
   // 2. concat :将多个数组拼接在一起var name1 = "lili"var name2 = "jiao"var name3 = "dandan"// 使用展开运算符const newNames = []newNames.push(...name1,...name2,...name3)const newNamess=name1.concat(name2,name3)console.log(newNamess);
  • join:将数组转成字符串,split:将字符串转化成数组
 // 3. join:将数组变成字符串console.log(names.join("-"));
  • 查找元素
    • indexOf:针对原始类型
 // 1. 数组中存放的是原始类型var names=["abc","cba","dddd"]// 1.1 indexOf// 找到返回索引// 没找到返回-1console.log(names.indexOf('abc'));// 2. 数组中存放的是对象类型var student = [{id:1002,name:"hey2",age:14},{id:1004,name:"hey3",age:15},{id:1005,name:"hey5",age:64},{id:1006,name:"hey4",age:34},]// 查找id为1004的学生信息// 2.1 自己写一个for循环// var stu = {}// 因此初始化为nullvar stu =null// 赋值为空的缺点:1. 转为布尔值都是真值 2. 空对象会占用内存for(var i =0;i<student.length;i++){if(student[i].id === 1004){console.log(student[i]);stu = student[i]break}}// 判断有没有找到对应的学生if(stu){console.log("找到了");}
  • find 方法
    // 2.2 find方法:高阶函数:数组中有几个元素就会调用多少次传入的函数var stu = student.find(function (item) {// console.log(item);if (item.id === 1004) return true})// 简写:var stu = student.find(item => item.id === 1004)</script>
//手动实现高阶函数forEachvar names = ["dd", "ddd", "gggg"]// forEach 函数:可以帮助遍历数组// names.forEach(function (item, index, err) {//   console.log(item, index, err);// })// //版本一:回调函数// // 自己实现上述函数// function liliForEach(fn) {//   for (var i = 0; i < names.length; i++) {//     fn(names[i], i, names)//   }// }// liliForEach(function (item, index, names) {//   console.log(item, index, names);// })// //版本二// function liliForEach(fn, arr) {//   for (var i = 0; i < arr.length; i++) {//     fn(names[i], i, arr)//   }// }// liliForEach(function (item, index, names) {//   console.log(item, index, names);// }, names)// // 版本三:往对象里面加属性// names.liliForEach = function liliForEach(fn) {//   for (var i = 0; i < this.length; i++) {//     fn(this[i], i, this)//   }// }// names.liliForEach(function (item, index, names) {//   console.log(item, index, names);// })// 版本四:放在原型链上Array.prototype.liliForEach = function liliForEach(fn) {for (var i = 0; i < this.length; i++) {fn(this[i], i, this)}}names.liliForEach(function (item, index, names) {console.log(item, index, names);})
//手动实现高阶函数forEach// 原始类型var names = ["abc", "vvv", "ooo1"]// 内部函数返回true,意味着找到了,后边就不需要遍历了,后面的不会继续执行// 没有返回值意味着返回undefined,布尔值为falsenames.find(function (item, index, arr) {console.log(item, index, arr);// return true//返回了第一个元素而不是true})// 数组中对象类型var students = [{ id: 1002, name: "hey2", age: 14 },{ id: 1004, name: "hey3", age: 15 },{ id: 1005, name: "hey5", age: 64 },{ id: 1006, name: "hey4", age: 34 },]students.find(function (item) {console.log(item);return item.id === 1002})// 自己实现Array.prototype.liliFind = function (fn) {var item //可以不设定,默认为undefinedfor (var i = 0; i < this.length; i++) {var isFlag = fn(this[i], i, this)if (isFlag) {// item = this[i]// breakreturn this[i]}}// return item}students.liliFind(function (item, index, arr) {return item.id === 101})
  • includes:返回 true / false
  • findIndex:查找元素的索引,找不到返回 -1
   // 查找元素// indexOf/lastIndexOf// includesconsole.log(names.includes('abc'));// findIndex:查找元素索引var findIndex = names.findIndex(function(item,index,arr){return item === 'nba'})console.log(findIndex);
  • 数组的排序:sort修改原数组

  • 数组的反转:reserve生成一个新的数组

  • 其他高阶函数

    • reduce

    • filter

    • map

    // 1.forEach函数var names = ["abc", "cba", "nba", "mba"]// 三种方式, 新增一种方式names.forEach(function (item) {console.log(item)})names.forEach(item => console.log(item))// 2.filter函数: 过滤var nums = [11, 20, 55, 100, 88, 32]// 2.1. for循环实现var newNums = []// for of方法for (var item of nums) {if (item % 2 === 0) {newNums.push(item)}}// 2.2. filter实现:形成新数组//  只筛选出满足条件的// var newNums = nums.filter(function(item) {//   return item % 2 === 0// })// console.log(newNums)// 3.map函数: 映射:对原来的数组元素进行变化,映射形成新数组var nums = [11, 20, 55, 100, 88, 32]var newNums = nums.map(function (item) {return item * item})console.log(newNums)// 4.reducevar numbers = [11, 20, 55, 100, 88, 32]var result = 0for (var item of numbers) {result += item}console.log(result)// initialValue: 初始化值, 第一次执行的时候, 对应的preValue// 如果initialValue没有传呢?var result = nums.reduce(function(preValue, item) {console.log(`preValue:${preValue} item:${item}`)return preValue + item}, 0)console.log(result)// reduce练习var products = [{ name: "鼠标", price: 88, count: 3 },{ name: "键盘", price: 200, count: 2 },{ name: "耳机", price: 9.9, count: 10 },]var totalPrice = products.reduce(function(preValue, item) {return preValue + item.price * item.count}, 0)console.log(totalPrice)// 综合练习: var nums = [11, 20, 55, 100, 88, 32]//   过滤所有的偶数, 映射所有偶数的平方, 并且计算他们的和var total = nums.filter(function (item) {return item % 2 === 0}).map(function (item) {return item * item}).reduce(function (preValue, item) {return preValue + item}, 0)console.log(total)var total = nums.filter(item => item % 2 === 0).map(item => item * item).reduce((preValue, item) => preValue + item, 0)console.log(total)

9.8 String 和 Array 常见操作

9.8.1 String 的常见操作

  • 创建方式 new String()
  • 属性
    • length —获取字符串的长度
  • 访问其中元素
    • [0]
    • charAt(0)
  • 遍历
    • 普通的for循环
    • for…of方式
      • 可迭代对象
      • 字符串/数组
  • 字符串不可变性
  • 实例方法:
    • toUpperCase() 将所有的字符转成大写;
    • toLowerCase() 将所有的字符转成小写;
    • indexOf 查找字符串位置
    • includes 是否包含字符串
    • startsWith 判断是否以xxx开头
    • endsWith 判断是否以xxx结尾
    • repace 替换字符串
    • slice/substring/substr 获取子字符串
    • concat 字符串拼接
    • trim 去除首尾空格
    • split 字符串分割,字符串—>数组
      • join 数组–>字符串

9.8.2 Array 的常见操作

  • 创建数组

    • [] 数组字面量
    • new Array()
      • 传1个数组,表示数组的长度
  • 数组基本操作

    • 获取元素
      • [0]
      • at(0)
    • 修改元素
      • arr[1] = "fff"
    • 新增
      • arr[5]="123"
    • 删除
      • delete arr[0]
  • 在数组的尾部:

    • push 尾部添加
    • pop 删除尾部的最后一个元素,返回被删除的元素
  • 在数组首部

    • unshift 首部添加
    • shift 删除首部的第一个元素,返回被删除的元素
  • 利器

    • splice 在任何位置添加/删除/替换元素
      • start 从什么位置开始操作元素
      • deleteCount 删除元素的个数
        • 2 删除2个
        • 0 添加元素
      • item1/item2 添加或者替换的元素

9.9 时间的表示

  • UTC :标准的时间

  • 创建 Date对象

   //创建Date对象的方式// 1. 没有传入任何的参数,获取到当前时间var date1 = new Date()console.log(date1);// 2. 传入参数:时间字符串var date2 = new Date("2022-09-09")console.log(date2);// 3. 传入具体的年月日时分秒var date3 = new Date(2023, 10, 10, 9, 8, 7, 333)console.log(date3);// 4. 传入一个 Unix 时间戳==》需要转成对应的时间// 1s ==> 1000msvar date4 = new Date(100000000000233)console.log(date4);
  • Date 对象的字符串形式:new Date().toISOSTring()---- 但其实也不经常用
  • 获取时间信息
  // 获取想要的时间信息var date = new Date()console.log(date.toISOString());var year = date.getFullYear()var month = date.getMonth() + 1var day = date.getDate()var hour = date.getHours()var minute = date.getMinutes()var second = date.getSeconds()// 一周中的第几天var weekday = data.getDay()
  • Date转变为时间戳:
 //  Date对象如何转成时间戳var date = new Date()console.log(date);// 方法一:当前时间的时间戳var timestamp = Date.now()console.log(timestamp);var timestamp1 = date.getTime()//获取时间戳一var timestamp2 = date.valueOf()//获取时间戳二//计算操作花费的时间var startTime = Date.now()for (var i = 0; i < 10000; i++) {console.log(i);}var endTime = Date.now()console.log("花费的时间:", endTime - startTime);

十、JavaScript 的 DOM 操作

10.1 DOM 、BOM

  • 利用浏览器提供给开发者的DOM、BOM相关的API才能对页面、浏览器进行操作

  • API:application programming interface

  • DOM:文档对象模型

    • 浏览器将其抽取为一个个文档对象模型
    • 将网页里面的所有内容表示为可以修改的对象
    • 通过 api 去获取
    • 整个的文档为 document
    • js 语法和浏览器之间的桥梁
    • 这些对象都可以通过JavaScript来对其进行访问
  • BOM:浏览器对象模型

    • 浏览器提供的用于处理文档之外的所有内容的其他对象
    • navigator、location、history

10.2 DOM

  • DOM tree:抽象成DOM对象的时候,会形成一个树结构

  • 学习顺序

    • DOM元素之间的关系
    • 获取DOM元素
    • DOM节点的 type、tag、content
    • DOM 节点的attributes、properies
    • DOM 节点的创建、插入、克隆、删除
    • DOM 节点的样式、类
    • DOM 元素/window的大小、滚动、坐标
  • 继承关系图

10.3 document 对象

  • document 节点表示的是整个载入的网页,它的实例是全局的 document 对象
    • 是DOM的入口点,可以从document开始去访问任何节点元素
  • 对于最顶层的 html、head、body 元素可以直接在 document 对象中获取到:
    • html元素: = document.documentElement
    • body元素: = document.body
    • head元素: = document.head
    • 文档声明: = document.doctype

10.4 DOM 和 document 对象

  • DOM:文档对象模型(Document Object Model)将页面所有的内容表示为可以修改的对象
    • 浏览器将编写在HTML中的每一个元素(Element)都抽象成了一个个对象
    • 所有这些对象都可以通过JavaScript来对其进行访问,可以通过 JavaScript来操作页面;
    • 将这个抽象过程称之为 文档对象模型(Document Object Model)
  • Document节点表示的整个载入的网页,它的实例是全局的document对象:
    • 对DOM的所有操作都是从 document 对象开始的
    • 它是DOM的入口点,可以从document开始去访问任何节点元素;

10.5 节点之间的导航

  • 父节点:parentNode
  • 前兄弟节点:previousSibling
  • 后兄弟节点:nextSibling
  • 子节点:childNodes
  • 第一个子节点:firstChild
  • 第二个子节点:lastChild

10.6 元素之间的导航

  • 获取到一个元素后,根据这个元素去获取其他的元素
  • 父元素:parentElement
  • 前兄弟节点:previousElementSibling
  • 后兄弟节点:nextElementSibling
  • 子节点:children
  • 第一个子节点:firstElementChild
  • 第二个子节点:lastElementChild

10.7 表格元素的导航

  • 元素独特属性:
    • table.rows —
    元素的集合;
  • table.caption/tHead/tFoot — 引用元素
  • table.tBodies —
  • 元素的集合;
  • ,, 元素提供了 rows 属性:

    • tbody.rows — 表格内部 元素的集合
    • tr.cells — 在给定 中的 和 单元格的集合;
    • tr.sectionRowIndex — 给定的 在封闭的 // 中的位置(索引);
    • tr.rowIndex — 在整个表格中 的编号(包括表格的所有行)
    • td.cellIndex — 在封闭的 中单元格的编号

10.8 表单元素的导航

  • 通过document来获取:document.forms
  • 获取form元素中的内容:form.elements
  • 设置表单子元素的name来获取他们
    • elements.accounts.value

10.9 获取元素

  • 通过导航获取:一层一层拿某个单独的元素非常不方便,当元素彼此靠近豁这相邻时候,导航属性非常有用
  • 直接获取:
    • document.getElementsByClassName(“keyword”)
    • document.getElementById(‘title’)
    • querySelector 和 querySelectAll
  // 1. 元素之间的导航// 1. 拿到 bodyvar bodyEl = document.body// 2. 拿到 boxvar boxEl = bodyEl.firstElementChild// 3. 拿到 containervar containerEl = boxEl.children[1]// 4. 拿到 pvar pEl = containerEl.children[0]// 5. 拿到 keywordvar spanEl = pEl.children[0]spanEl.style.color = 'red'// 2 通过getElementBy直接获取// 2.1 通过classname获取火速var keyword = document.getElementsByClassName("keyword")// 2.2 通过id获取元素var titleEl = document.getElementById('title')// 3 通过选择器查询var keyWordEL = document.querySelector('.keyword')var keywordEls = document.querySelectorAll('.keyword')// 是类数组对象但是是可迭代的,支持for of,有一个索引属性,不是数组//可迭代对象:String,数组,节点列表

10.10 节点的属性-nodeType

  • nodeType:节点的类型

    • 数值类型:
    • 10:DocumentType 节
    • 9:Document
    • 8:注释
    • 3:文字
    • 1:元素
  • nodeName:针对于节点,节点的名称

  • tagName:针对于元素,元素的标签名称

  • data/nodeValue:针对非元素的节点获取数据

  • innerHTML:对应的html元素也会获取,会直接进行替换,能够识别标签

  • textContent:只会获取文本内容,不能够识别标签

  • outerHTML

  • hidden属性:也是一个全局属性,可以用于设置元素隐藏,display

  • 总结

    • nodeName:获取node节点的名字
    • tagName:获取元素的标签名词
    • innerHTML:将元素中的 HTML 获取为字符串形式;设置元素中的内容
    • outerHTML:包含了元素的完整 HTML;innerHTML 加上元素本身
    • textContent:仅仅获取元素中的文本内容
    • nodeValue:用于获取非元素节点的文本内容
    • hidden:可以用于设置元素隐藏

10.11 元素的特性 attribute

  • 分类
    • 标准:html标准中原有的
    • 非标准:自定义的
  • 操作
    • elem**.hasAttribute(name) — 检查特性是否存在**。
    • elem.getAttribute(name) — 获取这个特性值,拿到字符串。
    • elem.setAttribute(name, value) — 设置这个特性值。
    • elem.removeAttribute(name) — 移除这个特性。
    • attributes:attr 对象的集合,具有name、value属性;

10.12 元素的属性 property

  • 对于标准的 attribute,会在DOM对象上创建与其对应的 property 属性:标准的attribute都有对应的 property
  • 在大多数情况下,它们是相互作用的
    • 改变property,通过attribute获取的值,会随着改变;
    • 通过attribute操作修改,property的值会随着改变;
    • 如果不支持就使用 setAttribute (比较标准)

10.13 动态修改样式

  • 选择一:在 CSS 中 编写好对应的样式,动态的添加 class
    • 比较固定的值
   boxEl.className = 'active'
  • 选择二:动态的修改style属性;
    • 精准的修改
 boxEl.style.color = 'red'boxEl.style.fontSize = '24px'

10.14 元素的 className 和 classList

  • 在 attribute 中对应为 class,对应的 property 为 className
  • className 会进行覆盖
  • 添加或者移除单个的class,那么可以使用classList属性,不会覆盖掉其他的
    • elem.classList 是一个特殊的对象
      • elem.classList.add (class) :添加一个类
      • elem.classList.remove(class):添加/移除类
      • elem.classList.toggle(class) :如果类不存在就添加类,存在就移除
      • elem.classList.contains(class):检查给定类,返回 true/false。
    • classList是可迭代对象,可以通过for of进行遍历

## 10.15 元素的 style 属性

  • 单独修改某一个 CSS 属性,那么可以通过 style 来操作:
  • 对于多词(multi-word)属性,使用驼峰式 camelCase
  • 将值设置为空字符串,那么会使用 CSS 的默认样式
  • 多个样式需要使用 cssText 属性

10.16 元素 style 的读取 - getComputedStyle

  • 对于内联样式,是可以通过style.*的方式读取到的
  • 对于 style、css 文件中的样式,是读取不到的
  • getComputedStyle 的全局函数来实现:getComputedStyle(boxEl).fontSize

10.17 data-自定义属性

  • HTML5 新增
  • 如果直接写的话就是 attributes 添加了一个 age 属性,不推荐这种写法
  • 推荐使用 data-*自定义属性
  • 标签中自定义:data-age = '19'
  • 在 script 中获取:boxEl.dataset.age

10.18 创建元素

  • 插入一个元素

    • 早期使用 document.write 方法写入

    • 后期

      • 步骤一:创建一个元素:document.createElement(tag)
      // 真实地创建一个 DOM 对象var h2El = document.createElement("h2")h2El.textContent = '我是标题'
      
      • 步骤二:插入元素到DOM的某一个位置;
          // 将元素加入boxboxElboxEl.append(h2El)

10.19 插入元素

  • node.append(…nodes or strings) —— 在 node 末尾 插入节点或字符串
  • node.prepend(…nodes or strings) —— 在 node 开头 插入节点或字符串
  • node.before(…nodes or strings) —— 在 node 前面 插入节点或字符串
  • node.after(…nodes or strings) —— 在 node 后面 插入节点或字符串
  • node.replaceWith(…nodes or strings) —— 将 node 替换为给定的节点或字符串

10.20 移除和克隆元素

  • 调用元素本身的 remove 方法
  • 复制一个现有的元素,可以通过 cloneNode 方法
    • 可以传入一个Boolean类型的值,来决定是否是深度克隆
    • 深度克隆会克隆对应元素的子元素,否则不会

10.21 元素的大小、滚动

  • clientWidth:contentWith+padding(不包含滚动条)内容的宽度加上 padding

  • clientHeight:contentHeight+padding

  • clientTop:border-top的宽度

  • clientLeft:border-left的宽度

  • offsetWidth:元素完整的宽度

  • offsetHeight:元素完整的高度

  • offsetLeft:距离父元素的x

  • offsetHeight:距离父元素的y

  • scrollHeight:整个可滚动的区域高度

  • scrollTop:滚动部分的高度

10.22 window 的大小、滚动

  • **window 的 width 和 height **
    • innerWidth、innerHeight:获取window窗口的宽度和高度(包含滚动条)
    • outerWidth、outerHeight:获取window窗口的整个宽度和高度(包括调试工具、工具栏)
    • documentElement.clientHeight、documentElement.clientWidth:获取html的宽度和高度(不包含滚动条)
  • window 的滚动位置:
    • scrollX:X轴滚动的位置(别名pageXOffset)
    • scrollY:Y轴滚动的位置(别名pageYOffset)
  • 也有提供对应的滚动方法:
    • scrollBy(x,y) :将页面滚动至 相对于当前位置的 (x, y) 位置:scrollBy(0,100)
    • 方法 scrollTo ( pageX,pageY ) 将页面滚动至 绝对坐标;

10.23 动态创建列表

<body><ul class="list"></ul><script>var ulEl = document.querySelector('.list')var isFlag = truewhile (isFlag) {var message = prompt('请输入待处理事件')if (!message) {isFlag = false} else {var liEl = document.createElement('li')liEl.textContent = messageulEl.append(liEl)}}</script>
</body>

10.24 倒计时

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.countdown {color: red;font-size: 40px;}.countdown .time {background-color: rgb(187, 119, 31);color: azure;display: inline-block;padding: 50px;border-radius: 3px;}</style>
</head><body><div class="countdown"><span class="time hour">03</span><span class="split"></span><span class="time minute">03</span><span class="split"></span><span class="time second">03</span></div><script>// 1. 获取元素var hourElement = document.querySelector('.hour')var minuteElement = document.querySelector('.minute')var secondElement = document.querySelector('.second')setInterval(function(){// 2. 获取倒计时的时间var nowDate = new Date()var endDate = new Date()endDate.setHours(24)endDate.setMinutes(24)endDate.setSeconds(24)endDate.setMilliseconds(24)// 间隔时间var interValTime = Math.floor((endDate.getTime() - nowDate.getTime()) / 1000)// 秒 ==》 小时 分钟 秒钟  按照六十进制var hour = Math.floor(interValTime / 3600)var minute = Math.floor((interValTime / 60) % 60)var second = interValTime % 60// 3. 设置内容hourElement.textContent = padLeft(hour)minuteElement.textContent = padLeft(minute)secondElement.textContent = padLeft(second)},1000)function padLeft(content, count, padStr) {count = count | 2padStr = padStr | '0'content = String(content)return content.padStart(count, padStr)}</script>
</body></html>

十一、JavaScript的事件处理

11.1 事件(Event)

  • Web页面需要经常和用户之间进行交互,而交互的过程中可能想要捕捉这个交互的过程
    • 比如用户点击了某个按钮、用户在输入框里面输入了某个文本、用户鼠标经过了某个位置
    • 浏览器需要搭建一条JavaScript代码和事件之间的桥梁,浏览器进行调用
    • 当某个事件发生时,让JavaScript可以相应(执行某个函数),所以需要针对事件编写处理程序(handler)
  • 事件监听
    • 事件监听方式一:在script中直接监听(很少使用)
      • js 代码和 html 代码混合
    • 事件监听方式二:DOM 属性,通过元素的on来监听事件
      • 获取元素对象,onclick属性
      • 不能调用多个函数,只有最后的函数会生效
    • 事件监听方式三:通过 EventTarget 中的 addEventListener 来监听
      • 获取元素对象
      • btnEl.addEventListener (“click”,fn1)

11.2 事件冒泡和事件捕获

  • 事件冒泡:默认情况下事件是从最内层的span向外依次传递的顺序
  • 事件捕获:从外层到内层(body -> span)
  • 如果都监听,那么会按照如下顺序来执行:
    • 捕获阶段(Capturing phase):事件(从 Window)向下走近元素
    • 目标阶段(Target phase):事件到达目标元素
    • 冒泡阶段(Bubbling phase):事件从元素上开始冒泡
  • 事实上,可以通过event对象来获取当前的阶段:
    • eventPhase
  • 开发中通常会使用事件冒泡

## 11.3 事件对象

  • 当一个事件发生时,就会有和这个事件相关的很多信息
    • 比如事件的类型是什么,点击的是哪一个元素,点击的位置是哪里等等相关的信息
    • 那么这些信息会被封装到一个Event对象中,这个对象由浏览器创建,称之为event对象
  • 该对象提供了想要的一些属性,以及可以通过该对象进行某些操作
  • 获取这个 event 对象
    • event 对象会在传入的事件处理(event handler)函数回调时,被系统传入
    • 可以在回调函数中拿到这个event对象

## 11.4 event 常见的属性和方法

  • 常见的属性

    • type:事件的类型
    • target:当前事件发生的元素
    • currentTarget:当前处理事件的元素(父元素)
      • 事件冒泡会有区别
    • eventPhase:事件所处的阶段
      • 捕获:1
      • 目标:2
      • 冒泡:3
    • offsetX、offsetY:事件发生在元素内的位置
    • clientX、clientY:事件发生在客户端内的位置(可见的视口)
    • pageX、pageY:事件发生在客户端相对于document的位置(文档)
    • screenX、screenY:事件发生相对于屏幕的位置
  • 常见的方法

    • preventDefault:取消事件的默认行为
      var aEl = document.querySelector("a")aEl.onclick = function(event){event.preventDefault()}
    
    • stopPropagation:阻止事件的进一步传递(冒泡或者捕获都可以阻止)

11.5 事件处理中的this

  • this指向谁跟浏览器怎么调用有关
    • 绑定到谁身上就是指向谁
    • 绑定到处理的元素 currentTarget

11.6 EventTarget类

  • 所有的节点、元素都继承自EventTarget
    • Window也继承自EventTarget
  • EventTarget
    • EventTarget是一个DOM接口,主要用于添加、删除、派发Event事件
    • 可以实现类似于事件总线的效果
  • EventTarget常见的方法
    • addEventListener:注册某个事件类型以及事件处理函数
    • removeEventListener:移除某个事件类型以及事件处理函数
      • 移除要移除之前对应加进去的函数
    • dispatchEvent:派发某个事件类型到 EventTarget 上

11.7 事件委托

  • 利用事件的冒泡机制,以及事件对象中可以准确获知触发事件的元素机制(e.target),将子元素事件委托给父元素处理的现象
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.active {color: red;font-size: 20px;}</style>
</head><body><ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li></ul><script>// 1.每一个li都监听自己的点击,并且有自己的处理函数 var liEls = document.querySelectorAll("li")for (const liEl of liEls) {liEl.onclick = function (event) {event.currentTarget.classList.add('active')console.log("点击li");}}// 2. 统一在ul中进行监听var ulEl = document.querySelector("ul")ulEl.onclick = function (event) {event.target.classList.add('active')console.log("点击li");}// 3. 点击li变成active,其他取消activevar ulEl = document.querySelector("ul")// 3.1 变量记录的方式var activeLiEl = nullulEl.onclick = function (event) {// 边界判断if (activeLiEl && event.target !== ulEl) {activeLiEl.classList.remove("active")}// 3.2 给点击的元素添加activeif (event.target !== ulEl) {event.target.classList.add('active')}console.log("点击li");// 3.3 记录最新的active对应的liactiveLiEl = event.target}</script>
</body></html>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><div class="box"><button data-action="remove">移除</button><button data-action="new">新建</button><button data-action="search">搜索</button></div><script>var boxEl = document.querySelector(".box")boxEl.onclick = function (event) {var btnEl = event.targetvar action = btnEl.dataset.actionswitch (action) {case "remove":console.log("click remove");breakcase "new":console.log("click new");breakcase "search":console.log("click search");break}}</script>
</body></html>

11.8 常见的鼠标事件

  • click:当用户点击某个对象时调用的事件
  • contextmenu:在用户点击鼠标右键打开上下文菜单时触发
  • dblclick:当用户双击某个对象时调用的事件
  • mousedown :鼠标按钮被按下
  • mouseup:鼠标按键被松开
  • mousemove :鼠标被移动
  • mouseover :鼠标移到某元素之上(支持冒泡)
  • mouseout :鼠标从某元素移开(支持冒泡)
  • mouseenter :当鼠标指针移动到元素上时触发(不支持冒泡)
  • mouseleave :当鼠标指针移出元素时触发(不支持冒泡)

11.9 mouseover 和 mouseenter 的区别

  • mouseenter 和 mouseleave
    • 不支持冒泡
    • 进入子元素依然属于在该元素内,没有任何反应
  • mouseover和mouseout
    • 支持冒泡
    • 进入元素的子元素时
      • 先调用父元素的mouseout
      • 再调用子元素的mouseover
      • 因为支持冒泡,所以会将mouseover传递到父元素中
  • 应用
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box {display: flex;width: 300px;height: 300px;background-color: aquamarine;}button {flex: 1;height: 40px;}</style>
</head><body><div class="box"><button>删除</button><button>新增</button><button>搜索</button></div><script>// 方案一:监听的本身就是button元素// var btnEls = document.querySelectorAll('button')// for (var i = 0; i < btnEls.length; i++) {//   btnEls[i].onmouseenter = function (event) {//     console.log(event.target.textContent);//   }// }// 方案二:事件委托(只给父元素绑定一个元素)var boxEl = document.querySelector(".box")boxEl.onmouseover = function (event) {if (event.target.tagName === 'BUTTON')console.log(event.target.textContent);}</script>
</body></html>

11.10 常见的键盘事件

  • onkeydown :某个键盘按键被按下,down事件先发生

  • onkeypress :某个键盘按键被按下,press 发生在文本被输入

  • onkeyup :某个键盘按键被松开,up发生在文本输入完成

  • 可以通过 key 和 code 来区分按下的键

    • event.code:“按键代码”(

    “KeyA”,“ArrowLeft” 等),特定于键盘上按键的物理位置,不区分大小写

    • event.key:字符(“A”,“a” 等),对于非字符(non-character)的按键,通常具有与 code 相同的值
    • keyCode 已经遗弃
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><input type="text"><button>button</button>
</body>
<script>const btnEl = document.querySelector('button')const inputEl = document.querySelector('input')btnEl.onclick = function () {console.log("sousuo");}btnEl.onkeyup = function (event) {if (event.code == 'Enter') {console.log("search");}}// 按下s,搜索自动获取焦点document.onkeyup = function (event) {console.log("document键盘事件", event.key, event.code);if (event.code === 'KeyS') {inputEl.focus()}}
</script></html>

11.11 常见的表单事件

  • onchange 该事件在表单元素的内容改变时触发( <input>, , , 和 )

  • oninput :元素获取用户输入时触发

  • onfocus :元素获取焦点时触发

  • onblur :元素失去焦点时触发

  • onreset :表单重置时触发

  • onsubmit :表单提交时触发

11.12 文档加载事件

  • DOMContentLoaded:浏览器已完全加载 HTML,并构建了 DOM 树,但像 和样式表之类的外部资源可能尚未加载完成
  • load:浏览器不仅加载完成了 HTML,还加载完成了所有外部资源:图片,样式等

十二、DOM 相关

12.1 window 定时器方法

  • 计划调用:并不想立即执行一个函数,而是等待特定一段时间之后再执行
  • setTimeout 允许将函数推迟到一段时间间隔之后再执行
  • setInterval 允许重复运行一个函数,从一段时间间隔之后开始运行,之后以该时间间隔连续重复运行该函数
  • clearTimeout:取消setTimeout的定时器
  • clearInterval:取消setInterval的定时器

12.2 setTimeout 的使用

  • setTimeout的语法如下
    • func|code:想要执行的函数或代码字符串。
      • 一般传入的都是函数,由于某些历史原因,支持传入代码字符串,但是不建议这样做
    • delay:执行前的延时,以毫秒为单位(1000 毫秒 = 1 秒),默认值是 0
    • arg1,arg2…:要传入被执行函数(或代码字符串)的参数列表
  • clearTimeout方法
    • setTimeout 在调用时会返回一个“定时器标识符(timer identifier)”,可以使用它来取消执行

12.3 setInterval的使用

  • setInterval 方法和 setTimeout 的语法相同
    • 所有参数的意义也是相同的
    • 不过与 setTimeout 只执行一次不同,setInterval 是每间隔给定的时间周期性执行
  • clearInterval方法
    • etInterval也会返回一个“定时器标识符(timer identifier)”,可以通过clearInterval来取消这个定时器

十三、BOM

13.1 认识 BOM

  • BOM:浏览器对象模型
    • 由浏览器提供的用于处理文档之外的所有内容的其他对象
    • navigator、location、history
  • js 有一个非常重要的运行环境就是浏览器
    • BOM是链接js脚本与浏览器窗口的桥梁
  • BOM 主要包括以下对象模型
    • window
    • location
    • history
    • navigator
    • screen

13.2 window 对象

  • 全局对象
    • Node :global
    • 浏览器:window 对象
  • 浏览器窗口对象
  • 放在 window 对象上的所有属性都可以被访问
  • 使用 var 定义的变量会被添加到window对象中
  • 默认提供了全局的函数和类:setTimeout、Math、Date、Object
  • 作用
    • 包含大量的属性:console、location、history、localStorage(60+)
    • 包含大量的方法:alert、close、scrollTo、open(40+)
    • 包含大量的事件:focus、blur、load、hashchange(30+)
    • 包含大量从EventTarget继承过来的方法

13.3 location 对象

  • 用于表示 window 上当前链接到的 URL 信息
  • 常见的属性
 // 完整的URLconsole.log(location.href);// 获取URL信息console.log(location.hostname);console.log(location.host);console.log(location.protocol);console.log(location.pathname);console.log(location.search);console.log(location.hash);
  • 常见的方法
    • assign:赋值一个新的URL,并且跳转到新的URL 上
    • replace:替换,新的网页替换原来的网页
    • reload:重新加载这个网页

13.4 URLSearchParams

  • get方法:获取参数的值
  • set方法:设置一个搜索参数和值
  • append:追加一个搜索参数和值
  • has:判断是否有某个搜索参数
  • 中文会进行编码

13.5 history

  • 前端路由的核心:修改 url ,但是页面不刷新
    • 修改 hash 值
    • 修改 history
  • 属性
    • history.length
    • history.state
  • 方法
    • 添加新的历史:pushState(state,“,”/lili")
    • 返回历史:back()
    • 前进历史:forward()
    • 跳转层级:go(number)
    • 替换历史:replaceState()

13.6 navigator

  • 表示用户代理的状态和标识等信息
  • 属性
    • userAgent
    • vendor

13.7 screen

  • 获取屏幕对应的像素

十四、JSON

14.1 认识 Json

  • 是一种非常重要的数据格式,并不是编程语言,可以在服务器和客户端之间传递

    • 服务器基本上是以 json 格式给你数据
    • 基本上传递都是 json
  • 全称是 JavaScript Object Notation( js 对象符号)

  • 一种轻量级资料交换格式,算是 js 的一个子集

  • 目前已经独立于编程呢个语言,可以在各个编程语言中使用

  • 在 js 中可以直接使用

  • 其他数据交换格式,使用什么数据格式是一种架构

    • XML:在解析、传输等方面弱于 JSON
    • Protobuf:有可能替换 json
      • 即时通信
  • 应用场景

    • 网络数据的传输JSON 数据
    • 项目的某些配置文件
    • 非关系型数据库 NoSQL 将 json 作为存储格式

14.2 JSON 基本语法

  • 不能在 json 文件中写注释
  • 数据格式(双引号,不支持单引号)
    • 简单值
    • 数组
    • 对象

14.3 JSON 的序列化和反序列化

  • 希望将一个对象保存在 localStorage 中,如果直接将对象塞到里面去只能看到 object

    • 需要进行序列化JSON.stringify():将 obj 对象转成字符串再塞进来

      • 在转换的过程当中改值:replacer
      • JSON.stringify(obj,function(key,value){if(key==="lili" return "miao")})
      • space:转换输出格式,前面留几个空格
      • 自定义toJSON方法
    • 需要进行反序列化JSON.parse():将字符串转成 obj 对象拿到结果

      • 在解析的过程中进行修改
      • JSON.parse(item,function(key,value){if(key==="age")return value+2})
      var obj = {name: "lili",age: 99}// 1. 将 obj 对象进行序列化var objJSONString = JSON.stringify(obj)// 2. 将对象存储到LocalStoragelocalStorage.setItem("info", objJSONString)console.log(localStorage.getItem("info"));var item = localStorage.getItem("info")// 3. 将字符串转回对象(反序列化)var newObj = JSON.parse(item)
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/242384.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RT-Thread 瑞萨 智能家居网络开发:RA6M3 HMI Board 以太网+GUI技术实践

不用放大了&#xff0c; 我在包里找到张不小的…… 以太网HMI线下培训-环境准备 这是社群的文档&#xff1a;【腾讯文档】以太网线下培训&#xff08;HMI-Board&#xff09; https://docs.qq.com/doc/DY0FIWFVuTEpORlNn 先介绍周六的培训是啥&#xff0c;然后再介绍一下要准…

GPT应用开发:编写插件获取实时天气信息

欢迎阅读本系列文章&#xff01;我将带你一起探索如何利用OpenAI API开发GPT应用。无论你是编程新手还是资深开发者&#xff0c;都能在这里获得灵感和收获。 本文&#xff0c;我们将继续展示聊天API中插件的使用方法&#xff0c;让你能够轻松驾驭这个强大的工具。 插件运行效…

Oracle21C + PLSQL Developer 15 + Oracle客户端21安装配置完整图文版

一、Oracle21C PLSQL Developer 15 Oracle客户端文件下载 1、Oracl21C下载地址&#xff1a;Database Software Downloads | Oracle 中国 2、 PLSQL Developer 15下载地址&#xff1a;Registered download PL/SQL Developer - Allround Automations 3、 Oracle 客户端下载地址…

51单片机中断

1、什么是中断&#xff1f; CPU在处理某一事件A时&#xff0c;发生了另一事件B请求CPU迅速去处理&#xff08;中断发生&#xff09;&#xff1b; CPU暂时中断当前的工作&#xff0c;转去处理事件B&#xff08;中断响应和中断服务&#xff09;&#xff1b; 待CPU将事件B处理完…

百度搜索Push个性化:新的突破

作者 | 通用搜索产品研发组 导读 本文简单介绍了百度搜索Push个性化的发展过程&#xff0c;揭示了面临的困境和挑战&#xff1a;如何筛选优质物料、如何对用户精准推荐等。我们实施了一系列策略方法进行突破&#xff0c;提出核心的解决思路和切实可行的落地方案。提升了搜索DAU…

Servlet系列两种创建方式

一、使用web.xml的方式配置&#xff08;Servlet2.5之前使用&#xff09; 在早期版本的Java EE中&#xff0c;可以使用XML配置文件来定义Servlet。在web.xml文件中&#xff0c;可以定义Servlet的名称、类名、初始化参数等。然后&#xff0c;在Java代码中实现Servlet接口&#x…

MacOS X 安装免费的 LaTex 环境

最近把工作终端一步步迁移到Mac上来了&#xff0c;搭了个 Latex的环境&#xff0c;跟windows上一样好用。 选择了 Mactex 做编译&#xff0c;用 Texmaker 做编辑&#xff1b; 1. 下载与安装 1.1 Mactex 下载安装 MacOS 安装和示例 LaTex 的编译器 与 编辑器 编译器使用免费…

c++ mysql数据库编程(linux系统)

ubuntu下mysql数据库的安装 ubuntu安装mysql&#xff08;图文详解&#xff09;-CSDN博客https://blog.csdn.net/qq_58158950/article/details/135667062?spm1001.2014.3001.5501 项目目录结构 数据库及表结构 public.h //打印错误信息 #ifndef PUBLIC_h #define PUBLIC_H…

[Linux 进程(四)] 再谈环境变量,程序地址空间初识

文章目录 1、前言2、环境变量2.1 main函数第三个参数 -- 环境参数表2.2 本地环境变量和env中的环境变量2.3 配置文件与环境变量的全局性2.4 内建命令与常规命令2.5 环境变量相关的命令 3、程序地址空间 1、前言 上一篇我们讲了环境变量&#xff0c;如果有不明白的先读一下上一…

maven 基本知识/1.17

maven ●maven是一个基于项目对象模型(pom)的项目管理工具&#xff0c;帮助管理人员自动化构建、测试和部署项目 ●pom是一个xml文件&#xff0c;包含项目的元数据&#xff0c;如项目的坐标&#xff08;GroupId,artifactId,version )、项目的依赖关系、构建过程 ●生命周期&…

list列表可编辑状态

有时候list需要修改或选择属性,mfc自带的只能显示内容,基本上是不可以修改,为了实现这个功能需求,需要完成一下步骤转换. 第一步记录选择的单元格. 第二步创建一个编辑框CComboBox对象, 设置字体,窗口属性. 第三步获取选中单元格的位置信息. 第四步获取单元格内容信息. 第五步…

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖微信小程序端(十三)

地址簿相关功能 1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计1.1.3 表设计 1.2 代码实现1.2.1 Mapper层1.2.2 Service层1.2.3 Controller层 1.1 需求分析和设计 1.1.1 产品原型 地址簿&#xff0c;指的是消费者用户的地址信息&#xff0c;用户登录成功后可以维护自己的地…

Kafka Console Client 的 Consumer Group

以往使用 kafka-console-consumer.sh 消费 Kafka 消息时并没有太在意过 Consumer Group&#xff0c;在命令行中也不会使用 --group 参数&#xff0c;本文针对 Kafka Console Client 命令行中的 Consumer Group 进行一次统一说明。 1. 如不设置 --group 参数会自动生成一个 Con…

JVM:Java类加载机制

Java类加载机制的全过程&#xff1a; 加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的&#xff0c;类型的加载过程必须按照这种顺序按部就班地开始&#xff0c;而解析阶段则不一定&#xff1a;它在某些情况下可以在初始化阶段之后再开始&#xff0c; 这是为了支持Java…

Java编程练习之this关键字(2)

this关键字除了可以调用成员变量或成员方法之外&#xff0c;还可以作为方法的返回值。 示例&#xff1a;创建一个类文件&#xff0c;在类中定义Book类型的方法&#xff0c;并通过this关键字进行返回。 public class Book{ public Book getBook(){ return this; } } 在getB…

宿舍人走断电系统的重要性

宿舍人走断电系统石家庄光大远通电气有限公司公寓智能用电管理系统适合集体公寓、学生宿舍等应用场景&#xff0c;具备多种性能&#xff0c;满足多种形式需求&#xff0c;解决方案面向实际&#xff1b;集计量控制、违规用电管理、用电过程管理等功能于一体。系统采用集中控制&a…

大创项目推荐 深度学习验证码识别 - 机器视觉 python opencv

文章目录 0 前言1 项目简介2 验证码识别步骤2.1 灰度处理&二值化2.2 去除边框2.3 图像降噪2.4 字符切割2.5 识别 3 基于tensorflow的验证码识别3.1 数据集3.2 基于tf的神经网络训练代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x…

使用Scrapy 爬取“http://tuijian.hao123.com/”网页中左上角“娱乐”、“体育”、“财经”、“科技”、历史等名称和URL

一、网页信息 二、检查网页&#xff0c;找出目标内容 三、根据网页格式写正常爬虫代码 from bs4 import BeautifulSoup import requestsheaders {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/53…

C#操作pdf之使用itext实现01-生成一个简单的table

创建.net 8控制台项目 安装itext <PackageReference Include"itext" Version"8.0.2" /><PackageReference Include"itext.bouncy-castle-adapter" Version"8.0.2" /><PackageReference Include"itext.bouncy-cast…

【从零开始学习Java重要知识 | 第三篇】暴打ReentrantLock底层源码

目录 前言&#xff1a; 前置知识&#xff1a; 什么是公平锁与非公平锁&#xff1f; 尝试自己构造一把锁&#xff1a; ReentrantLock源码&#xff1a; 加锁&#xff1a; 解锁&#xff1a; 总结&#xff1a; 前言&#xff1a; 在并发编程中&#xff0c;线程安全是一个重…