欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Js 运行机制与字符串,数组常用 API

程序员文章站 2022-05-25 09:09:49
...

Js 运行机制与字符串,数组常用 API

事件冒泡与事件委托/代理

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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. <ul class="list">
  11. <li class="item">item1</li>
  12. <li class="item">item2</li>
  13. <li class="item">item3</li>
  14. <li class="item">item4</li>
  15. <li class="item">item5</li>
  16. </ul>
  17. <script>
  18. // 先给第一个li添加一个点击事件
  19. document.querySelector(".list").firstElementChild.onclick = () =>
  20. console.log(event.currentTarget, event.target); //输出内容:<li class="item"> <li class="item">
  21. // 再给他的父级ul添加一个onclick事件
  22. document.querySelector(".list").onclick = () =>
  23. console.log(event.currentTarget, event.target); //输出内容:<ul class="list"> <li class="item">
  24. // 以上我只点击了一次,触发了li上的onclick事件,但是,他的父级ul上添加的点击事件也被触发了,这就是事件冒泡,我们看到li的父级ul事件输出的内容currentTarget(事件绑定者/事件主题是他本身),但是target(事件的触发者确实子集li),这个现象也叫事件委托/代理
  25. </script>
  26. </body>
  27. </html>

表单事件

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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. <form action="" method="post" id="login">
  11. <label class="title">用户登录</label>
  12. <label for="email">邮箱:</label>
  13. <input type="email" id="email" name="email" value="" autofocus />
  14. <label for="password">密码:</label>
  15. <input type="password" id="password" name="password" />
  16. <button name="submit" ">登录</button>
  17. </form>
  18. <script>
  19. const login=document.forms.login
  20. const email=document.forms.login.email
  21. const password=document.forms.login.password
  22. const button=document.querySelector('#login > button')
  23. button.onclick=()=>event.preventDefault();
  24. email.onfocus=()=>{
  25. email.style.color='black';
  26. email.placeholder='';
  27. }
  28. password.onfocus=()=>{
  29. password.style.color='black';
  30. password.placeholder='';
  31. }
  32. email.onblur=()=>{
  33. if(email.value.length===0){
  34. email.style.color='red';
  35. email.placeholder='请填写邮箱';
  36. setTimeout(()=>email.focus(),2000)
  37. }
  38. else{
  39. password.focus()
  40. }
  41. }
  42. password.onblur=()=>{
  43. if(password.value.length===0){
  44. password.style.color='red';
  45. password.placeholder='请填写密码';
  46. setTimeout(()=>password.focus(),2000)
  47. }
  48. }
  49. </script>
  50. </body>
  51. </html>

js 运行机制:单线程+事件循环

  • 单线程
    1.单线程:主线程
    同步:代码的书写顺序与执行顺序一致,写在前面先执行
    和 html 的文档流有点像
  1. <script>
  2. console.log(1);
  3. console.log(2);
  4. console.log(3);
  5. </script>

就像这个代码一样,先输出 1,再输出 2,再输出 3

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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>Document</title>
  8. </head>
  9. <body>
  10. <!-- <input type="text" placeholder="同步" onkeydown="console.log(this.value)" /> -->
  11. <!-- 慢半拍 -->
  12. <!-- 分析为什么第一次获取不到?
  13. 1. 当按下某个键时, 它会触发keydown事件,事件循环将事件方法从任务队列添加到主线中,并立即调用,即console.log立即执行
  14. 2. 但是此时这个键对应的值,例如1, 还没有被DOM渲染到input输入框中,所以console.log获取不到值,或获取一个空值
  15. 3. 因为"按下1" 和 "显示1" 是2步操作,而console.log是在第1步结束后一瞬间执行,而值还没被显示到input框中
  16. 4. 所以, console.log()执行时机,是在"按下"与"显示"之间,所以无法获取到用户输入的内容或获取到一个空值
  17. 5. 为什么第2次按下时,console.log()可以获取到了呢?
  18. 6. 是因为当用户再次按下时, console.log()立即执行,此时input中已经有了内容,就是上一次的输入内容,所以就正常输出了 -->
  19. <!-- 解决方案也很简单,让console.log()异步执行即可,等到input框中的内容渲染完成之后再执行 -->
  20. <!-- 必知内容:
  21. 1. DOM渲染是同步任务, 这里的dom渲染,是指将内容显示到input框中
  22. 2. DOM事件是异步任务, 使用keydown
  23. 3. 异步必须在同步完成后执行
  24. -->
  25. <!-- 现在简单了, 将console.log异步调用就可以,直接放在setTimeout中就可以,将延迟设置为0 -->
  26. <!-- 因为setTimeout是异步任务,完毕才会进一定会等主线程中的同步任务执行入主线程,转为同步任务执行
  27. 而此时, dom渲染已完成, input框中已经有了数据,所以console.log()就正确的, 同步的获取到了数据
  28. 完美解决了"慢半拍"的问题 -->
  29. <input
  30. type="text"
  31. onkeydown="setTimeout(()=>console.log(this.value),10)"
  32. placeholder="异步"
  33. />
  34. <!-- 解决方案 -->
  35. <input type="text" oninput="console.log(this.value)" placeholder="input" />
  36. <!-- input = keydown + setTimeout -->
  37. </body>
  38. </html>

字符串中常用的 api

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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>字符中常用api</title>
  8. </head>
  9. <body>
  10. <script>
  11. let str = "";
  12. // 索引从0开始:
  13. // [0->p,1->p,2->p,3->中,4->文, 5->网]
  14. // index = [0, str.length-1]
  15. // 1. length 长度
  16. console.log(str.length);
  17. // 2. charAt: 索引->元素
  18. console.log(str.charAt(3));
  19. console.log(str[3]);
  20. // 3. indexOf: 字符->索引
  21. console.log(str.indexOf("中"));
  22. // 4. search: indexOf一样,但支持正则等
  23. console.log(str.search("文"));
  24. // 5. concat: 字符串拼装
  25. console.log(str.concat("(", "php.cn", ")"));
  26. // 直接用"+", 或者`模板字面量` 更方便
  27. // 6. replace: 替换
  28. console.log(str.replace("中文网", ".cn"));
  29. // str = "php";
  30. console.log(str);
  31. // 7. slice: 子串, 忽略结束索引的值
  32. console.log(str.slice(0, 3));
  33. // 8. substr: 子串, 只需要知道取多少个
  34. console.log(str.substr(0, 3));
  35. console.log(str.substr(3, 3));
  36. // -1最后一个, -2向前一个
  37. console.log(str.substr(-3, 3)); // 中文网
  38. // 9. split: str->array
  39. console.log(str.split(""));
  40. console.log(str.split("", 3));
  41. // 10. toLowerCase, toUpperCase 大小写转换
  42. console.log(str.toLowerCase());
  43. console.log(str.toUpperCase());
  44. // 11. 与html相关
  45. console.log(`<a href="https://php.cn">${str}</a>`);
  46. console.log(str.link("https://php.cn"));
  47. console.log(str.bold());
  48. console.log(str.big());
  49. console.log(str.anchor("url"));
  50. </script>
  51. </body>
  52. </html>

常用数组 api

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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>数组常用api-1</title>
  8. </head>
  9. <body>
  10. <script>
  11. // 字面量
  12. let arr = [
  13. 1,
  14. 2,
  15. "a",
  16. "b",
  17. true,
  18. { x: 1, y: 2 },
  19. [1, 2, 3],
  20. function () {},
  21. ];
  22. // console.log(arr);
  23. // ...rest
  24. arr = [4, 5, 6];
  25. let arr1 = [...arr];
  26. console.log(arr1);
  27. arr = [1, 2, 3, ...arr, 7, 8, 9];
  28. console.log(arr);
  29. // Array.of
  30. // 原始数据有可能来自一个外部请求api或文件,而这个原始数据就是数组
  31. let a = [1, 2, 3, 4, 5, 6];
  32. // 经过一些其它操作,例如过滤,再重新生成
  33. arr = Array.of(...a);
  34. console.log(arr);
  35. // Array.from
  36. const likeArr = {
  37. 0: "red",
  38. 1: "blue",
  39. 2: "green",
  40. length: 3,
  41. };
  42. console.log(likeArr);
  43. console.log(Array.from(likeArr));
  44. </script>
  45. </body>
  46. </html>
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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>数组常用api-2</title>
  8. </head>
  9. <body>
  10. <script>
  11. // push,pop, unshift,shift,delete
  12. let arr = [];
  13. // 1. 尾部增删
  14. console.log(arr.push(10));
  15. // 从左到右进入
  16. console.log(arr.push(20, 30));
  17. console.log(arr);
  18. // 尾部删除
  19. console.log(arr.pop());
  20. console.log(arr.pop());
  21. console.log(arr.pop());
  22. // 2. 头部增删
  23. console.log(arr.unshift(10));
  24. // 从右到左进入
  25. console.log(arr.unshift(30, 20));
  26. console.log(arr);
  27. console.log(arr.shift());
  28. console.log(arr.shift());
  29. console.log(arr.shift());
  30. console.log(arr);
  31. arr = [1, 2, 3, 4, 5];
  32. //删除指定索引位置的值,赋null值,但是实际数组长度不变,不影响数组的遍历
  33. delete arr[1];
  34. console.log(arr);
  35. console.log(arr.length);
  36. //可通过修改数组的长度来删减数组内的成员
  37. arr.length = 4;
  38. console.log(arr);
  39. </script>
  40. </body>
  41. </html>
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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>数组常用api-3</title>
  8. </head>
  9. <body>
  10. <script>
  11. // 迭代方法, 遍历元素
  12. // 1. forEach,map
  13. // 2. every, some
  14. // 3. filter, find, findIndex
  15. // 4. reduce
  16. // 1. forEach((item,index,arr)=>{...}), 每个元素逐个调用回调处理
  17. let arr = [1, 2, 3, 4, 5];
  18. let res = arr.forEach(function (item, index, arr) {
  19. // 三个参数中, 只有第一个 item是必须的
  20. console.log(item, index, arr);
  21. // dom
  22. document.body.append(item);
  23. });
  24. // 没有返回值
  25. console.log(res);
  26. // 2. map: 参数与功能 与forEach一样,只不过有返回值
  27. res = arr.map((item) => item * 2);
  28. console.log(res);
  29. // 3. every, some: 断言函数,返回true,false
  30. // every: 数组成员全部满足条件,则返回 true , 否则 false 与
  31. console.log(arr.every((item) => item >= 0));
  32. console.log(arr.every((item) => item >= 3));
  33. // some: 数组成员中只要有一个满足条件,就返回 true, 否则 false, 或
  34. console.log(arr.some((item) => item >= 3));
  35. console.log(arr.some((item) => item >= 10));
  36. // 4. filter: 返回数组中的满足条件的元素组成的新数组
  37. console.log(arr.filter((item) => item >= 3)); // [3,4,5]
  38. // arr.filter(item => item >= 3)[0] -> find
  39. console.log(arr.find((item) => item >= 3));
  40. console.log(arr.findIndex((item) => item >= 3));
  41. // 5. reduce: 归并
  42. res = arr.reduce(function (acc, cur, index, arr) {
  43. // 查看reduce的执行过程
  44. console.log("acc=", acc, "cur=", cur, "index=", index, "arr=", arr);
  45. // 最终结果用 acc 返回, acc累加器
  46. return acc + cur;
  47. }, 5);
  48. console.log(res);
  49. </script>
  50. </body>
  51. </html>
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  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>数组常用api-4</title>
  8. </head>
  9. <body>
  10. <script>
  11. // 1. sort
  12. let arr = [1, 10, 20, 6];
  13. console.log(arr.sort());
  14. // asc
  15. console.log(arr.sort((a, b) => a - b));
  16. // desc
  17. console.log(arr.sort((a, b) => b - a));
  18. // 2. join: array -> string
  19. // string.split string -> array
  20. arr = ["red", "green", "blue"];
  21. console.log(arr.join());
  22. console.log(arr.join("-"));
  23. // 3. slice: 子元素
  24. arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  25. console.log(arr.slice(2, 5));
  26. console.log(arr.slice(2));
  27. console.log(arr.slice(-6, -3));
  28. // 4. splce: 删除, 新增, 替换
  29. // delete
  30. console.log(arr);
  31. console.log(arr.splice(1, 2));
  32. console.log(arr);
  33. // update
  34. console.log(arr.splice(1, 2, "a", "b"));
  35. console.log(arr);
  36. // insert
  37. console.log(arr.splice(1, 0, "red", "green"));
  38. console.log(arr);
  39. let data = ["red", "green", "blue"];
  40. console.log(arr.splice(1, 0, ...data));
  41. console.log(arr);
  42. </script>
  43. </body>
  44. </html>