小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2025-10-05 / 1 阅读
0
0

用恋爱故事秒懂JavaScript:DOM操作与异步编程指南

querySelectorAll()

querySelectorAll() 方法返回文档中匹配指定 CSS 选择器的所有元素,返回 NodeList 对象。

NodeList 对象表示节点的集合。可以通过索引访问,索引值从 0 开始。

提示: 你可以使用 NodeList 对象的 length 属性来获取匹配选择器的元素属性,然后你可以遍历所有元素,从而获取你想要的信息。

document. getElementById("")

const elem = document.getElementById("para");

elem.style.color = "blue";

注意事项

ID 值必须在整个文档中保持唯一。

document.querySelector('')

是 JavaScript 中用于选择 DOM 元素的强大方法,它返回与指定 CSS 选择器匹配的第一个元素。如果没有匹配项,则返回 null

var showValueElement = document.querySelector('.showvalue');
console.log(showValueElement); // 输出匹配的 DOM 元素或 null
  • 仅返回第一个匹配项:如果页面中有多个 .showvalue 类的元素,querySelector 只会返回第一个。
  • 支持复杂选择器:可以使用任意有效的 CSS 选择器

addEventListener()

更多资料:浏览器事件监听及 addEventListener 相关的实例方法本文主要介绍浏览器事件的传播模型以及 addEvent - 掘金

我关心你,我需要默默监视你的一举一动

const 我们的聊天 = document.querySelector('#爱情聊天框');

我们的聊天.addEventListener('input', (e) => {
  if (e.target.value.includes('想你')) {
    console.log('🎉 捕捉到思念信号!立即回复!');
    秒回消息('我也想你~💕');
      e.stopPropagation(); // stopPropagation方法只会阻止事件的传播,不会阻止该事件触发<p>节点的其他click事件的监听函数。也就是说,不是彻底取消click事件。如果想要彻底取消该事件,不再触发后面所有click的监听函数,可以使用stopImmediatePropagation方法。
     // e.stopImmediatePropagation();
      //上面代码中,stopImmediatePropagation方法可以彻底取消这个事件,使得后面绑定的所有click监听函数都不再触发。所以,只会输出1,不会输出2。
  }
});

我们的聊天.addEventListener('focus', () => {
  console.log('👀 你点开聊天框了!是在想我吗?');
});

鼠标事件

  • click: 当用户点击某个对象时触发。
  • dblclick: 当用户双击某个对象时触发。
  • mousedown: 鼠标按钮被按下时触发。
  • mouseup: 鼠标按钮被松开时触发。
  • mousemove: 鼠标移动时触发。
  • mouseover: 鼠标移到某元素上时触发。
  • mouseout: 鼠标从某元素移开时触发。

键盘事件(document)

  • keydown: 某个键盘按键被按下时触发。
  • keypress: 某个键盘按键被按下并松开时触发。
  • keyup: 某个键盘按键被松开时触发。

框架/对象事件(document)

  • load: 页面或图像加载完成时触发。
  • unload: 用户退出页面时触发。
  • resize: 窗口或框架被重新调整大小时触发。
  • scroll: 文档被滚动时触发。

表单事件

  • blur: 元素失去焦点时触发。
  • focus: 元素获得焦点时触发。
  • change: 表单元素的内容改变时触发。
  • submit: 表单提交时触发。

剪贴板事件

  • copy: 用户拷贝元素内容时触发。
  • cut: 用户剪切元素内容时触发。
  • paste: 用户粘贴元素内容时触发。

多媒体事件

  • play: 视频/音频开始播放时触发。
  • pause: 视频/音频暂停时触发。
  • ended: 视频/音频播放结束时触发。

动画事件

  • animationstart: CSS 动画开始播放时触发。
  • animationend: CSS 动画结束播放时触发。
  • animationiteration: CSS 动画重复播放时触发。

过渡事件

  • transitionend: CSS 完成过渡后触发。

其他事件

  • message: 从对象接收到消息时触发(如 WebSocket, Web Worker)。
  • online: 浏览器开始在线工作时触发。
  • offline: 浏览器开始离线工作时触发。

我们分手了我受够你的监视了

const 我们的聊天 = document.querySelector('#爱情聊天框');

我们的聊天.addEventListener('input', (e) => {
  if (e.target.value.includes('想你')) {
    console.log('🎉 捕捉到思念信号!立即回复!');
    秒回消息('我也想你~💕');
  }
});

我们的聊天.removeEventListener()

该方法用来移除 addEventListener()方法添加的事件监听函数。

event.preventDefault()阻止默认事件

需要先监听事件,然后阻止

示例

阻止链接跳转

以下示例展示了如何阻止点击链接时的默认跳转行为:

document.getElementById("myAnchor").addEventListener("click", function(event) {
event.preventDefault();
});

异步编程和同步编程

纯爱战士和海王的恋爱方式

核心概念对比

编程方式 恋爱方式 特点
同步编程 直球恋爱 一步接一步,不能分心
异步编程 海王恋爱 同时发展多条线,效率高

同步编程 - 纯爱战士的恋爱

特点:一次只爱一个人

function 同步恋爱() {
  console.log("1. 🤵 遇见心动的人");
  console.log("2. 💕 疯狂追求中...");
  console.log("3. 🎉 终于在一起了!");
  console.log("4. 🏠 开始考虑买房结婚");
  console.log("5. 👶 生娃养娃");
  
  return "完成人生大事!";
}

const 人生进度 = 同步恋爱();
// 必须等上一步完成才能进行下一步
// 就像:不追到手绝不看别人一眼!

同步恋爱的日常

function 约会流程() {
  const 早餐 = "做爱心早餐🍳"; // 等早餐做完
  const 接送 = "接送上下班🚗"; // 等接送完成  
  const 电影 = "看浪漫电影🎬"; // 等电影结束
  const 晚安 = "说甜蜜晚安🌙"; // 等晚安说完
  
  return `${早餐} → ${接送} → ${电影} → ${晚安}`;
}
// 💡 特点:专心致志,但效率低下

异步编程 - 时间管理大师的恋爱

特点:多条线同时发展

async function 异步恋爱() {
  console.log("🎯 开始多线操作!");
  
  // 同时发展多个潜在对象
  const 小红 = 追求女生("小红").then(结果 => {
    console.log("📱 和小红的进展:", 结果);
  });
  
  const 小美 = 追求女生("小美").then(结果 => {
    console.log("💻 和小美的进展:", 结果);
  });
  
  const 小芳 = 追求女生("小芳").then(结果 => {
    console.log("📞 和小芳的进展:", 结果);
  });
  
  // 不等某个结果,继续做自己的事
  console.log("🏃 继续健身提升自己");
  console.log("💼 努力工作赚钱");
  console.log("🎮 打游戏放松心情");
  
  // 等所有结果出来
  const 所有结果 = await Promise.all([小红, 小美, 小芳]);
  console.log("🎊 最终战果:", 所有结果);
}

Promise (承诺)

形象解释:我承诺(Promise)和你找对象了,你需要等我(.then)

Promise的恋爱三部曲

// 我向你发出恋爱承诺
const 我们的关系 = new Promise((resolve, reject) => {
  if (你接受我) {
    resolve("我们在一起吧!💖"); // 表白成功
  } else {
    reject("你是个好人😭");     // 被发好人卡
  }
});

Pending - 爱情的暧昧期

const 我们的关系 = new Promise((resolve, reject) => {
  // 现在处于「暧昧期」- pending状态
  // 我还在等你回复,你既没说Yes也没说No
  // 这种悬而未决的状态就是pending!
});

.then 恋爱中的各种状态

我们的关系
  .then(结果 => {
    console.log(结果); // "我们在一起吧!💖"
    return "第一次约会🎉";
  })
  .then(约会结果 => {
    console.log(约会结果); // "第一次约会🎉"
    return "见家长👨•👩•👧";
  });

就像恋爱中的每一步进展,都是基于上一步的成功

分手处理 .catch()

我们的关系
  .then(结果 => {
    // 甜蜜的恋爱过程...
  })
  .catch(原因 => {
    console.log(原因); // "你是个好人😭"
    return "疗伤期💔";
  });

即使被拒绝,也要优雅地处理分手

最终都会执行 .finally()

我们的关系
  .then(结果 => {/* 恋爱过程 */})
  .catch(原因 => {/* 分手处理 */})
  .finally(() => {
    console.log("这段感情让我成长了🌱");
  });

Promise.all() = 集体相亲

我和多个人相亲,等待一个相亲的结果

const 相亲局 = Promise.all([我, 女朋友A,男朋友B,女朋友C]);

相亲局.then(大家都有对象了吗 => {
  console.log("都没对象,所有人都脱单成功!🎊");
});

要等所有人都找到对象才算成功

Promise.race() - 比赛谁先脱单

const 脱单竞赛 = Promise.race([我, 室友, 同事]);

脱单竞赛.then(最先脱单的人 => {
  console.log(`${最先脱单的人}最先脱单了!🏃•♂️`);
});

不管其他人,第一个脱单的就赢了

Promise概念 恋爱解释
new Promise() 发出恋爱邀请
pending 等待对方回复
fulfilled 表白成功,在一起
rejected 被拒绝,失恋
.then() 恋爱中的下一步
.catch() 分手后的处理
.finally() 无论成败,都有收获

爱情就像Promise,不是所有的承诺都能兑现,但每一段经历都值得珍惜~💝

async 函数

在函数声明前添加 async 关键字,表示该函数是异步的:

async function fetchData() {
 // 函数体
}

async 函数总是返回一个 Promise:
  • 如果返回值不是 Promise,会自动包装成 resolved Promise
  • 如果抛出异常,会返回 rejected Promise

await 表达式

await 只能在 async 函数内部使用:

async function fetchData() {
 const result = await somePromise;
 console.log(result);
}

await 会暂停 async 函数的执行,等待 Promise 完成:

  • 如果 Promise 被 resolve,返回 resolve 的值
  • 如果 Promise 被 reject,抛出错误(可以用 try/catch 捕获)

FetchApi

💘 Fetch API - 恋爱中的主动出击与等待回应

🎯 核心概念:恋爱中的请求与回应

// 像发出恋爱邀请一样发起请求
const 我的追求 = fetch('你的心', {
  method: 'GET_LOVE', // 求爱方式
  headers: {
    '诚意': '100%',
    '真心': '满满'
  }
});

🌟 Fetch 恋爱全流程

1. 鼓起勇气发出邀请 💌

async function 发起追求() {
  try {
    console.log("😊 深呼吸...准备发出恋爱邀请");
  
    const 回应 = await fetch('/表白', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/真心',
        'Authorization': 'Bearer 我的爱'
      },
      body: JSON.stringify({
        心意: "我喜欢你",
        期望: "请做我的女朋友",
        承诺: "我会好好珍惜你"
      })
    });
  
    return 回应;
  } catch (error) {
    console.log("😨 连邀请都没发出去:", error);
  }
}

2. 等待回应的煎熬阶段 ⏳

function 等待爱情回应() {
  const 我的爱情请求 = fetch('你的答案')
    .then(回应 => {
      console.log("📨 收到回应了!状态码:", 回应.status);
  
      if (!回应.ok) {
        throw new Error("被拒绝了...💔");
      }
  
      return 回应.json(); // 解析她的真心
    })
    .then(恋爱数据 => {
      console.log("🎉 解析成功!她的心意:", 恋爱数据);
  
      if (恋爱数据.答案 === "YES") {
        return "我们在一起了!💕";
      } else {
        throw new Error("我们还是做朋友吧😭");
      }
    })
    .catch(错误 => {
      console.log("💔 追求失败:", 错误.message);
      return "疗伤中...";
    })
    .finally(() => {
      console.log("🌅 无论结果如何,生活继续");
    });
  
  return 我的爱情请求;
}

💕 各种恋爱请求场景

场景1:日常关心问候 🌞

async function 日常关心() {
  // 像发送早安一样发起请求
  const 早安回应 = await fetch('/早安问候', {
    method: 'POST',
    body: JSON.stringify({
      消息: "早上好呀~今天天气超好!",
      附件: "阳光照片.jpg",
      期待: "希望你今天开心"
    })
  });
  
  if (早安回应.status === 200) {
    const 她的回复 = await 早安回应.json();
    console.log("💬 她回复了:", 她的回复.消息);
  }
}

场景2:约会邀请 🎬

async function 发起约会() {
  try {
    const 约会请求 = await fetch('/周末约会', {
      method: 'PUT', // 更新我们的关系状态
      headers: {
        '浪漫程度': 'MAX',
        '诚意指数': '100%'
      },
      body: JSON.stringify({
        时间: "周六晚上",
        地点: "那家你喜欢的餐厅",
        活动: "晚餐+电影",
        惊喜: "准备了小礼物"
      })
    });
  
    if (!约会请求.ok) {
      const 错误信息 = await 约会请求.json();
      throw new Error(错误信息.原因 || "约会被拒了😢");
    }
  
    const 约会确认 = await 约会请求.json();
    console.log("✅ 约会达成!详情:", 约会确认);
  
  } catch (错误) {
    console.log("❌ 约会失败:", 错误.message);
  }
}

场景3:纪念日提醒 🎁

function 纪念日准备() {
  fetch('/恋爱纪念日')
    .then(回应 => {
      if (回应.status === 404) {
        throw new Error("TA根本不记得纪念日💔");
      }
      return 回应.json();
    })
    .then(纪念日信息 => {
      console.log("📅 纪念日快到了!准备惊喜中...");
  
      // 准备礼物请求
      return fetch('/准备礼物', {
        method: 'POST',
        body: JSON.stringify({
          礼物: "定制项链",
          惊喜: "浪漫晚餐",
          预算: "一个月工资"
        })
      });
    })
    .then(礼物回应 => 礼物回应.json())
    .then(准备结果 => {
      console.log("🎁 礼物准备完成:", 准备结果);
    })
    .catch(错误 => {
      console.log("😱 纪念日危机:", 错误.message);
    });
}

💔 处理恋爱中的各种响应状态

HTTP状态码的恋爱解读

class 爱情状态码解读 {
  static 解读回应(状态码) {
    switch(状态码) {
      case 200:
        return "✅ 成功!两情相悦";
      case 201:
        return "🎉 新关系建立!恋爱开始";
      case 202:
        return "⏳ 接受请求,但还在考虑中";
      case 204:
        return "😶 没有回应(已读不回)";
      case 400:
        return "❌ 请求错误(表白方式不对)";
      case 401:
        return "🔒 未授权(还没到那一步)";
      case 403:
        return "🚫 被拒绝(发好人卡)";
      case 404:
        return "😵 找不到心(单相思)";
      case 408:
        return "⏰ 请求超时(等回复等太久)";
      case 500:
        return "💥 服务器错误(内心混乱)";
      case 503:
        return "🚧 服务不可用(暂时不想恋爱)";
      default:
        return "🤔 未知状态(猜不透的心)";
    }
  }
}

🌈 高级恋爱Fetch技巧

并行追求策略 🔄

async function 多线发展策略() {
  try {
    // 同时了解多个潜在对象
    const [小红, 小美, 小芳] = await Promise.all([
      fetch('/了解/小红').then(r => r.json()),
      fetch('/了解/小美').then(r => r.json()),
      fetch('/了解/小芳').then(r => r.json())
    ]);
  
    console.log("📊 市场调研完成:");
    console.log("小红:", 小红.匹配度);
    console.log("小美:", 小美.匹配度);
    console.log("小芳:", 小芳.匹配度);
  
    // 选择最合适的继续发展
    const 最佳选择 = [小红, 小美, 小芳].reduce((最佳, 当前) => 
      当前.匹配度 > 最佳.匹配度 ? 当前 : 最佳
    );
  
    console.log("🎯 锁定目标:", 最佳选择.名字);
    return 最佳选择;
  
  } catch (错误) {
    console.log("😅 多线操作翻车了");
  }
}

重试机制 - 坚持不懈 🏃‍♂️

async function 坚持不懈的追求(目标, 最大尝试次数 = 3) {
  for (let 尝试 = 1; 尝试 <= 最大尝试次数; 尝试++) {
    try {
      console.log(`第${尝试}次尝试追求${目标}...`);
  
      const 回应 = await fetch(`/追求/${目标}`, {
        method: 'POST',
        body: JSON.stringify({ 诚意: 尝试 * 10 })
      });
  
      if (回应.ok) {
        console.log("🎉 追求成功!");
        return await 回应.json();
      }
  
      if (尝试 === 最大尝试次数) {
        throw new Error("已经尽力了,放手吧");
      }
  
      // 等待一段时间再试
      await new Promise(resolve => 
        setTimeout(resolve, 1000 * 尝试)
      );
  
    } catch (错误) {
      if (尝试 === 最大尝试次数) {
        console.log("💔 最终失败:", 错误.message);
        throw 错误;
      }
    }
  }
}

💖 Fetch API 恋爱总结

Fetch 概念 恋爱解释
fetch() 发出恋爱邀请
Request 精心准备的表白
Response 对方的回应
.then() 等待并处理回应
.catch() 处理拒绝或失败
await 耐心等待结果
status 关系状态码
headers 恋爱的诚意和方式
body 真心的内容

Fetch就像恋爱中的主动出击:

  • 💌 发出请求:鼓起勇气表达心意
  • 等待回应:那种紧张又期待的心情
  • 📨 处理结果:无论成功失败都要面对
  • 🔄 重试机制:真爱值得多次尝试

记住:就像Fetch需要处理各种响应状态,恋爱中也要学会接受所有可能的答案。重要的是保持真诚,尊重对方的选择! 💕

勇敢Fetch爱情,但也要优雅地处理404(单相思)和403(被拒绝)! 😊

promise补充

我来详细解释一下如何正确创建 Promise 对象,以及你代码中的问题:

Promise 的基本创建方式

  1. 使用 Promise 构造函数
// 正确创建 Promise 的方式
const promise = new Promise((resolve, reject) => {
  // 这里包含异步操作或条件判断
  const isSuccess = Math.random() > 0.5; // 模拟50%成功率
  
  if (isSuccess) {
    resolve("我们在一起吧!💖"); // 表白成功
  } else {
    reject("你是个好人😭");     // 被发好人卡
  }
});
  1. 使用 Promise 的静态方法
// 直接创建已解决的 Promise
const successPromise = Promise.resolve("我们在一起吧!💖");

// 直接创建已拒绝的 Promise
const failPromise = Promise.reject("你是个好人😭");

完整的使用示例

// 创建表白 Promise
function createConfessionPromise() {
  return new Promise((resolve, reject) => {
    console.log("正在表白...");
  
    setTimeout(() => {
      const random = Math.random();
  
      if (random > 0.3) { // 70% 成功率
        resolve("我们在一起吧!💖");
      } else {
        reject("你是个好人😭");
      }
    }, 1000);
  });
}

// 使用 Promise
createConfessionPromise()
  .then((result) => {
    console.log("成功:", result);
  })
  .catch((error) => {
    console.log("失败:", error);
  })
  .finally(() => {
    console.log("表白流程结束");
  });

你代码中的问题

你的代码缺少了 new Promise 构造函数:

// ❌ 错误的写法
promise resolve("我们在一起吧!💖"); // 缺少 new Promise

// ✅ 正确的写法
new Promise((resolve, reject) => {
  if (/* 条件 */) {
    resolve("我们在一起吧!💖");
  } else {
    reject("你是个好人😭");
  }
});

更实用的表白函数

function 表白(诚意程度) {
  return new Promise((resolve, reject) => {
    console.log(`带着 ${诚意程度}% 的诚意表白中...`);
  
    setTimeout(() => {
      if (诚意程度 > 80) {
        resolve({
          success: true,
          message: "我们在一起吧!💖",
          response: "我也喜欢你!"
        });
      } else {
        reject({
          success: false,
          message: "你是个好人😭",
          advice: "请再多一些诚意"
        });
      }
    }, 2000);
  });
}

// 使用 async/await 方式
async function 发起表白() {
  try {
    const 结果 = await 表白(90);
    console.log("🎉 表白成功:", 结果.message);
    console.log("对方回应:", 结果.response);
  } catch (错误) {
    console.log("💔 表白失败:", 错误.message);
    console.log("建议:", 错误.advice);
  }
}

发起表白();

关键要点

  1. 必须使用 new Promise 构造函数
  2. resolve 和 reject 是函数参数,不是全局函数
  3. Promise 会自动返回内容,不需要额外 return
  4. 使用 .then() 处理成功,.catch() 处理失败

这样就能正确创建和使用 Promise 对象了!

reject走到catch里

resolve状态为 fulfilled会走到then


评论