REC
首页
文章分类
源码资源
技术教程
程序软件
文创娱乐
玄学修炼
关于我们
其他页面
网站统计
友情链接
用户留言
高清壁纸
关于易航
热门文章
Joe再续前缘主题 - 搭建本站同款网站
易航网址导航系统 – 功能强大,轻量易用
JsonDb-PHP轻量级文件数据库系统
Typecho一键调整网站为冬天情景插件
V免签全开源免签约码支付系统(支持:支付宝 微信 QQ)
标签搜索
PHP
Web前端
网站源码
PHP源码
Typecho
Typecho插件
课程资料
Windows程序
Android软件
武术内功
HTML源码
Web
Joe主题
Python
Windows
国漫
网络协议
MySQL
NodeJs
小说
发布
登录
注册
找到
42
篇与
Web前端
相关的结果
- 第 2 页
2025-01-04
手把手教你在 Vue 项目中优雅地封装 axios!
1.axios 简介 axios 是一个用来发起网络请求的 js 库,返回的格式是 Promise。 vue 项目中基本都是用 axios 发起网络请求。 2.安装配置 axios 2.1 安装 axios npm i axios -- save2.2 配置 axios 创建 Axios 实例 添加请求拦截器 添加响应拦截器 配置全局的 loading 在 src/util 下面新建 axios.js 文件 import axios from "axios"; import { ElMessage } from 'element-plus' import { ElLoading } from 'element-plus' import { ref } from 'vue' // -------------------------1. 创建axios实例----------------------- const instance = axios.create({ // 接口 baseURL: "/api", // 超时时间 timeout: 3000, }); // -------------------------2.请求拦截----------------------- instance.interceptors.request.use( config => { let token = sessionStorage.getItem('token'); if (token) { config.headers['token'] = token } // 加载loading addLoading(); return config; }, error => { // 请求发生错误,抛出异常 Promise.reject(error); } ); // -------------------------3.响应拦截----------------------- instance.interceptors.response.use( res => { // 取消加载 loading cancelLoading(); return res; }, error => { // 取消加载 loading cancelLoading(); if (error && error.response) { const status = error.response.status switch (status) { case 400: ElMessage.error("请求错误"); break; case 401: ElMessage.error("未授权,请重新登录"); break; case 403: ElMessage.error("登录过期,请重新登录"); break; case 404: ElMessage.error("请求错误,未找到相应的资源"); break; case 408: ElMessage.error("请求超时"); break; case 500: ElMessage.error("服务器错误"); break; case 504: ElMessage.error("网络超时"); break; default: ElMessage.error("请求失败"); } } else { if (JSON.stringify(error).includes("timeout")) { error.code = "TIMEOUT"; error.message = "服务器响应超时,请刷新页面"; } } return Promise.reject(error); }, ); // -------------------------4.配置全局loading----------------------- let loadCount = 0; let loadingInstance = ref(null); // 加载loading const addLoading = () => { loadCount++; if (loadCount === 1) { loadingInstance.value = ElLoading.service({ fullscreen: false, text: "正在请求数据中....", background: "rgba(0, 0, 0, 0)", }); } }; // 取消加载loading const cancelLoading = () => { loadCount--; if (loadCount === 0) { loadingInstance.value.close(); }; }; // -------------------------配置全局loading----------------------- // 5.导出 axios 实例 export default instance;2.3 封装常用的 http 请求 在 /src/util 下面新建 http.js 文件 其实就是先引入 axios 实例,然后将 axios 的几种常用网络请求封装成 Promise 并返回。import instance from "./axios"; const post = (url, data) => { return new Promise((resolve, reject) => { instance .post(url, data) .then((res) => { resolve(res); }) .catch((err) => { reject(err); }); }); }; const get = (url, data) => { return new Promise((resolve, reject) => { instance .get(url, { params: data }) .then((res) => { resolve(res); }) .catch((err) => { reject(err); }); }); }; const put = (url, data) => { return new Promise((resolve, reject) => { instance .put(url, data) .then((res) => { resolve(res); }) .catch((err) => { reject(err); }); }); }; const del = (url, data) => { return new Promise((resolve, reject) => { instance .delete(url, { params: data }) .then((res) => { resolve(res); }) .catch((err) => { reject(err); }); }); }; export default { post, get, put, del, };2.4 开发接口 在 /src/api 文件夹下新建接口文件 import http from "../utils/http"; // 用户登录 const login = (data) => { return http.post("/index/user/login", data); }; export default { login }图片 3.请求案例 // 导入用户api import userApi from "../api/user"; // 登录 const onSubmit = async () => { const res = await userApi.login(form); if (res.data.code == 200) { // 登录逻辑 } else { ElMessage.error(res.data.message); } };图片
技术教程
# Web前端
# Vue
易航
1月4日
0
103
0
2024-12-28
Web前端与众不同的夜间开关交互效果(附源码)
图片 这是一个精美炫酷的日/夜开关切换按钮效果。这个效果展示了如何通过纯CSS和少量JavaScript来创建复杂、富有动感的用户界面元素。它不仅功能性强,还具有很高的视觉吸引力,为用户提供了愉悦的交互体验。 主要特点和核心实现原理如下: 视觉效果: 一个圆形的切换按钮,模拟了日夜交替的场景。 日间模式显示太阳、云朵和一个小飞机。 夜间模式显示月亮、星星和一个宇航员熊。 切换时有平滑的动画过渡效果。 核心实现原理: a. HTML结构: b. CSS技术: c. JavaScript: 根据复选框状态同步更新body的data-dark-mode属性。 使用CSS变量(如 --dark)控制日/夜模式的状态。 大量使用CSS transitions和animations实现平滑的动画效果。 使用transform属性(如translate、scale、rotate)实现元素的移动和变形。 使用clip-path和overflow控制元素的可见区域。 巧妙运用z-index和定位来管理层叠关系。 使用SVG创建复杂的图形元素(如云、星星、熊等)。 使用嵌套的span元素组织不同的视觉元素。 关键技巧: 使用CSS变量和calc()函数动态计算样式值,实现平滑过渡。 利用SVG的灵活性创建复杂的图形和动画。 通过改变单一CSS变量(--dark)来控制整个场景的变化。 创作来源:Jhey - Night && Day Toggle ☀️/🌙 详细代码解析:与众不同的夜间开关交互效果源代码 可上下滑动查看完整源代码: <!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> *, *:after, *:before { box-sizing: border-box; } :root { --slide-ease: cubic-bezier(.4, -0.3, .6, 1.3); --easing: var(--slide-ease); --speed: 0.5s; --width: clamp(200px, 45vmin, 500px); --ar: 8 / 3; --ray: hsl(0 0% 100% / 0.5); --sun: hsl(47, 91%, 58%); --moon: hsl(212, 13%, 82%); --crater: hsl(221, 16%, 68%); --bg: hsl(219, 30%, 88%); --bear-speed: 10s; --color: hsl(219 30% 20%); } [data-dark-mode=true] { --bg: hsl(219, 30%, 12%); --color: hsl(219 30% 98%); } body { display: grid; place-items: center; min-height: 100vh; overflow: hidden; background: var(--bg); transition: background var(--speed) var(--easing); font-family: sans-serif, system-ui; } .toggle__backdrop:first-of-type .clouds path:first-of-type { fill: var(--ray); } .toggle { -webkit-tap-highlight-color: transparent; width: var(--width); /* random attempts at tackling the overflow iOS issue */ z-index: 10; will-change: transform; isolation: isolate; transform: translate3d(0, 0, 0); /* End of workaround city */ aspect-ratio: var(--ar); border-radius: 100vh; border: 0; position: relative; padding: 0; overflow: hidden; cursor: pointer; transition: background var(--speed) var(--easing); --sky: hsl(204, 53%, 47%); --night: hsl(229, 25%, 16%); outline-color: transparent; background: hsl(calc(204 + (var(--dark, 0) * 25)) calc((53 - (var(--dark, 0) * 28)) * 1%) calc((47 - (var(--dark, 0) * 31)) * 1%)); box-shadow: calc(var(--width) * 0) calc(var(--width) * 0.02) calc(var(--width) * 0.01) calc(var(--width) * -0.0025) hsl(210 10% 100% / 0.95), calc(var(--width) * 0) calc(var(--width) * -0.02) calc(var(--width) * 0.01) calc(var(--width) * -0.0025) hsl(210 10% 10% / 0.2), calc(var(--width) * 0) calc(var(--width) * 0.02) calc(var(--width) * 0.5) 0 hsl(210 10% 100% / 0.15); } .toggle:after { content: ""; position: absolute; inset: 0; box-shadow: calc(var(--width) * 0) calc(var(--width) * -0.025) calc(var(--width) * 0.025) 0 hsl(210 10% 10% / 0.15) inset, calc(var(--width) * 0) calc(var(--width) * 0.025) calc(var(--width) * 0.025) 0 hsl(210 10% 10% / 0.65) inset; border-radius: 100vh; } .toggle__content { position: absolute; top: 0; left: 0; right: 0; bottom: 0; overflow: hidden; border-radius: 100vh; display: block; clip-path: inset(0 0 0 0 round 100vh); } .toggle__backdrop { overflow: visible !important; position: absolute; bottom: 0; width: 100%; left: 0; transition: translate var(--speed) var(--easing); translate: 0 calc(var(--dark, 0) * (100% - (3 / 8 * var(--width)))); } [aria-pressed=false] .toggle__backdrop:last-of-type { transition-timing-function: cubic-bezier(.2, -0.6, .7, 1.6); } [aria-pressed=false] .stars path { transition-delay: 0s; } .stars path { transform-box: fill-box; transform-origin: 25% 50%; scale: calc(0.25 + (var(--dark, 0) * 0.75)); transition: scale var(--speed) calc(var(--speed) * 0.5) var(--easing); } .toggle__indicator { height: 100%; aspect-ratio: 1; border-radius: 0%; display: grid; place-items: center; padding: 3%; } .pilot-bear { position: absolute; width: 25%; } .toggle__star { height: 100%; aspect-ratio: 1; border-radius: 50%; position: relative; transition: translate var(--speed) var(--easing); translate: calc((var(--dark, 0) * -10%) + 5%) 0; /* translate: calc((var(--dark, 0) * -18%) + 5%) 0; */ } .sun { background: var(--sun); position: absolute; inset: 0; border-radius: 50%; overflow: hidden; box-shadow: calc(var(--width) * 0.01) calc(var(--width) * 0.01) calc(var(--width) * 0.02) 0 hsl(210 10% 100% / 0.95) inset, calc(var(--width) * -0.01) calc(var(--width) * -0.01) calc(var(--width) * 0.02) 0 hsl(210 10% 20% / 0.5) inset; } .moon { position: absolute; inset: -1%; border-radius: 50%; background: var(--moon); transition: translate var(--speed) ease-in-out; translate: calc((100 - (var(--dark, 0) * 100)) * 1%) 0%; box-shadow: calc(var(--width) * 0.01) calc(var(--width) * 0.01) calc(var(--width) * 0.02) 0 hsl(210 10% 100% / 0.95) inset, calc(var(--width) * -0.01) calc(var(--width) * -0.01) calc(var(--width) * 0.02) 0 hsl(210 10% 10% / 0.95) inset; } .moon__crater { position: absolute; background: var(--crater); border-radius: 50%; width: calc(var(--size, 10) * 1%); aspect-ratio: 1; left: calc(var(--x) * 1%); top: calc(var(--y) * 1%); box-shadow: calc(var(--width) * 0.01) calc(var(--width) * 0.01) calc(var(--width) * 0.01) 0 hsl(210 10% 6% / 0.25) inset, 0 calc(var(--width) * 0.005) calc(var(--width) * 0.01) 0 hsl(210 10% 100% / 0.25); } .moon__crater:nth-of-type(1) { --size: 18; --x: 40; --y: 15; } .moon__crater:nth-of-type(2) { --size: 20; --x: 65; --y: 58; } .moon__crater:nth-of-type(3) { --size: 34; --x: 18; --y: 40; } .toggle__star:before { content: ""; z-index: -1; width: 356%; background: radial-gradient(hsl(0 0% 100% / 0.25) 40%, transparent 40.5%), radial-gradient(hsl(0 0% 100% / 0.25) 56%, transparent 56.5%) hsl(0 0% 100% / 0.25); border-radius: 50%; aspect-ratio: 1; position: absolute; top: 50%; left: 50%; transition: translate var(--speed) var(--easing); translate: calc((50 - (var(--dark, 0) * 4)) * -1%) -50%; } .toggle__star:after { content: ""; position: absolute; inset: 0; display: block; background: hsl(0 0% 0% / 0.5); filter: blur(4px); translate: 2% 4%; border-radius: 50%; z-index: -1; } .toggle__indicator-wrapper { position: absolute; inset: 0; transition: translate var(--speed) var(--slide-ease); translate: calc(var(--dark, 0) * (var(--width) - (3 / 8 * var(--width)))) 0; } [aria-pressed=true] { --dark: 1; } /* Fun stuff! */ /* We have 11 stars */ .stars g { transform-box: fill-box; transform-origin: 50% 50%; } .stars g:nth-of-type(3) { animation: twinkle 4s -2s infinite; } .stars g:nth-of-type(11) { animation: twinkle 6s -2s infinite; } .stars g:nth-of-type(9) { animation: twinkle 4s -1s infinite; } @keyframes twinkle { 0%, 40%, 60%, 100% { transform: scale(1); } 50% { transform: scale(0); } } .astrobear { width: 12%; position: absolute; top: 100%; left: 0%; transition: translate calc(var(--speed) + (var(--dark, 0) * (var(--bear-speed) - var(--speed)))) calc(var(--bear-speed) * (0.4 * var(--dark, 0))) linear; translate: calc(var(--dark, 0) * 400%) calc(var(--dark, 0) * -350%); } .astrobear svg { transform-origin: 50% 75%; scale: var(--dark, 0); rotate: calc(var(--dark, 0) * 360deg); transition: rotate calc(var(--speed) + (var(--dark, 0) * (var(--bear-speed) - var(--speed)))) calc(var(--bear-speed) * 0.4) linear, scale var(--speed) ease-in-out; } .astrobear__container { position: absolute; overflow: hidden; inset: 0; clip-path: inset(0 0 0 0); opacity: var(--dark, 0); translate: 0 calc(-200% + (var(--dark, 0) * 200%)); transition: opacity var(--speed) var(--easing), translate var(--speed) var(--easing); } .pilot__container { position: absolute; overflow: hidden; inset: 0; clip-path: inset(0 0 0 0); opacity: calc(1 - var(--dark, 0)); translate: 0 calc(var(--dark, 0) * 200%); transition: opacity var(--speed) var(--easing), translate var(--speed) var(--easing); } .pilot-bear { width: 18%; position: absolute; top: 70%; left: 100%; transition: translate calc(var(--speed) + ((1 - var(--dark, 0)) * ((var(--bear-speed) * 0.5) - var(--speed)))) calc((var(--bear-speed) * 0.5) * ((1 - var(--dark, 0)) * 0.4)) linear; translate: calc((0 - (1 - var(--dark, 0))) * (var(--width) + 100%)) calc((0 - (1 - var(--dark, 0))) * (200%)); } .pilot { rotate: 12deg; animation: fly 4s infinite ease-in-out; width: 100%; } @keyframes fly { 50% { translate: 0 -25%; } } .controls { position: fixed; bottom: 1rem; right: 1rem; display: flex; align-items: center; gap: 0.5rem; font-family: sans-serif; color: var(--color); transition: color var(--speed) var(--easing); } [type=checkbox] { accent-color: var(--color); transition: accent-color var(--speed) var(--easing); } </style> </head> <body> <div class="controls"> <label for="sync">Sync <body></label> <input id="sync" type="checkbox" /> </div> <!-- 背景色控制 --> <button class="toggle" aria-pressed="false" title="Toggle Dark Mode"> <span class="toggle__content"> <!-- light模式的云2 --> <svg aria-hidden=true class="toggle__backdrop" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 290 228"> <g class="clouds"> <path fill="#D9D9D9" d="M335 147.5c0 27.89-22.61 50.5-50.5 50.5a50.78 50.78 0 0 1-9.29-.853c-2.478 12.606-10.595 23.188-21.615 29.011C245.699 243.749 228.03 256 207.5 256a50.433 50.433 0 0 1-16.034-2.599A41.811 41.811 0 0 1 166 262a41.798 41.798 0 0 1-22.893-6.782A42.21 42.21 0 0 1 135 256a41.82 41.82 0 0 1-19.115-4.592A41.84 41.84 0 0 1 88 262c-1.827 0-3.626-.117-5.391-.343C74.911 270.448 63.604 276 51 276c-23.196 0-42-18.804-42-42s18.804-42 42-42c1.827 0 3.626.117 5.391.343C64.089 183.552 75.396 178 88 178a41.819 41.819 0 0 1 19.115 4.592C114.532 176.002 124.298 172 135 172a41.798 41.798 0 0 1 22.893 6.782 42.066 42.066 0 0 1 7.239-.773C174.137 164.159 189.749 155 207.5 155c.601 0 1.199.01 1.794.031A41.813 41.813 0 0 1 234 147h.002c.269-27.66 22.774-50 50.498-50 27.89 0 50.5 22.61 50.5 50.5Z" /> </g> </svg> <!-- light模式的小飞机 --> <span aria-hidden=true class="pilot__container"> <span class="pilot-bear"> <img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f13edbe752dd4d11b7c394aaf0f68637~tplv-k3u1fbpfcp-watermark.image?" alt="pilot-bear" class="pilot" /> </span> </span> <!-- light模式的云1 --> <svg aria-hidden=true class="toggle__backdrop" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 290 228"> <g class="clouds"> <path fill="#fff" d="M328 167.5c0 15.214-7.994 28.56-20.01 36.068.007.31.01.621.01.932 0 23.472-19.028 42.5-42.5 42.5-3.789 0-7.461-.496-10.957-1.426C249.671 263.676 233.141 277 213.5 277a42.77 42.77 0 0 1-7.702-.696C198.089 284.141 187.362 289 175.5 289a42.338 42.338 0 0 1-27.864-10.408A42.411 42.411 0 0 1 133.5 281c-4.36 0-8.566-.656-12.526-1.876C113.252 287.066 102.452 292 90.5 292a42.388 42.388 0 0 1-15.8-3.034A42.316 42.316 0 0 1 48.5 298C25.028 298 6 278.972 6 255.5S25.028 213 48.5 213a42.388 42.388 0 0 1 15.8 3.034A42.316 42.316 0 0 1 90.5 207c4.36 0 8.566.656 12.526 1.876C110.748 200.934 121.548 196 133.5 196a42.338 42.338 0 0 1 27.864 10.408A42.411 42.411 0 0 1 175.5 204c2.63 0 5.204.239 7.702.696C190.911 196.859 201.638 192 213.5 192c3.789 0 7.461.496 10.957 1.426 2.824-10.491 9.562-19.377 18.553-24.994-.007-.31-.01-.621-.01-.932 0-23.472 19.028-42.5 42.5-42.5s42.5 19.028 42.5 42.5Z" /> </g> </svg> <span class="toggle__indicator-wrapper"> <span class="toggle__indicator"> <span class="toggle__star"> <span class="sun"> <span class="moon"> <span class="moon__crater"></span> <span class="moon__crater"></span> <span class="moon__crater"></span> </span> </span> </span> </span> </span> <!-- dark模式的星星 --> <svg aria-hidden=true class="toggle__backdrop" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 290 228"> <g> <g class="stars"> <g> <path fill="#fff" fill-rule="evenodd" d="M61 11.5a.75.75 0 0 1 .721.544l.813 2.846a3.75 3.75 0 0 0 2.576 2.576l2.846.813a.75.75 0 0 1 0 1.442l-2.846.813a3.749 3.749 0 0 0-2.576 2.576l-.813 2.846a.75.75 0 0 1-1.442 0l-.813-2.846a3.749 3.749 0 0 0-2.576-2.576l-2.846-.813a.75.75 0 0 1 0-1.442l2.846-.813a3.749 3.749 0 0 0 2.576-2.576l.813-2.846A.75.75 0 0 1 61 11.5Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M62.5 45.219a.329.329 0 0 1 .315.238l.356 1.245a1.641 1.641 0 0 0 1.127 1.127l1.245.356a.328.328 0 0 1 0 .63l-1.245.356a1.641 1.641 0 0 0-1.127 1.127l-.356 1.245a.328.328 0 0 1-.63 0l-.356-1.245a1.641 1.641 0 0 0-1.127-1.127l-1.245-.356a.328.328 0 0 1 0-.63l1.245-.356a1.641 1.641 0 0 0 1.127-1.127l.356-1.245a.328.328 0 0 1 .315-.238Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M32 31.188a.28.28 0 0 1 .27.204l.305 1.067a1.405 1.405 0 0 0 .966.966l1.068.305a.28.28 0 0 1 0 .54l-1.068.305a1.405 1.405 0 0 0-.966.966l-.305 1.068a.28.28 0 0 1-.54 0l-.305-1.068a1.406 1.406 0 0 0-.966-.966l-1.067-.305a.28.28 0 0 1 0-.54l1.067-.305a1.406 1.406 0 0 0 .966-.966l.305-1.068a.281.281 0 0 1 .27-.203Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M41.5 74.219a.329.329 0 0 1 .315.238l.356 1.245a1.641 1.641 0 0 0 1.127 1.127l1.245.356a.328.328 0 0 1 0 .63l-1.245.356a1.641 1.641 0 0 0-1.127 1.127l-.356 1.245a.328.328 0 0 1-.63 0l-.356-1.245a1.641 1.641 0 0 0-1.127-1.127l-1.245-.356a.328.328 0 0 1 0-.63l1.245-.356a1.641 1.641 0 0 0 1.127-1.127l.356-1.245a.328.328 0 0 1 .315-.238Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M34 83.188a.28.28 0 0 1 .27.203l.305 1.068a1.405 1.405 0 0 0 .966.966l1.068.305a.28.28 0 0 1 0 .54l-1.068.305a1.405 1.405 0 0 0-.966.966l-.305 1.068a.28.28 0 0 1-.54 0l-.305-1.068a1.406 1.406 0 0 0-.966-.966l-1.068-.305a.28.28 0 0 1 0-.54l1.068-.305a1.406 1.406 0 0 0 .966-.966l.305-1.068a.281.281 0 0 1 .27-.204Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M63 89.25a.375.375 0 0 1 .36.272l.407 1.423a1.874 1.874 0 0 0 1.288 1.288l1.423.406a.374.374 0 0 1 0 .722l-1.423.406a1.874 1.874 0 0 0-1.288 1.288l-.407 1.423a.374.374 0 0 1-.72 0l-.407-1.423a1.874 1.874 0 0 0-1.288-1.288l-1.423-.406a.374.374 0 0 1 0-.722l1.423-.406a1.874 1.874 0 0 0 1.288-1.288l.407-1.423a.376.376 0 0 1 .36-.272Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M110.5 53.156a.236.236 0 0 1 .225.17l.254.89a1.174 1.174 0 0 0 .805.805l.89.254a.23.23 0 0 1 .122.084.233.233 0 0 1-.122.366l-.89.254a1.167 1.167 0 0 0-.805.805l-.254.89a.232.232 0 0 1-.225.17.235.235 0 0 1-.225-.17l-.254-.89a1.174 1.174 0 0 0-.805-.805l-.89-.254a.23.23 0 0 1-.122-.084.233.233 0 0 1 .122-.366l.89-.254a1.167 1.167 0 0 0 .805-.805l.254-.89a.232.232 0 0 1 .225-.17Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M120 27.188a.279.279 0 0 1 .27.204l.305 1.067a1.41 1.41 0 0 0 .966.966l1.067.305a.283.283 0 0 1 .148.1.286.286 0 0 1 0 .34.283.283 0 0 1-.148.1l-1.067.305a1.403 1.403 0 0 0-.966.966l-.305 1.067a.279.279 0 0 1-.439.147.275.275 0 0 1-.101-.147l-.305-1.067a1.41 1.41 0 0 0-.966-.966l-1.068-.305a.284.284 0 0 1-.147-.1.286.286 0 0 1 0-.34.284.284 0 0 1 .147-.1l1.068-.305a1.405 1.405 0 0 0 .966-.966l.305-1.067a.279.279 0 0 1 .27-.204Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M155 28.5a.753.753 0 0 1 .721.544l.813 2.846a3.746 3.746 0 0 0 2.576 2.576l2.846.813a.747.747 0 0 1 .543.721.75.75 0 0 1-.543.721l-2.846.813a3.75 3.75 0 0 0-2.576 2.576l-.813 2.846a.747.747 0 0 1-.721.543.749.749 0 0 1-.721-.543l-.813-2.846a3.746 3.746 0 0 0-2.576-2.576l-2.846-.813a.747.747 0 0 1-.543-.721.75.75 0 0 1 .543-.721l2.846-.813a3.75 3.75 0 0 0 2.576-2.576l.813-2.846A.751.751 0 0 1 155 28.5Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M147 60.25a.377.377 0 0 1 .36.272l.407 1.423a1.883 1.883 0 0 0 1.288 1.288l1.423.407a.375.375 0 0 1 0 .72l-1.423.407a1.875 1.875 0 0 0-1.288 1.288l-.407 1.423a.371.371 0 0 1-.36.272.377.377 0 0 1-.36-.272l-.407-1.423a1.883 1.883 0 0 0-1.288-1.288l-1.423-.406a.375.375 0 0 1 0-.722l1.423-.406a1.875 1.875 0 0 0 1.288-1.288l.407-1.423a.372.372 0 0 1 .36-.272Z" clip-rule="evenodd" /> </g> <g> <path fill="#fff" fill-rule="evenodd" d="M125.5 76.344a.513.513 0 0 1 .496.374l.559 1.956a2.574 2.574 0 0 0 1.771 1.771l1.956.56a.514.514 0 0 1 .27.805.514.514 0 0 1-.27.186l-1.956.559a2.57 2.57 0 0 0-1.771 1.77l-.559 1.957a.514.514 0 0 1-.806.27.514.514 0 0 1-.186-.27l-.559-1.956a2.574 2.574 0 0 0-1.771-1.771l-1.956-.56a.514.514 0 0 1-.27-.805.514.514 0 0 1 .27-.186l1.956-.559a2.57 2.57 0 0 0 1.771-1.77l.559-1.957a.515.515 0 0 1 .496-.374Z" clip-rule="evenodd" /> </g> </g> </g> </svg> <!-- 太空熊动画 --> <span class="astrobear__container"> <span class="astrobear"> <svg aria-hidden=true xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 316 432"> <circle cx="158" cy="143" r="140" fill="#444" /> <circle cx="158" cy="143" r="140" fill="url(#a)" fill-opacity=".2" /> <circle cx="158" cy="143" r="140" stroke="#000" stroke-width="6" /> <path fill="#AF7128" fill-rule="evenodd" d="M65.98 159.61C49.913 155.643 38 141.134 38 123.842 38 103.495 54.495 87 74.842 87c14.337 0 26.761 8.19 32.85 20.146C119.687 100.674 133.414 97 148 97h20c14.52 0 28.19 3.641 40.146 10.059C214.251 95.15 226.65 87 240.952 87c20.347 0 36.842 16.495 36.842 36.842 0 17.222-11.818 31.685-27.787 35.72A85.104 85.104 0 0 1 253 182v66.56l10.054-10.054c11.325-11.325 29.687-11.325 41.012 0s11.325 29.687 0 41.012l-44.548 44.548a29.004 29.004 0 0 1-6.518 4.906V407c0 12.15-9.85 22-22 22h-44c-12.15 0-22-9.85-22-22v-28.69a41.072 41.072 0 0 1-14 .174V407c0 12.15-9.85 22-22 22H85c-12.15 0-22-9.85-22-22v-77.797a28.99 28.99 0 0 1-6.946-5.137l-44.548-44.548c-11.325-11.325-11.325-29.687 0-41.012 11.326-11.325 29.687-11.325 41.013 0L63 248.988V182a85.106 85.106 0 0 1 2.98-22.39Z" clip-rule="evenodd" /> <path fill="#000" d="m65.98 159.61 2.894.789a3.002 3.002 0 0 0-2.175-3.701l-.72 2.912Zm41.712-52.464-2.673 1.362a3 3 0 0 0 4.098 1.279l-1.425-2.641Zm100.454-.087-1.419 2.643a3 3 0 0 0 4.089-1.274l-2.67-1.369Zm41.861 52.503-.735-2.908a2.997 2.997 0 0 0-2.159 3.698l2.894-.79ZM253 248.56h-3a3 3 0 0 0 5.121 2.121L253 248.56Zm10.054-10.054-2.121-2.121 2.121 2.121Zm41.012 0-2.121 2.122 2.121-2.122Zm0 41.012 2.121 2.122-2.121-2.122ZM253 328.972l-1.448-2.627a3 3 0 0 0-1.552 2.627h3Zm-88 49.338h3a3 3 0 0 0-3.548-2.949l.548 2.949Zm-14 .174.475-2.963a3 3 0 0 0-3.475 2.963h3Zm-88-49.281h3a3 3 0 0 0-1.597-2.651L63 329.203Zm-6.946-5.137-2.121 2.121 2.121-2.121Zm-44.548-44.548-2.121 2.122 2.121-2.122Zm0-41.012 2.122 2.122-2.122-2.122Zm41.013 0-2.122 2.122 2.122-2.122ZM63 248.988l-2.121 2.121A2.999 2.999 0 0 0 66 248.988h-3ZM35 123.842c0 18.704 12.886 34.391 30.26 38.681l1.439-5.825C51.941 153.054 41 139.721 41 123.842h-6ZM74.842 84C52.838 84 35 101.838 35 123.842h6C41 105.151 56.151 90 74.842 90v-6Zm35.524 21.785C103.785 92.862 90.351 84 74.842 84v6c13.165 0 24.58 7.517 30.177 18.508l5.347-2.723ZM148 94c-15.095 0-29.311 3.803-41.733 10.506l2.85 5.281C120.685 103.544 133.924 100 148 100v-6Zm20 0h-20v6h20v-6Zm41.565 10.416C197.183 97.769 183.027 94 168 94v6c14.013 0 27.196 3.512 38.727 9.702l2.838-5.286ZM240.952 84c-15.471 0-28.878 8.82-35.476 21.691l5.34 2.737C216.427 97.481 227.819 90 240.952 90v-6Zm39.842 39.842c0-22.004-17.838-39.842-39.842-39.842v6c18.69 0 33.842 15.151 33.842 33.842h6Zm-30.052 38.629c17.269-4.364 30.052-20 30.052-38.629h-6c0 15.816-10.853 29.104-25.522 32.812l1.47 5.817ZM256 182a88.09 88.09 0 0 0-3.099-23.228l-5.788 1.58A82.082 82.082 0 0 1 250 182h6Zm0 66.56V182h-6v66.56h6Zm-.879 2.121 10.054-10.053-4.242-4.243-10.054 10.054 4.242 4.242Zm10.054-10.053c10.154-10.154 26.616-10.154 36.77 0l4.242-4.243c-12.496-12.497-32.758-12.497-45.254 0l4.242 4.243Zm36.77 0c10.153 10.153 10.153 26.615 0 36.769l4.242 4.243c12.497-12.497 12.497-32.758 0-45.255l-4.242 4.243Zm0 36.769-44.548 44.548 4.243 4.242 44.547-44.547-4.242-4.243Zm-44.548 44.548a26.013 26.013 0 0 1-5.845 4.4l2.896 5.255a32.006 32.006 0 0 0 7.192-5.413l-4.243-4.242ZM256 360v-31.028h-6V360h6Zm0 47v-47h-6v47h6Zm-25 25c13.807 0 25-11.193 25-25h-6c0 10.493-8.506 19-19 19v6Zm-44 0h44v-6h-44v6Zm-25-25c0 13.807 11.193 25 25 25v-6c-10.493 0-19-8.507-19-19h-6Zm0-28.69V407h6v-28.69h-6Zm-4.5 3.69c2.74 0 5.429-.253 8.048-.74l-1.096-5.899c-2.261.42-4.583.639-6.952.639v6Zm-6.975-.554c2.279.365 4.608.554 6.975.554v-6c-2.047 0-4.058-.163-6.025-.479l-.95 5.925ZM154 407v-28.516h-6V407h6Zm-25 25c13.807 0 25-11.193 25-25h-6c0 10.493-8.506 19-19 19v6Zm-44 0h44v-6H85v6Zm-25-25c0 13.807 11.193 25 25 25v-6c-10.493 0-19-8.507-19-19h-6Zm0-47v47h6v-47h-6Zm0-30.797V360h6v-30.797h-6Zm-6.067-3.016a32.008 32.008 0 0 0 7.664 5.668l2.806-5.303a26.002 26.002 0 0 1-6.228-4.607l-4.242 4.242ZM9.385 281.64l44.548 44.547 4.242-4.242-44.547-44.548-4.243 4.243Zm0-45.255c-12.497 12.497-12.497 32.758 0 45.255l4.243-4.243c-10.154-10.154-10.154-26.616 0-36.769l-4.243-4.243Zm45.255 0c-12.497-12.497-32.758-12.497-45.255 0l4.243 4.243c10.153-10.154 26.616-10.154 36.77 0l4.242-4.243Zm10.481 10.481L54.64 236.385l-4.243 4.243 10.482 10.481 4.242-4.243ZM60.001 182v66.988h6V182h-6Zm3.084-23.178A88.1 88.1 0 0 0 60 182h6c0-7.48 1.001-14.722 2.874-21.601l-5.789-1.577Z" /> <path fill="#fff" fill-rule="evenodd" d="M267.721 234.712C241.49 266.061 202.073 286 158 286c-43.749 0-82.91-19.647-109.141-50.598-11.328-8.104-27.18-7.069-37.353 3.104-11.325 11.325-11.325 29.687 0 41.012l44.548 44.548A28.99 28.99 0 0 0 63 329.203V407c0 12.15 9.85 22 22 22h44c12.15 0 22-9.85 22-22v-28.517c2.123.341 4.293.517 6.5.517 2.555 0 5.06-.236 7.5-.69V407c0 12.15 9.85 22 22 22h44c12.15 0 22-9.85 22-22V328.972a29.004 29.004 0 0 0 6.518-4.906l44.548-44.548c11.325-11.325 11.325-29.687 0-41.012-9.875-9.875-25.099-11.139-36.345-3.794Z" clip-rule="evenodd" /> <path fill="url(#b)" fill-opacity=".5" fill-rule="evenodd" d="M267.721 234.712C241.49 266.061 202.073 286 158 286c-43.749 0-82.91-19.647-109.141-50.598-11.328-8.104-27.18-7.069-37.353 3.104-11.325 11.325-11.325 29.687 0 41.012l44.548 44.548A28.99 28.99 0 0 0 63 329.203V407c0 12.15 9.85 22 22 22h44c12.15 0 22-9.85 22-22v-28.517c2.123.341 4.293.517 6.5.517 2.555 0 5.06-.236 7.5-.69V407c0 12.15 9.85 22 22 22h44c12.15 0 22-9.85 22-22V328.972a29.004 29.004 0 0 0 6.518-4.906l44.548-44.548c11.325-11.325 11.325-29.687 0-41.012-9.875-9.875-25.099-11.139-36.345-3.794Z" clip-rule="evenodd" /> <path fill="#000" d="m267.721 234.712-1.64-2.511c-.248.162-.47.359-.66.586l2.3 1.925Zm-218.862.69 2.289-1.94a3.026 3.026 0 0 0-.544-.5l-1.745 2.44Zm-37.353 3.104 2.122 2.121-2.122-2.121Zm0 41.012-2.121 2.122 2.121-2.122Zm44.548 44.548-2.121 2.121 2.121-2.121ZM63 329.203h3a2.999 2.999 0 0 0-1.597-2.651L63 329.203Zm88 49.28.475-2.962a3 3 0 0 0-3.475 2.962h3Zm14-.173h3a3 3 0 0 0-3.548-2.949l.548 2.949Zm88-49.338-1.448-2.627a3 3 0 0 0-1.552 2.627h3Zm51.066-49.454 2.121 2.122-2.121-2.122Zm0-41.012-2.121 2.121 2.121-2.121Zm-38.645-5.719C239.735 263.484 201.148 283 158 283v6c44.999 0 85.245-20.361 112.022-52.362l-4.601-3.851ZM158 283c-42.831 0-81.167-19.23-106.852-49.538l-4.578 3.879C73.347 268.937 113.332 289 158 289v-6ZM13.628 240.627c9.118-9.118 23.331-10.049 33.486-2.785l3.49-4.88c-12.502-8.944-29.991-7.805-41.219 3.423l4.243 4.242Zm0 36.77c-10.154-10.154-10.154-26.616 0-36.77l-4.243-4.242c-12.497 12.497-12.497 32.758 0 45.255l4.243-4.243Zm44.547 44.548-44.547-44.548-4.243 4.243 44.548 44.547 4.242-4.242Zm6.228 4.607a26.002 26.002 0 0 1-6.228-4.607l-4.242 4.242a32.008 32.008 0 0 0 7.664 5.668l2.806-5.303ZM66 360v-30.797h-6V360h6Zm0 47v-47h-6v47h6Zm19 19c-10.493 0-19-8.507-19-19h-6c0 13.807 11.193 25 25 25v-6Zm44 0H85v6h44v-6Zm19-19c0 10.493-8.506 19-19 19v6c13.807 0 25-11.193 25-25h-6Zm0-28.517V407h6v-28.517h-6Zm9.5-2.483c-2.047 0-4.058-.163-6.025-.479l-.95 5.925c2.279.365 4.608.554 6.975.554v-6Zm6.952-.639c-2.261.42-4.583.639-6.952.639v6c2.74 0 5.429-.253 8.048-.74l-1.096-5.899ZM168 407v-28.69h-6V407h6Zm19 19c-10.493 0-19-8.507-19-19h-6c0 13.807 11.193 25 25 25v-6Zm44 0h-44v6h44v-6Zm19-19c0 10.493-8.506 19-19 19v6c13.807 0 25-11.193 25-25h-6Zm0-47v47h6v-47h-6Zm0-31.028V360h6v-31.028h-6Zm7.397-7.027a26.043 26.043 0 0 1-5.845 4.4l2.896 5.255a32.036 32.036 0 0 0 7.192-5.413l-4.243-4.242Zm44.548-44.548-44.548 44.548 4.243 4.242 44.547-44.547-4.242-4.243Zm0-36.77c10.153 10.154 10.153 26.616 0 36.77l4.242 4.243c12.497-12.497 12.497-32.758 0-45.255l-4.242 4.242Zm-32.583-3.403c10.081-6.585 23.732-5.447 32.583 3.403l4.242-4.242c-10.898-10.899-27.697-12.29-40.106-4.184l3.281 5.023Z" /> <path fill="#000" d="M292.654 245.606a3 3 0 1 1-4.243-4.242l4.243 4.242Zm8.485-8.485-8.485 8.485-4.243-4.242 8.485-8.486 4.243 4.243ZM301.208 254.161a3 3 0 1 1-4.242-4.243l4.242 4.243Zm8.486-8.485-8.486 8.485-4.242-4.243 8.485-8.485 4.243 4.243ZM21.919 246.606a3 3 0 1 0 4.242-4.242l-4.242 4.242Zm-8.486-8.485 8.486 8.485 4.242-4.242-8.485-8.486-4.243 4.243ZM13.364 255.161a3 3 0 1 0 4.243-4.243l-4.243 4.243Zm-8.485-8.485 8.485 8.485 4.243-4.243-8.486-8.485-4.242 4.243Z" /> <path fill="#FF1E1E" d="M113.322 154.665h88.371v13.25h-88.371z" /> <path fill="#000" fill-rule="evenodd" d="M225.3 113.481c17.939 14.394 28.018 37.148 28.018 57.504H191.67c-.087-13.669-11.194-24.723-24.883-24.723h-18.56c-13.689 0-24.796 11.054-24.883 24.723H62c0-20.356 10.078-43.11 28.018-57.504C107.957 99.087 132.289 91 157.659 91c25.37 0 49.701 8.087 67.641 22.481Z" clip-rule="evenodd" /> <circle cx="212.665" cy="197.079" r="8.079" fill="#000" /> <circle cx="104.079" cy="197.079" r="8.079" fill="#000" /> <path fill="#000" d="M179.165 211.683c0 8.21-9.868 17.451-20.845 17.451-10.977 0-20.845-9.241-20.845-17.451 0-8.211 9.868-12.281 20.845-12.281 10.977 0 20.845 4.07 20.845 12.281Z" /> <path stroke="#000" stroke-linecap="round" stroke-width="6" d="M198 417v12M222 417v12M95 417v12M119 417v12" /> <circle cx="158" cy="143" r="140" fill="url(#c)" stroke="#000" stroke-width="6" /> <g clip-path="url(#d)"> <path fill="#F5D949" stroke="#000" stroke-width="6" d="m217.543 305.943.704 1.692 1.826.146 12.818 1.027h.001a.17.17 0 0 1 .059.011l.002.001a.147.147 0 0 1 .037.065.15.15 0 0 1 .008.075l-.001.002c0 .001-.01.017-.041.044h-.001l-9.765 8.365-1.391 1.192.425 1.782 2.981 12.506h.001c.009.04.008.058.008.06l-.001.002a.148.148 0 0 1-.05.056.146.146 0 0 1-.069.031h-.002c-.002-.001-.02-.005-.054-.026l-10.974-6.702-1.564-.955-1.564.955-10.974 6.702a.177.177 0 0 1-.053.025l-.002.001c-.004-.001-.032-.005-.069-.032a.146.146 0 0 1-.051-.056l-.001-.002s-.001-.018.008-.058l.001-.001 2.981-12.506.425-1.782-1.391-1.192-9.765-8.365h-.001c-.031-.027-.04-.043-.041-.044l-.001-.002a.15.15 0 0 1 .008-.075.147.147 0 0 1 .037-.065l.002-.001a.17.17 0 0 1 .059-.011h.001l12.818-1.027 1.826-.146.704-1.692 4.938-11.875a.161.161 0 0 1 .028-.051l.001-.001a.146.146 0 0 1 .076-.016c.047 0 .072.013.076.016l.001.001c.001 0 .012.013.028.051l4.938 11.875Z" /> </g> <path stroke="#000" stroke-linecap="round" stroke-width="16" d="M56.884 247.116A143.01 143.01 0 0 0 158 289a143.002 143.002 0 0 0 101.116-41.884" /> <path stroke="#000" stroke-width="6" d="M65.035 404s25.382-6.618 41.965-6.5c17.059.121 43.035 7.5 43.035 7.5M164.012 403.977s25.961-5.606 42.932-5.472C224.402 398.642 251 405 251 405M25 290l7.769-4.072a57.001 57.001 0 0 0 25.067-26.121L62 251M254.363 252l3.867 7.873a57.002 57.002 0 0 0 25.452 25.746l8.694 4.394" /> <defs> <linearGradient id="a" x1="158" x2="158" y1="0" y2="286" gradientUnits="userSpaceOnUse"> <stop offset=".219" /> <stop offset="1" stop-color="#fff" /> </linearGradient> <linearGradient id="b" x1="254" x2="100" y1="419" y2="325" gradientUnits="userSpaceOnUse"> <stop stop-opacity=".98" /> <stop offset="1" stop-opacity="0" /> </linearGradient> <radialGradient id="c" cx="0" cy="0" r="1" gradientTransform="matrix(165.9998 58.9999 -60.6938 170.7657 210 171)" gradientUnits="userSpaceOnUse"> <stop offset=".771" stop-color="#D9D9D9" stop-opacity="0" /> <stop offset="1" stop-color="#fff" stop-opacity=".63" /> </radialGradient> <clipPath id="d"> <path fill="#fff" d="M189 291h47v45h-47z" /> </clipPath> </defs> </svg> </span> </span> </span> </button> </body> <script> const BUTTON = document.querySelector("button"); const SYNC = document.querySelector("#sync") const TOGGLE = () => { const IS_PRESSED = BUTTON.matches("[aria-pressed=true]"); if (SYNC.checked) document.body.setAttribute("data-dark-mode", IS_PRESSED ? false : true); BUTTON.setAttribute("aria-pressed", IS_PRESSED ? false : true); }; BUTTON.addEventListener("click", TOGGLE); </script> </html>使用方式 复制源代码到空白的html格式文件,在浏览中打开运行即可。
技术教程
# Web前端
易航
1年前
3
42
1
2024-12-19
一个兼容 OneBot 协议的非官方 QQ 客户端实现,支持网页及 electron 客户端
Stapxs-QQ-Lite-2.0 一个兼容 OneBot 协议的非官方 QQ 客户端实现,支持网页及 electron 客户端Github地址:隐藏内容,请前往内页查看详情 在线体验:隐藏内容,请前往内页查看详情 图片 ✨ 特性支持 ✅ 使用 Vue.js 全家桶开发,快乐前后端分离 🎨 自适应布局,竖版也能使用 🖥️ 支持 PWA(都有 Electron 了(小声)) 🌚 Light/Dark Mode 自动切换 🍱 该有的都有(虽然比不过官方端) 复杂消息显示、转发、回复、撤回 群文件、群公告、群设置(一小部分)、精华消息 图片、收藏表情、文件发送 📦️ 支持多种 bot,我就是要用! 🔥 水深火热但是更好看的 Electron 客户端 🥚 彩蛋!来更多的彩蛋! 🛠 更多特性开发中 💬 提醒和问题 > 关于不安全连接 当使用 https 页面连接 ws 服务(反之相同)的情况下,连接将会失败;这是由于其中某一者是不安全的。在这种情况下,你可以选择将 ws 提升为 wss 或者将 https 降级为 http(不安全)来解决问题,此处不提供解决方案。>> Stapxs-QQ-Lite#32 > 我能使用其他 QQ Http Bot 吗 如果它兼容 OneBot 11 协议, 你可以尝试连接它, 但是由于消息体格式和接口扩展的差异,大部分情况下都不能完全正常使用。 已经兼容的 Bot 都写在了文档里,可以去 这里 查看。 > 使用 Bot 是否有风险 如果你使用的是 oicq-http, 可以查看此处了解 如果你尝试使用其他 QQ Bot (参见上一条问题), 请自行参考它的文档。 使用风险:https://github.com/takayama-lily/oicq/wiki/98.%E5%85%B3%E4%BA%8E%E8%B4%A6%E5%8F%B7%E5%86%BB%E7%BB%93%E5%92%8C%E9%A3%8E%E6%8E%A7
程序软件
# 网站源码
# Web前端
# HTML源码
# Windows程序
易航
1年前
2
54
0
2024-12-19
不要过度使用 console.log 啦!我们有更好的调试方式!
Hello,大家好,我是 Sunday。 在日常的工作中,我经常会帮同学【远程调试代码】。在远程时,我发现 很多同学会大量使用 console.log 进行打印调试。打印的数量之多,让同学自己都摸不清哪个打印对应哪个内容了😂。 毫无疑问,console.log 是一个很好的调试方式。但是 如果我们滥用它,效果反而会适得其反!大量打印信息堆积如山,反倒使得我们难以理清各条输出的对应逻辑! 因此,我们可以寻找可好的调试方案,来解决 console.log 过多而导致的混乱问题。 console 不止 log 没错!console 不止 log ,console 对象内部提供了很多的方法。在之前的文章中,我们提到过这一点:调试只会console.log?来看一看这 6 种惊艳的调试技巧! 使用更多的 console 方法配合可以帮助我们大幅提升调试的效率。 1. 使用 console.dir() 打印对象 console.dir() 是一个专门打印 对象 的 API。 console.dir() 方法可以显示指定 JavaScript 对象的属性列表,并以交互式的形式展现。输出结果呈现为分层列表,包含展开/折叠的三角形图标,可用于查看子对象的内容。因此,当我们打印对象时,可以使用 dir 代替 log 2. 使用 console.table() 打印数组 如果想要打印数组的话,那么 table() 是首选方法: const users = [ { id: 1, name: '张三', age: 25 }, { id: 2, name: '李四', age: 30 }, { id: 3, name: '王五', age: 35 }, ]; console.table(users);一句话:贼清晰! 图片 3. 使用 console.clear() 清理控制台 这个 API 可以帮我们解决控制台打印过多的问题。 如果我们要开启一轮新的调试,那么可以在开始前执行 console.clear(),清空之前的控制台打印。 这样,可以帮我们更加专注的针对本次的调试,而不需要被之前的打印信息所误导! 4. 使用 console.group() 控制打印组 这在 嵌套函数、递归 中非常有用,配合 console.groupEnd() 可以帮助我们完成分组打印。 比如下面的场景: function factorial(n) { console.group(`方法开始,长度(${n})`); if (n <= 1) { console.log("执行 1"); console.groupEnd(); return 1; } else { let result = n * factorial(n - 1); console.log(`执行 ${result}`); console.groupEnd(); return result; } } factorial(3);最终,打印结果如下: 图片 5. 使用 console.time() 完成计时 console.time() 配合 console.timeEnd() 经常用来处理 计时操作。 比如,我们想要测试一个函数的执行耗时,那么就可以通过这种方式完成: function processLargeData() { console.time("time"); // 模拟耗时操作 for (let i = 0; i < 1000000; i++) { Math.sqrt(i); } console.timeEnd("time"); } processLargeData();计时结果如下: 图片
技术教程
# Web前端
易航
1年前
0
43
0
2024-12-19
免费的轻量级代码编辑器 HBuilderX
HBuilderX 是由DCloud开发的一款面向Web前端开发者的集成开发环境(IDE),它是HBuilder的下一代产品,继承了HBuilder的诸多优点,并在此基础上进行了全面的升级。HBuilderX旨在提供更加强大、高效的开发体验,支持多种前端技术栈,包括但不限于HTML5、CSS3、JavaScript、Vue.js、React、Angular等。 功能特点 快速启动:启动速度快,能够在几秒内启动,这对于频繁切换任务的开发者来说是非常有用的特性。 智能提示:提供了丰富的代码补全和提示功能,能够提高编写代码的速度和准确性。 实时预览:支持实时预览功能,开发者可以直接在编辑器中看到代码修改的效果,无需频繁切换浏览器。 多页面编辑:支持多页面同时编辑,可以在同一个窗口中打开多个文件,方便进行对比和同步修改。 多光标操作:支持多光标编辑,允许用户一次编辑多处相同代码,提高编码效率。 HTML5/CSS3支持:内置对HTML5和CSS3的支持,包括新特性的语法高亮和代码提示。 Git集成:内置Git支持,方便开发者进行版本控制和团队协作。 代码美化:提供代码格式化功能,帮助开发者保持代码整洁。 文件压缩打包:支持JavaScript、CSS文件的压缩合并,减少HTTP请求次数,提高网页加载速度。 调试工具:拥有内置的调试工具,便于开发者进行前端代码的调试。 扩展插件:支持插件扩展,用户可以根据需要安装额外的插件来增强IDE的功能。 模板支持:内置了多种模板,包括常用的框架模板,方便快速搭建项目。 下载及安装 HBuilderX官网下载地址:https://www.dcloud.io/hbuilderx.html,可以在下载页面选择Windows或MacOS平台,Windows平台压缩包下载后解压即可运行。 HBuilderX首次运行时会出现主题和快捷键选择窗口,可以选择喜欢的主题和习惯的操作方式。点击【开始体验】按钮后,可以在HBuilderX自述文件中查看HBuilderX的特性。 图片 基本操作 语法提示:工具提供多种框架语法提示库,可以在窗口右下角进行选择。 图片 代码助手:工具提供智能的代码提示助手,可按【ctrl+I】打开代码助手,代码提示后可以按【alt+数字】选择直接选择某个项目。 图片 语法帮助:在编辑区域鼠标悬停会自动弹出语法或说明提示,按下【F1】键可以跳转到官方手册(2.5.7以上版本会在外部浏览器打开说明文档)。 图片 多光标操作:在编辑区域按【ctrl+鼠标左键】可增加一个光标,【ctrl+鼠标右键】可取消一个光标或选区。 图片 相同词操作:在编辑区域按【ctrl+shift+L】可以选择和光标位置相同的所有词同时进行编辑。 列选择:在编辑区域使用【alt+鼠标拖选】进入列选择编辑方式。 图片 Emmet支持:Emmet语法可以用缩写来动态生成所需要的结构及样式,从而极大改善HTML和CSS的编写流程。 图片 智能双击: 双击引号/括号内侧,选中引号/括号内的内容 双击逗号两侧,选择逗号前一段或后一段 双击行尾,选中该行(不含回车符) 双击连词符(-_)选中整个词 双击折叠行首内容开头,选择折叠段落 双击行首缩进,选择相同缩进的段落 双击列表符号,选择列表段落 双击Tag开头或结尾,选择整段Tag 双击属性赋值等号=,选择Html属性 双击if、function等关键字,选择整段包围区域 双击分号,选择js等语言的;分号前段落 双击css类名左侧,选择Css类 双击注释符选择注释区域 双击#选择markdown标题段落 双击语法定义符开头选择markdown图片、超链接、加粗、倾斜、代码等语法区 还有更多的操作和编辑技巧可以查看官方文档:https://hx.dcloud.net.cn 另外,软件对vue开发做了大量优化,新版本仅支持uni-app、uni-app cli、vue2-cli、vue3-cli项目中可以切换vue语法提示库;对Markdown文件编辑提供了强大支持,支持Emmet、快捷键编辑、智能粘贴、路径提示、Mermaid流程图等;对Json编辑进行了优化;支持开发小程序;可以创建uni-app项目;支持java插件、nodejs插件,并兼容了很多vscode的插件及代码块。 总之,HBuilderX非常适用于Web前端开发人员,特别是在进行HTML5相关的项目开发时非常高效。此外,由于其对多种语言的支持,也可以作为通用的轻量级开发工具使用。
程序软件
# Web前端
# Windows程序
易航
1年前
0
46
0
2024-12-19
你不知道的 7 项 CSS 新功能
CSS 一直在进步,不断推出新的功能,让开发更加强大、简单、有趣。以下是一些最新的 CSS 更新,它们不仅能优化你的工作流程,还会改变你对 CSS 的使用方式。我们也会通过一些示例帮助你理解这些功能的应用场景。 1. 无需 Flexbox 或 Grid 的快速居中对齐 还记得以前用 CSS 居中元素的“痛苦”吗? 现在,有了 align-content 属性,居中对齐变得轻松无比,无需额外的容器。 .my-element { display: block; align-content: center; }再也不用纠结是选 flexbox 还是 grid 了。 2. 更智能的 CSS 变量:@property CSS 变量非常灵活,但也存在缺陷,比如缺乏类型约束和默认值支持。 现在,@property 规则让你可以定义具有特定类型、继承规则和初始值的自定义属性。 传统做法: :root { --rotation: 45deg; } div { transform: rotate(var(--rotation)); }如果意外赋值 --rotation: blue;,代码可能会报错或行为异常。 新方法: @property --rotation { syntax: '<angle>'; inherits: false; initial-value: 0deg; } div { transform: rotate(var(--rotation)); } syntax: 限定变量值类型,比如 <angle> 表示角度。 inherits: 决定变量是否继承父级值。 initial-value: 定义默认值(这里是 0deg)。 这不仅提升了代码的健壮性,也减少了意外错误。 3. @starting-style:解决页面加载时样式闪烁问题 开发者经常遇到页面加载时内容闪烁的问题(FOUC)。 @starting-style 提供了解决方案,可以为元素设置初始样式,避免布局错乱。 @starting-style { .modal { opacity: 0; visibility: hidden; } } .modal { opacity: 1; visibility: visible; transition: opacity 0.3s ease, visibility 0.3s ease; }这样,即使在页面加载时,也能保证模态框的显示效果流畅自然,无需繁琐的内联样式。 4. 数学功能升级:更多强大的计算方法 以前,calc() 是 CSS 唯一的数学函数,但功能有限。 现在,新增了 round()、mod() 和 rem() 等强大函数,大幅扩展了计算能力。 传统方式: .element { width: calc(100% - 50px); }新功能: .box { /* 四舍五入为 3px */ margin: round(2.5px); } .stripe:nth-child(odd) { left: calc(var(--index) * 50px mod 200px); } .circle { /* 输出 1px */ width: rem(10px, 3px); }这些新增函数让复杂的布局计算变得更加灵活且直观。 5. 光明与黑暗的完美切换:light-dark() 定义明暗主题的样式曾经需要依赖媒体查询,容易导致代码重复。 现在,light-dark() 函数简化了这一过程。 传统方法: body { background-color: white; color: black; } @media (prefers-color-scheme: dark) { body { background-color: black; color: white; } }新方法: body { background-color: light-dark(white, black); color: light-dark(black, white); } 第一个值是浅色模式的样式。 第二个值是深色模式的样式。 再也不用重复代码,主题切换更加高效。 6. 表单验证新伪类::user-valid 和 :user-invalid 以前,:valid 和 :invalid 的表单验证伪类会在页面加载时触发,导致样式误判。 新伪类 :user-valid 和 :user-invalid 专注于用户交互后的状态,大幅提升体验。 新方法: input:user-valid { border-color: green; } input:user-invalid { border-color: red; }这避免了未交互前就出现错误提示的问题,让表单验证更贴合实际需求。 7. interpolate-size:更顺滑的尺寸动画 CSS 一直以来对高度、宽度等尺寸的动画支持不够友好。 现在,有了 interpolate-size 属性,尺寸动画变得更加平滑自然。 传统方法: .collapsible { overflow: hidden; max-height: 0; transition: max-height 0.3s ease-out; } .collapsible.open { max-height: 500px; }新方法: .panel { interpolate-size: height 0.5s ease; } .panel.open { height: auto; }浏览器会动态计算起始和结束尺寸,无论内容多少,动画都能流畅衔接。 总结 这些 CSS 新功能都得到了主流浏览器的支持,无论是 Chrome、Firefox 还是 Safari,都可以立即开始使用。掌握这些特性不仅能提升你的工作效率,还能让代码更加简洁优雅。
技术教程
# Web前端
易航
1年前
0
21
0
2024-12-08
CSS奇思妙想:动态点亮文本下划线
一、简介 在现代网页中,为用户提供流畅且具有吸引力的交互体验至关重要。本文分享了一种纯CSS实现的动态文本下划线效果。当鼠标悬停在文本上时,无论文本的宽度如何、有多少行、行中有多少字,下划线都会以从左到右、从上到下的顺序,自适应的在文本底部动态、平滑地显示出来。而当鼠标移出时,下划线则按照相反的方向,逐行动态、平滑地隐藏,直到恢复至最初状态。具体效果如下: 案例效果 图片 该动画效果看起来很简单,具体实现也确实不难,难的是实现思路,需要扎实的前端CSS基础和很大的脑洞。该动画效果中利用到了:行内元素的基础特性、元素背景特性、trasition过渡等CSS的基础知识。 该动画可用于资料列表、新闻列表等页面场景中,可以突出显示鼠标所聚焦的文本内容,提升用户的视觉交互体验。 二、具体实现 1、实现思路 ① 看到文本下划线,我们首先会考虑通过text-decoration属性来实现,将文本的该属性默认状态设置为none,然后在hover的时候将其设置为underline,使文本出现下划线。但仔细想想,会发现这个方案并不可取,因为text-decoration是一个离散属性,只能在不同属性值状态之间切换,无法通过trasition过渡实现平滑动画。 ② 排除掉text-decoration属性之后,我们继续思考还有什么样式属性可以实现类似下划线的效果。此时应该想到两个属性:border和background。然后进一步思考,发现border只能控制宽度或者颜色,而且每一行的border只能同时显示,或者同时隐藏,无法实现逐行按序显示/隐藏下划线的效果。排除掉border后,最终确定需要依赖background属性来实现目标效果。 ③ 确定属性之后,首先我们要使用行内元素(或设置display: inline;的其他元素)来承载文本内容。因为行内元素具有一个重要的特性:元素的宽度和高度由其内容决定,当文本内容换行时,从布局角度看,每个换行后的文本片段会被视为单独的内联内容部分,而不是一个整体的块级元素那样有明确的整体宽度和高度概念。这一点特性,在后面通过背景实现下划线效果时将会起到关键作用。 ④ 接下来思考应该如何设置背景属性。目标效果中下划线是纯色的,首先想到的应该是设置背景颜色,但这种想法是错误的。因为设置背景颜色会直接应用到整个行内元素内容区域,而不是对每行的内联文本片段进行单独设置,且无法控制尺寸和位置。但如果给行内元素设置的背景图片,则会基于每行的内联文本片段来进行处理,而非整体内容区域,并且可以通过 background-size 和 background-position 属性进行精确控制。简单来说:我们给换行的行内元素设置背景图片时,其实际效果并非给整个内容块设置背景,而是给每行的内联文本片段设置背景。 ⑤ 经过前面四步的思考,我们已经明确了实现目标效果的关键,接下来只需按部就班设置相关样式即可。首先通过linear-gradient生成一张纯色图片作为元素的背景图片,并设置为不允许重复;其次设置background-size属性,设置初始宽高,使其看起来为一条线;然后通过background-position将背景定位在元素底部,变为下划线。此时查看页面样式,发现每行文本底部的下划线效果已经实现。 ⑥ 最后我们实现平滑动画效果。首先设置background-size属性,将初始宽度设置为0,将背景隐藏;然后在元素hover的时候,将背景宽度恢复为100%,显示背景;再然后借助transition属性,实现平滑的过渡效果,使得背景能逐行动态平滑的显示。 2、具体代码 HTML <div class="title-box"> <span> 有志者,事竟成。破釜沉舟,百二秦关终属楚。苦心人,天不负。卧薪尝胆,三千越甲可吞吴。有志者,事竟成。破釜沉舟,百二秦关终属楚。苦心人,天不负。卧薪尝胆,三千越甲可吞吴。 </span> </div>CSS .title-box { /* 父级盒子设置宽度 限制内部文本宽度 使其换行 */ width: 336px; margin: 50px auto; } .title-box span { color: #333; /* 通过渐变设置图片背景 且不允许重复 */ background: linear-gradient(to right, #333, #333) no-repeat; /* 背景初始宽度为0 高度为2px */ background-size: 0 2px; /* 背景位置在文字底部 */ background-position: left bottom; /* 设置平滑过渡效果 */ transition: background-size 1.5s ease-in-out; cursor: pointer; } /* hover时触发动画 */ .title-box span:hover { /* 背景宽度变为100% 高度不变 */ background-size: 100% 2px; /* 可以通过改变背景位置 改变下划线出现和消失的方向 */ /* background-position: right bottom; */ }三、相似扩展 1、效果1 图片 2、效果2 图片
技术教程
# Web前端
易航
1年前
0
44
0
2024-12-08
揭开迷雾:全面解析 JS 中的 this 指向问题
一、简介 身为一个使用JavaScript的开发者,我们或多或少在开发中都遇到过因 this 指向不明导致的代码错误。函数中this 关键字的指向是一个复杂但又关键的概念,大多数时候它的指向不是在编写时确定的,而是在代码执行时根据函数的调用方式来决定,简单来说,this 的指向取决于函数的调用者(箭头函数除外)。 本文将全面详细的讲解this的指向规则,让你能够清晰理解并正确使用 this,避免由于错误的指向导致的程序异常,并提升对JavaScript的整体理解。 二、详解 1、 全局作用域 在全局作用域下(非严格模式),也就是最外层的JS脚本中,this指向全局对象(浏览器中为window对象)。 <script> console.log(this === window); // 浏览器中输出 true </script>2、普通函数 在调用一个独立的普通函数时(非严格模式),此时相当于通过全局对象来调用函数,this会进行默认绑定,指向全局对象(浏览器中为window对象)。 重点:普通函数中的 this 指向是动态的,取决于函数的调用方式,会因为调用方式的不同而发生改变。 // 非严格模式下 // 两个普通函数 function showThis() { console.log(this); } const showThis2 = function() { console.log(this); } // 调用普通话函数 showThis(); // 输出 window 对象 showThis2(); // 输出 window 对象 // 相当于通过window来调用函数 因此this指向window window.showThis(); // 输出 window window.showThis2(); // 输出 window如果让一个对象内部的方法指向普通函数,并通过该对象来调用函数,则this指向发生改变,指向调用函数的对象,谁进行调用,this就指向谁。 // 普通函数 function showThis() { console.log(this); } // 创建对象 并让对象的方法指向函数 const obj = { getThis: showThis }; // 通过对象调用函数 obj.getThis(); // 输出 obj3、箭头函数 箭头函数不会创建自己的this,其内部的this会继承函数定义时其外层最近的非箭头函数的 this 指向。如果是在全局作用域内使用箭头函数,则this指向全局对象;如果是在构造函数中使用箭头函数,则this指向new出来的新对象... 重点:箭头函数中的 this 指向是静态的,在函数定义时确定,后面不会因为调用方式的不同而发生改变,也无法被call/apply/bind等方法改变。 // 非严格模式下 // 箭头函数 this指向window const showThis3 = () => { console.log(this); } // 调用箭头函数 showThis3(); // 输出 window 对象如果让一个对象内部的方法指向箭头函数,并通过该对象来调用函数,此时虽然函数的调用者发生变化,但this指向不会改变,依旧指向全局对象。 // 箭头函数 const showThis3 = () => { console.log(this); } // 创建对象 并让对象的方法指向函数 const obj = { getThis: showThis3 }; // 通过对象调用函数 但this指向不会改变 obj.getThis(); // 输出 window4、调用对象的方法 在通过对象直接调用其内部的方法时,方法中的this 会进行隐式绑定,指向当前对象。 const obj = { getThis: function() { // 对象的方法中的this 指向当前对象 console.log(this) } }; // 通过对象调用方法 this指向当前对象 obj.getThis(); // 输出 obj如果先用一个变量指向对象的方法,然后再通过变量来调用对应的方法时,this的指向将不再指向对象,而是指向全局对象(浏览器中为window对象)。因为此时相当于进行独立函数调用,遵守独立函数的默认绑定规则。 <script> const obj = { getThis: function () { console.log(this) } }; // 通过对象调用方法 this指向对象本身 obj.getThis(); // 输出 obj // 使用变量指向对象的方法 但不调用 const fun = obj.getThis; // 通过变量调用方法 此时相当于独立函数调用 所以this指向window fun(); // 输出 window </script>如果使用一个对象的方法指向另一个对象的方法,此时两个对象都可以调用该方法,那么具体的this指向取决于调用者,谁进行调用, this就指向谁。 <script> const obj = { getThis: function () { console.log(this) } }; // 通过obj调用方法 this指向obj本身 obj.getName(); // 输出 obj // 在另一个对象中使用属性指向前面对象的方法 const obj2 = { // 指向obj的方法 get2: obj.getThis } // 通过obj2调用方法 此时this指向obj2 obj2.get2(); // 输出 obj2 </script>还存在一种特殊情况:如果对象的方法使用的是箭头函数,那么方法中的 this 将继承定义对象时所在作用域的this指向,而非对象本身,并且后续不会因为调用者改变而改变this指向。 <script> // 如果对象的方法使用的是箭头函数 那么this将继承定义对象时所在作用域的this指向 // 在全局作用域下定义对象 const obj = { getThis2: () => { // 此时箭头函数中的this 指向全局对象window console.log(this) } } // 虽然是通过obj调用的 但是其this还是会指向全局对象window obj.getThis2(); // 输出 window // 使用变量指向对象的方法 但不调用 const fun = obj.getThis2; // 通过变量调用方法 this依旧指向window fun(); // 输出 window // 在另一个对象中使用属性指向对象的方法 const obj2 = { // 指向obj的方法 get2: obj.getThis2 } // 通过obj2调用方法 此时this依旧指向window obj2.get2(); // 输出 window </script>5、调用构造函数 在使用new关键字调用构造函数时,会创建一个新的对象,此时this 会指向被创建的新对象。内部的普通函数和箭头函数内的 this 也都指向被创建的新对象,但后续普通函数的this指向是会根据调用者不同而发生改变,箭头函数则不会改变。 // 构造函数 function Person(name) { // 构造函数中的this指向通过new创建的新对象 this.name = name; // 普通函数 this.getThis = function () { console.log(this) } // 箭头函数 this.getThis2 = () => { console.log(this) } } // 调用构造函数创建新对象 const person = new Person('Bob'); // 通过新对象调用方法 此时this指向新对象 person.getThis(); // 输出 person person.getThis2(); // 输出 person // 在另一个对象中使用属性指向new出来的新对象的方法 const obj = { getThis: person.getThis, getThis2: person.getThis2 } // 通过obj调用方法 此时this指向会根据函数类型不同而不同 obj.getThis(); // 输出 obj obj.getThis2(); // 输出 person 还存在一种特殊情况,就是Function()构造函数,在使用该构造函数创建新函数时,其内部的this指向并非指向新函数本身,而是根据函数被调用的方式来决定this指向,谁调用this就指向谁。 // 非严格模式 // 在全局作用域下 const func = new Function('console.log(this)'); // 相当于通过window来调用函数 因此this指向window func(); // 输出 window 对象 // 在对象中 const p = { name: 'Alice', get: func } // 通过对象中调用函数 对象内的this指向对象本身 p.get(); // 输出 Person { name: 'Alice', get: [Function] }6、事件处理函数 在事件处理函数中,如果绑定的函数是普通函数,则相当于由DOM元素调用函数,则函数内的this指向触发事件的DOM元素;如果绑定的是箭头函数,则函数内的this会继承绑定事件处理函数所在作用域的this指向。 <button id="btn">Click me</button> <!-- 内联的事件处理器也一样 --> <button onclick="console.log(this)">Click me</button> <script> const btn = document.getElementById('btn'); // 绑定普通函数 相当于dom调用函数 所以this指向button元素 btn.addEventListener('click', function () { console.log('普通函数this--', this); // 输出 button 元素 }); // 绑定箭头函数 继承绑定事件处理函数所在作用域的this 此时为全局作用域 所以this指向window btn.addEventListener('click', () => { console.log('箭头函数this--', this); // 输出 window }); </script>7、回调函数 当把一个函数作为回调函数传递后,其this指向取决于回调函数的调用方式和函数的类型两者: 如果函数类型为普通函数且被传递后是直接独立调用的,此时相当于独立函数调用,函数内部this指向全局对象(浏览器中为window对象)。 如果函数类型为普通函数且被传递后是通过别的对象进行调用的,此时相当于通过对象调用函数,函数内部的this指向函数的调用者。 如果函数类型为箭头函数,则无论被传递后是如何进行调用的,都不会修改函数内部的this指向,箭头函数内部的this指向在函数定义后确定就不会再被改变。 const obj = { // 普通函数 showThis: function () { console.log(this); }, // 箭头函数 showThis2: () => { console.log(this); } } function fun(fn) { // 直接独立调用回调函数 fn(); } function fun2(fn) { // 通过对象调用回调函数 const a = { getThis: fn, } a.getThis(); } // 对象普通函数中的this指向对象本身 obj.showThis(); // 输出 obj // 对象箭头函数中的this继承定义对象时所在作用域的this指向 此时为window obj.showThis2(); // 输出 window // 传入一个普通函数 并且直接调用函数 相当于独立函数调用 所以this指向window fun(obj.showThis); // 输出 window // 传入一个箭头函数 并且直接调用函数 this指向不受影响 依旧为window fun(obj.showThis2); // 输出 window // 传入一个普通函数 并且通过对象调用函数 this被改变 指向其调用者 fun2(obj.showThis); // 输出调用者对象 a // 传入一个箭头函数 并且通过对象调用函数 this指向不受影响 依旧为window fun2(obj.showThis2); // 输出 window数组提供的内置方法中,除了传递回调函数之外,还可以通过第二个参数指定回调函数的this指向。如果未指定this的指向,则取决于函数的调用环境内的this指向。 // 创建对象 const obj = { multiplier: 2 }; // 创建数组 const numbers = [1, 2, 3]; // 使用数组提供的map方法 第一个参数是回调函数 第二个参数是指定回调函数的this指向 const doubled = numbers.map(function (number) { // 回调函数中的this指向obj 所以this.multiplier指向obj.multiplier 值为2 return number * this.multiplier; }, obj); // 最终运算结果为[2, 4, 6] console.log(doubled); // 未指定this指向 回调函数中的this指向window const doubled2 = numbers.map(function (number) { return this; }); // 最终运算结果为[window, window, window] console.log(doubled2);8、call/apply/bind 显式指定 call()、apply()、bind()三个方法都可以显式的指定函数的this指向,只是在一些具体细节上有所不同。例如:call() 和 apply() 方法会在改变函数内部this指向的同时,调用函数执行一次。而bind() 不会调用函数执行,仅改变函数的this指向;在向函数传递参数时,call() 和 bind() 传递的参数都是用逗号隔开的独立参数,而apply()是以数组的形式来传递参数。 // call方法 function greet(text) { console.log(`${text}, ${this.name}`); } const user = { name: 'Charlie' }; // 使函数的this指向user 且会调用执行一次 greet.call(user, 'Hello'); // 输出 'Hello, Charlie' // apply方法 function introduce(age, gender) { console.log(`Name: ${this.name}, Age: ${age}, Gender: ${gender}`); } const user2 = { name: 'Dana' }; // 使函数的this指向user 且会调用执行一次 introduce.apply(user2, [25, 'Female']); // 输出 'Name: Dana, Age: 25, Gender: Female' // bind方法 const module = { x: 42, getX: function () { return this.x; } }; // 此时指向对象的方法 但不调用执行 const retrieveX = module.getX; // 调用执行 此时的 this 指向window 因为相当于独立函数调用 console.log(retrieveX()); // 输出 undefined // 修改this指向 使函数的this指向module 且不会调用执行 const boundGetX = retrieveX.bind(module); // 手动调用执行一次 console.log(boundGetX()); // 输出 42三、课后练习 1、下面代码的执行结果是什么? // 全局作用域 且非严格模式 [1, 2, 3].forEach(function (item) { console.log(this); });2、下面代码的执行结果是什么? // 全局作用域 且非严格模式 const obj = { a: () => { console.log(this); }, b: function () { console.log(this); } }; obj.a(); obj.b();3、下面代码的执行结果是什么? // 全局作用域 且非严格模式 function Person(name) { this.name = name; this.getName = () => { return this.name; }; } const person1 = new Person('Alice'); const person2 = { name: 'Bob' }; person2.getName = person1.getName; console.log(person2.getName());欢迎大家在评论区揭晓答案
技术教程
# Web前端
易航
1年前
0
26
0
2024-11-23
15 分钟带你感受 CSS :has() 选择器的强大
最近看到了许多关于 :has() 选择器的知识点,在此总结下来。 MDN 对 :has() 选择器 的解释是这样的: CSS 函数式 伪类 :has() 表示一个元素,如果作为参数传递的任何 相对选择器 在锚定到该元素时,至少匹配一个元素。这个伪类通过把 可容错相对选择器列表 作为参数,提供了一种针对引用元素选择父元素或者先前的兄弟元素的方法。下面一起来感受下 :has() 选择器的强大之处吧。 :has() 选择器选择父元素和前面的兄弟元素 邻接兄弟选择器(+)用来选中恰好处于另一个在继承关系上同级的元素旁边的物件。例如,选中所有紧随<p>元素之后的<img>元素: p + img { }通用兄弟关系选择器(~)用来选中一个元素后面的所有兄弟元素。例如,选中<p>元素之后的所有的<img>元素: p ~ img { }css 并没有提供直接选择父元素或者前面的兄弟元素的选择器,但 :has() 可以做到这点。 1、比如选择所有包含 <p>元素的父元素: :has(p) { }2、选择直接后代元素包含 <p>元素的父元素: :has(> p) { }3、选择直接后代元素包含 <p>元素的父级标签名是 div父元素: div:has(> p) { }4、选择 <p>元素的相邻的前一个标签名是 div的兄弟元素: div:has(+ p) { }5、选择 <p>元素的前面所有标签名是 div的兄弟元素: div:has(~ p) { }:has() 选择器中的 且 和 或 在 :has() 选择器中表示 且 和 或 很简单,例如: p:has(.a):has(.b) 表示选择同时包含子元素 a 和 子元素 b 的 元素 p p:has(.a, .b) 表示选择包含子元素 a 或者包含子元素 b 的 元素 p :has() 选择器选择一个范围内的元素 现在有如下元素 <div> <h2>标题开始(选择第一行字体为绿色,最后一行字体为红色)</h2> <p>h2中间第一行</p> <h4>h2中间第二行</h4> <h5>h2中间最后一行</h5> <h2>标题结束</h2> </div>要求选择第一行字体为绿色,最后一行字体为红色。需要注意的是,中间元素可以是任意的。 cc.png图片 使用 :has() 实现上面效果,可以这么做 /* 选择 h2 中间第一行 */ h2+ :has(~ h2) { color: green; } /* 选择 h2 中间最后一行 */ h2~ :has(+ h2) { color: red; }h2 + :has(~ h2) 表示选择紧跟着 h2 的并且后面还有 h2 元素的兄弟元素。也就选择到了 h2 范围内的第一个元素。 h2 ~ :has(+ h2) 表示选择 h2 后面的兄弟元素,并且该兄弟元素的下一个兄弟元素是 h2,也就选择到了 h2 范围内最后一个元素 那如果要选择中间所有元素呢,可以这样做 dd.png图片 /* 选择 hr 中间所有行 */ hr~ :has(~ hr) { color: blue; }:has()选择器的应用 1、CSS :has() 选择器之星级评分 关于星级评分,之前写过一篇文章分享过三种方式使用纯 CSS 实现星级评分。 这里介绍下使用 :has() 选择器 + :not() 选择器 实现星级评分的方式。 星级评分效果包括鼠标滑入和点击,滑入或点击到第几颗星的位置,该位置之前的星高亮,之后的星不高亮或者有高亮的则取消高亮; star.webp图片 html 结构 <div> <input type="radio" name="radio" id="radio1"> <label for="radio1"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"> <path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"> </path> </svg> </label> <input type="radio" name="radio" id="radio2"> <label for="radio2"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"> <path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"> </path> </svg> </label> <input type="radio" name="radio" id="radio3"> <label for="radio3"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"> <path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"> </path> </svg> </label> <input type="radio" name="radio" id="radio4"> <label for="radio4"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"> <path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"> </path> </svg> </label> <input type="radio" name="radio" id="radio5"> <label for="radio5"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"> <path fill="currentColor" d="M283.84 867.84 512 747.776l228.16 119.936a6.4 6.4 0 0 0 9.28-6.72l-43.52-254.08 184.512-179.904a6.4 6.4 0 0 0-3.52-10.88l-255.104-37.12L517.76 147.904a6.4 6.4 0 0 0-11.52 0L392.192 379.072l-255.104 37.12a6.4 6.4 0 0 0-3.52 10.88L318.08 606.976l-43.584 254.08a6.4 6.4 0 0 0 9.28 6.72z"> </path> </svg> </label> </div>为了使星星有点击效果,利用 radio + label 的方式实现点击效果;label 代表星星。 当点击星星时,高亮当前星星 input:checked+label { color: gold; }当鼠标移入星星时,高亮当前星星,并且该位置之后的星星取消高亮; label:hover { color: gold; &~label { color: #ccc !important; } }让当前位置之前的所有星星也高亮,可以利用 :not ,排除掉当前位置和当前位置之后的星星。 label:not(:hover, :hover ~ *) { color: gold; }并且只有鼠标滑入时添加这些效果。 div:has(label:hover) label:not(:hover, :hover ~ *) { color: gold; }同样,当点击星星时,点亮当前选择的之前所有的星星也如此 div:has(input:checked) label:not(input:checked ~ label) { color: gold; }完整示例 2、CSS :not 和 :has() 模拟 :only-of-type 有下面的 html 结构 <div> <p>第一页</p> <p class="this">第二页</p> <p>第三页</p> <p>第四页</p> </div>要选择类名为 this 的元素,并设置颜色为红色,使用 .this{color:red;} 可以轻松做到。 aa.png图片 如果现在有两个 div 元素块 <div> <p>第一页</p> <p class="this">第二页</p> <p>第三页</p> <p>第四页</p> </div> <div> <p>第一页</p> <p class="this">第二页</p> <p class="this">第三页</p> <p>第四页</p> </div>现要求选择 div 的子元素中只有含有一个类名为 this 的元素(也就是第一个 div 元素块),并且设置其颜色为红色,该怎么做呢? :only-of-type 代表了任意一个元素,这个元素没有其他相同类型的兄弟元素。 但 :only-of-type 判断是否有相同类型的依据是标签名,而不是类名。所以并不能达到想要的效果。 /* 这种写法是无效的,无法判断元素有没有其他相同的类名。 */ .this:only-of-type { color: red; } /* 这种写法是有效的,但判断的是没有相同的 p 的元素,显然无法满足上面的要求,但能匹配下面 ul 中的 p */ p:only-of-type { color: red; }<ul> <li>第一页</li> <li class="this">第二页</li> <li class="this">第三页</li> <p>第四页</p> </ul>而 :has 能做到,要选择前后没有相同类名的元素 ,也就是排除前后的 .this 。 排除前面的 .this /* 表示选择前面没有 .this 的 .this */ .this:not(.this ~) { }排除后面的 .this, /* 表示排除后面有 .this 的 .this */ .this:not(:has(~ .this)) { }两个做并集,也就选择到了唯一的 .this .this:not(:has(~ .this)):not(.this ~ *) { color: red; }bb.png图片 完整示例 3、CSS :has() 选择器之模仿 mac 电脑 dock 栏 利用 :has() 可以选择到前面的兄弟元素的特点,还能做出下面的动画效果 aa.gif图片 当鼠标滑入到一个元素时,该元素放大,该元素的前一个元素和后一个元素缩小,除了这三个元素之外的其他元素缩的更小并且有一定透明度; html 结构如下 <div class="box"> <div class="son">乔丹</div> <div class="son">科比</div> <div class="son">詹姆斯</div> <div class="son">奥尼尔</div> <div class="son">邓肯</div> <div class="son">卡特</div> <div class="son">麦迪</div> <div class="son">艾弗森</div> <div class="son">库里</div> <div class="son">杜兰特</div> </div>关键 css 代码 .son { ... ... ... &:hover { background-color: #67c23a; transform: scale(1.4); &+.son { transform: scale(1.1); // 后一个相邻的兄弟元素 } } }让前一个元素也缩放为原来的 1.1 /* 选择存在 后一个相邻的被hover的兄弟元素 的元素 */ .son:has(+ .son:hover) { transform: scale(1.2); }然后对这三个元素之外的其他元素缩放为原来的 0.8 .box:has(.son:hover) .son:not(:hover, :has(+ :hover), .son:hover + *) { transform: scale(0.8); opacity: 0.7; }.box:has(.son:hover) 表示选择子元素 son 被 hover 时的 .box .son:not(:hover, :has(+ :hover), .son:hover + *) 表示排除 son 元素里面被 hover 的元素,被 hover 的元素的前一个邻接的兄弟元素,被 hover 的元素的后一个邻接的兄弟元素; 完整示例 4、CSS :has() 选择器之单选题 bb.gif图片 这是个有趣的应用,当选择的是错误的选项时,选择题的标题和当前选择项标红。并且会给正确的选项添加动画效果提示用户这才是正确选项。 这里用 data-correct="false" 表示错误的选项,data-correct="true" 表示正确的选项。 <input type="radio" name="option" data-correct="false" id="option1" /> <label for="option1">Responsive design</label> <input type="radio" name="option" data-correct="true" id="option2" /> <label for="option2">Responsive design</label> <input type="radio" name="option" data-correct="false" id="option3" /> <label for="option3">Responsive design</label>选择错误选项时,标红当前选项。选择正确选项时标绿当前选项。 .question { --correct: #5ed235; /* 正确选项的颜色 */ --wrong: #f83d56; /* 错误选项的颜色 */ --wrong-bg: rgba(248, 61, 86, 0.8); --correct-bg: rgb(94, 210, 53, 0.8); } input[data-correct="false"]:checked+label { color: #fff; background-color: var(--wrong); border-color: var(--wrong); } input[data-correct="true"]:checked+label { color: #fff; background-color: var(--correct); border-color: var(--correct); }选择错误选项时,标红标题; 这里用 :has 选择器获取子元素中有错误选项选中时。 .question:has(input[data-correct="false"]:checked) { .questionHeader { box-shadow: inset 0 7px 0 0 var(--wrong); background-color: var(--wrong-bg); } }并且给正确选项增加提示动画 .question:has(input[data-correct="false"]:checked) { input[data-correct="true"]+label { animation: flash 2s infinite; } } @keyframes flash { 0% { background-color: white; } 25% { background-color: #5ed235; } 50% { background-color: white; } 75% { background-color: #5ed235; } 100% { background-color: white; } }选择正确选项时,标绿标题; .question:has(input[data-correct="true"]:checked) { .questionHeader { box-shadow: inset 0 7px 0 0 var(--correct); background-color: var(--correct-bg); } }完整示例 总结 本文介绍了 :has()选择器的基本用法以及四个实际应用; 选择父元素和前面的兄弟元素 :has() 选择器中的 且 和 或 选择一个范围内的元素 在 :has()选择器出来之前,使用 CSS 是无法直接选择到父级元素和前面的兄弟元素的,但 :has()选择器的出现使这个变成了可能; 如果对本文感兴趣或对你有帮助,麻烦动动你们的发财手,点点赞~
技术教程
# Web前端
易航
1年前
0
68
0
上一页
1
2
3
...
5
下一页