易航 发布的文章 - 易航博客
首页
文章分类
源码资源
技术教程
程序软件
文创娱乐
玄学修炼
关于我们
其他页面
网站统计
友情链接
用户留言
高清壁纸
关于易航
热门文章
Joe再续前缘主题 - 本站同款
易航网址导航系统 – 功能强大,轻量易用
Js自动播放HTML音乐(不受浏览器限制,无需先与浏览器交互,无需对浏览器进行修改)
JsonDb-PHP轻量级文件数据库系统
Typecho一键调整网站为冬天情景插件
标签搜索
PHP
网站源码
Web前端
PHP源码
Typecho
课程资料
HTML源码
Typecho插件
武术内功
Joe主题
Web
Android软件
国漫
网络协议
Windows程序
MySQL
Windows
小说
Linux程序
Java源码
发布
登录
注册
找到
176
篇与
易航
相关的结果
2024-12-04
一个简单而高效的论坛服务,几分钟之内构建属于自己的社区
flarum 一个简单而高效的论坛软件,不臃肿、不复杂、不过度依赖。几分钟之内构建属于自己的社区。旨在为您的网站构建出色的社区。图片 特点 快速且简单:Flarum 没有复杂的依赖关系,没有冗余功能,界面简洁。它使用PHP构建,易于部署,界面由Mithril这个轻量级的JavaScript框架驱动,性能出色。 美观且响应式:Flarum 被设计为跨平台一致且直观,用户体验友好,是为人类设计的论坛软件。 强大且可扩展:您可以自定义、扩展并集成Flarum以适应您的社区需求。Flarum的架构非常灵活,拥有强大的扩展API。 功能 社区平台:Flarum 不论社区大小,都能在各个层面上表现出色。通过扩展来增强Flarum核心体验,您可以根据需要定制您的社区。 发现扩展: Flarum 提供了丰富的扩展,让您可以调整Flarum以满足特定需求。 群组和权限:权限组允许您轻松配置权限和成员。您可以授予对类别的访问权限,同时定义全局和类别限制的操作,如版主管理、标记等。 强大的编辑器:Flarum 支持简单的BBCode/Markdown编辑器,也支持完整的所见即所得(WYSIWYG)编辑器,以满足不同用户的需求。 样式和主题:通过管理员外观设置页面轻松自定义,安装主题或使用自定义CSS完全修改外观,CSS会自动集成到所有页面和扩展中。创意无限! 通知和参与:使用浏览器内通知、电子邮件或各种其他渠道提高用户参与度。安装WebSocket扩展可以让您社区的互动性更强,实现实时更新。 无限扩展:以上只是Flarum提供的一部分功能,有数百个扩展可供选择,您可以根据需要调整Flarum!如果您需要一些完全独特或前所未有的功能,您可以轻松扩展或委托扩展Flarum。 源码地址 隐藏内容,请前往内页查看详情
源码资源
# 网站源码
# PHP源码
易航
2天前
0
9
0
2024-12-04
一个快速创建专业logo的工具,完全开源,允许用户自定义风格和功能
logocreator 一个快速创建专业logo的工具,并且是完全开源的,允许用户自定义风格和功能。图片图片 技术栈 Flux Pro 1.1 on Together AI:用于logo生成的核心技术。 Next.js with TypeScript:作为应用程序框架。 Shadcn:用于UI组件。 Tailwind:用于样式。 Upstash Redis:用于速率限制。 Clerk:用于认证。 Plausible & Helicone:用于分析和可观察性。 运行 克隆仓库:git clone https://github.com/Nutlope/logocreator 创建一个.env文件,并添加你的Together AI API密钥:TOGETHER_API_KEY= 运行npm install安装依赖,然后运行npm run dev本地运行项目。 未来任务 创建一个带有用户logo历史的仪表板。 支持SVG导出,而不仅仅是PNG。 增加对额外风格的支持。 添加图像大小的下拉选择(最大可支持1440x1440)。 在使用自己的Together AI密钥时显示大致价格。 允许上传参考logo(使用视觉模型读取)。 使用我的logo制作器重新设计流行品牌logo,并在展示中展示。 工具地址 隐藏内容,请前往内页查看详情
源码资源
# 网站源码
# HTML源码
易航
2天前
1
19
0
2024-12-04
PHP 纤程:它真的能实现异步执行吗?
图片图片 PHP 8.1 引入了 Fibers,这让许多开发者好奇:它能否打破 PHP 作为单线程同步语言的固有局限,让它像 JavaScript 和 Node.js 那样实现异步操作?答案并非简单的肯定或否定:Fibers 本身并不提供真正的异步执行,但它为更高效的任务管理提供了强大的机制。下文将深入探讨这一概念。 什么是 PHP 纤程? PHP 纤程是一种协作式多任务处理机制。它允许你暂停和恢复代码的特定部分,而不会阻塞整个 PHP 进程。你可以把纤程想象成一种特殊的函数,它能够将执行控制权交回主程序,并在需要时从之前暂停的地方继续执行。 纤维的主要特点 可启动、暂停和恢复执行。 在单一的 PHP 进程内运行,不涉及多线程。 尤其适用于构建非阻塞代码。 当纤程暂停时会发生什么? 当使用 Fiber::suspend() 暂停纤程时,执行控制权会返回主 PHP 脚本。这意味着: 主程序可以继续执行其他部分。 纤程的执行暂停,直到被 resume() 唤醒。 例如: $fiber = new Fiber(function () { echo "Fiber started\n"; Fiber::suspend(); echo "Fiber resumed\n"; }); echo "Before Fiber\n"; $fiber->start(); echo "After Fiber Start\n"; $fiber->resume(); echo "After Fiber Resume\n";输出: Before Fiber Fiber started After Fiber Start Fiber resumed After Fiber Resume以下是具体情况 1、Fiber::suspend() 暂停纤程,并将执行控制权返回到启动纤程的主脚本 ($fiber->start() 之后的代码)。 2、主脚本继续执行。 3、当调用 resume() 时,纤程从暂停处恢复执行,直至完成。 恢复纤程是否会阻塞主进程? 调用 Fiber::resume() 恢复纤程会暂时阻塞主进程。这意味着: 在纤程完成或再次暂停之前,脚本的其他部分(或其他纤程)无法执行。 由于 PHP 的单线程特性,纤程的执行仍然是阻塞式的。 尽管纤程提供了更灵活的控制,但它并没有改变 PHP 的底层执行模型。 例如: $fiber = new Fiber(function () { echo "Processing Fiber...\n"; sleep(2); // Simulates a blocking task echo "Fiber Done\n"; }); echo "Before Fiber\n"; $fiber->start(); echo "Between Fiber Start and Resume\n"; $fiber->resume(); echo "After Fiber\n";输出: Before Fiber Processing Fiber... Fiber Done Between Fiber Start and Resume After Fiber在此示例中,纤程在调用 sleep(2) 期间会阻塞主进程。 因此,尽管纤程提供了一种更有效地组织代码的方式,但它们并不会神奇地实现并行处理或真正的异步执行。 它们只是提供了一种在单线程环境下更精细地控制执行流程的机制。 光纤如何仍然“不阻塞”? 纤程的“非阻塞”并非指并行执行,而是指其更优的任务管理能力。纤程暂停时不会阻塞主进程,而是将控制权交还给主脚本或事件循环。 这在基于事件驱动的库或框架(如 ReactPHP 或 Amp)中尤为有用: 长时间运行或等待的任务(例如数据库查询、API 调用)可以被暂停。 其他任务可以同时进行。 当任务准备好后,纤程会被恢复并继续执行。 这使得在单线程环境下能够模拟异步行为,从而提升效率。 事件循环和纤程 纤程通常与事件循环结合使用才能实现真正的非阻塞操作。事件循环负责跟踪多个任务并决定下一步执行哪个任务。其工作原理如下: 当遇到阻塞任务(例如数据库查询)时,纤程自动暂停。 事件循环选择并处理其他任务。 阻塞任务完成后,事件循环恢复相应的纤程。 像 Amp 和 ReactPHP 这样的库正是利用纤程和事件循环来实现异步任务处理。 为什么 Fiber 不是真正异步的 与 JavaScript 或 Node.js 中的异步编程(任务可以通过线程或事件循环并行运行)不同,PHP 纤程: 在单个 PHP 进程内同步执行。 通过允许开发者手动控制任务的暂停和恢复来实现协作式多任务处理。 换句话说: 纤程不引入并行性(任务仍然按顺序逐个执行)。 它们是一种更有效地管理和构建非阻塞代码的工具,而非真正的并行机制。 它们提供了一种在单线程环境下模拟异步行为的方式。 尽管 PHP 纤程本身并不能使 PHP 真正实现异步,但它们仍然是该语言的有力补充。原因如下: 1、改进的任务管理:纤程允许暂停和恢复任务,从而释放主进程去处理其他工作。 2、非阻塞工作流: 与事件循环结合使用时,纤程可以实现非阻塞任务处理,提升程序的并发性能。 3、同步执行的便利性: 恢复时,纤程同步执行,简化了代码逻辑,尽管会暂时阻塞进程。 这使得开发者无需处理复杂的回调或 Promise,就能以更线性的方式编写异步代码。 对于需要高效多任务处理的 PHP 应用(例如实时应用、后台作业或 API),纤程是一项重要的改进。它能够更好地管理任务并模拟异步行为。 然而,要实现真正的并行处理,仍然需要依赖外部解决方案,例如扩展或单独的进程来实现多线程。
技术教程
# PHP
易航
2天前
0
5
0
2024-12-03
Bing搜索引擎爆出严重XSS漏洞
最近在 Bing.com 上发现的跨站点脚本 (XSS) 漏洞引发了严重的安全问题,可能允许攻击者在 Microsoft 的互连应用程序之间发送精心设计的恶意请求。此漏洞在 Bing 的主域上发现,突显了与广泛的 Web 服务集成相关的风险,并突出了大规模利用的可能性。 该漏洞是在对 Bing 的 API 攻击面进行详细检查时发现的,特别关注 Bing 的主域如何与其他 Microsoft 服务交互。 研究表明,XSS 漏洞可用于在 Bing 的主域“www.bing.com”上执行任意 JavaScript。 研究人员“pedbap”观察到,然后可以利用此执行来制作针对用户默认登录的其他 Microsoft 应用程序(例如 Outlook、Copilot 和 OneDrive)的恶意请求。 攻击机制 攻击首先利用XSS 漏洞创建恶意链接。此链接允许攻击者在 Bing 的主域上下文中执行 JavaScript。鉴于 Bing 与其他 Microsoft 服务的集成,恶意脚本可以发送触发这些平台敏感操作的请求。 Bing 的广泛使用增强了攻击的潜在影响,每天有数百万用户与 Bing 的功能进行交互。一旦执行,恶意 JavaScript 就可以跨多个 Microsoft 服务访问用户数据。 这包括在 Outlook 中阅读电子邮件、访问 OneDrive 中的文件,以及可能在其他连接的应用程序中操作数据。Microsoft 生态系统的互连性质意味着一项服务中的漏洞可能会对其他服务产生级联影响。 这一发现凸显了对用户和 Microsoft 的重大安全影响。从 Bing 等受信任域执行 XSS 攻击的能力构成了严重威胁,因为它可能导致未经授权的数据访问和操纵。 图片图片 此外,此类漏洞可能是“可蠕虫的”(无需用户交互即可自动传播)增加了被广泛利用的风险。 Microsoft 已收到此漏洞的警报,预计将迅速采取措施修补受影响的系统。 建议用户在点击来自不受信任的来源的链接时要小心,并确保他们的浏览器和安全软件是最新的。 作为更广泛的安全措施的一部分,使用 Microsoft 服务的组织应检查其配置和访问控制,以防止未经授权的访问。 Bing.com 上的 XSS 漏洞严重提醒我们强大的 Web安全实践的重要性,尤其是在互连的数字生态系统中。 漏洞原理:https://medium.com/@pedbap/wormable-xss-www-bing-com-7d7cb52e7a12 演示视频:https://www.youtube.com/watch?v=_brKdFmYGdI86a8210e9ed855b00c00e5ccaa9fb0878embeds_widget_referrer=https%3A%2F%2Fmedium.com%2F%40pedbap%2Fwormable-xss-www-bing-com-7d7cb52e7a1286a8210e9ed855b00c00e5ccaa9fb0879embeds_referring_euri=https%3A%2F%2Fcdn.embedly.com%2F86a8210e9ed855b00c00e5ccaa9fb08710embeds_referring_origin=https%3A%2F%2Fcdn.embedly.com86a8210e9ed855b00c00e5ccaa9fb08711source_ve_path=OTY3MTQ
技术教程
# 网络安全
易航
3天前
2
15
0
2024-12-03
PHP 8.4 正式发布!🧨
图片 PHP 8.4 第一个正式发布版本今天发布。PHP 8.4 在很大程度上向后兼容 PHP 8.0 到 8.4,并带来了一些新功能。 PHP 8.4 新增/变更功能 curl_getinfo 支持 CURLINFO_POSTTRANSFER_TIME_T curl_version() 支持 feature_list 新增 http_(get|clear)_last_response_headers 函数 新增 CURLOPT_PREREQFUNCTION 选项 新增 CURLOPT_DEBUGFUNCTION 选项 新增 CURLOPT_SERVER_RESPONSE_TIMEOUT 选项,以替换 CURLOPT_FTP_RESPONSE_TIMEOUT 新增 CURLOPT_TCP_KEEPCNT 选项 新增round()函数 新增 mb_trim、mb_ltrim 和 mb_rtrim 函数 DateTime(Immutable) 类新增 createFromTimestamp 方法 phpinfo 显示 PHP 整数大小信息 DateTime(Immutable) 类新增 get/setMicrosecond 方法 新增函数 request_parse_body PCRE2 升级及相关正则表达式变化 PHP 8.4 语法/功能变更 OpenSSL:最低要求的 OpenSSL 版本提升至 1.1.1 MBString:Unicode 字符数据库更新至版本 16 exit/die 从语言构造变为函数 CURLOPT_DNS_USE_GLOBAL_CACHE 不再有效 密码哈希:默认 Bcrypt 成本从 10 变为 12 PHP_ZTS 和 PHP_DEBUG 常量值类型从 int 变为 bool Opcache:JIT 启用方式的 INI 变更 round() 函数:无效的舍入模式将抛出 \ValueError 异常 Curl:最低要求的 libcurl 版本提升至 7.61.0 PHP 8.4 弃用功能 隐式可为空的参数声明被弃用 E_STRICT 常量被弃用 调用 session_set_save_handler() 时使用超过 2 个参数被弃用 CSV:必须提供 $escape 参数 CURLOPT_BINARYTRANSFER 被弃用 PHP 8.4 移除功能 Pspell 扩展从 PHP 核心移至 PECL IMAP 扩展从 PHP 核心移至 PECL OCI8 和 PDO-OCI 扩展从 PHP 核心移至 PECL
技术教程
# PHP
易航
3天前
0
20
0
2024-11-30
PHP 8.4 新功能
图片图片 PHP 8.4 的正式发布计划于下周,即 2024 年 11 月 21 日发布。在此次发布之前,一系列预发布版本(Alpha、Beta 和候选版本)允许社区测试新功能并进行最后一刻的调整。PHP 8.4 引入了多项改进,包括用于操作数组的新功能、受其他语言启发的属性钩子以及简化的语法。让我们一起回顾一下此版本中要记住的新功能。 Property Hooks Property Hooks 是 8.4 版中引入的主要功能之一。PHP 实现的灵感来自其他语言(如 Kotlin、C#、Swift、Javascript 或 Python)中的现有实现。让我们举几个例子来说明 Property Hooks 的用途以及如何使用它们: <?php declare(strict_types=1); class Foo { private string $id; public function getId(): string { return $this->id; } public function setId(string $id): void { $this->id = $id; } }从 PHP 8 开始,由于 Constructor Property Promotion,可以通过以下方式进行简化: <?php class Foo { function __construct(public string $id) {} }在我们必须保留访问器 (getter/setter) 的情况下,我们会考虑包含业务逻辑的丰富模型,我们失去了更轻量级语法的优势。PHP 版本 8.4 和引入的 Property Hooks 修复了这个问题: <?php class Foo { public function __construct( public string $id { get { return '#' . $this->id; } set(string $id){ $this->id = mb_strtoupper($id); } }, ){} }乍一看,语法似乎令人困惑,但就像任何语法演变一样,随着时间的推移,您会习惯它。 Property Hooks 引入的另一种可能性是能够在 property 上定义接口。 使用这个新版本的 PHP,我们可以编写以下定义: <?php interface HasId { public string $id { get; set; } } // Les fonction fléchées peuvent être aussi utilisées pour raccourcir la syntaxe class Foo implements HasId { function __construct( public string $id { get => '#' . $this->id; set (string $id) => $this->id = mb_strtoupper($id); }, ) {} } // Le contrat d’interface est également respecté sans l’utilisation des Property Hooks en déclarant publiquement la propriété class Bar implements HasId { function __construct(public string $id) {} }一个完整的案例 <?php declare(strict_types=1); interface HasId { public string $id { get; set; } } class Foo implements HasId { function __construct( public string $id { get => '#' . $this->id; set (string $id) => $this->id = mb_strtoupper($id); }, ) {} } class Bar implements HasId { function __construct(public string $id) {} } class Baz { public function display(HasId $object): void { echo $object->id . PHP_EOL; } public function update(HasId $object, string $id): void{ $object->id = $id; $this->display($object); } } $foo = new Foo(id: 'FOO'); $bar = new Bar(id: 'BAR'); $baz = new Baz(); $baz->display($foo); $baz->update($foo, 'foo'); $baz->display($bar); $baz->update($bar, 'bar');设置具有非对称可见性的类属性的可见性 非对称可见性 允许您根据相关操作是读取还是写入属性,对同一属性设置不同的可见性。然后,可以定义读取访问的公共可见性和写入访问的更受限的可见性(受保护或私有)。接下来的两个类是等效的,随着非对称可见性的引入,语法更加简洁。 <?php class Foo { function __construct(private string $id,) { // } public function getId(): string { return $this->id; } } class Bar { function __construct( public private(set) string $id, ) {} }不对称可见性附带一些规则,这些规则很容易理解: 属性必须被类型化(来自 PHP 实现的约束) 只关注对象属性,静态属性不能从中受益(这也是 PHP 实现产生的约束)。 对于对象属性,如果该属性设置为 private(set),则不能在与当前类不同的范围内修改链接对象。但是,如果链接对象的属性被定义为 Properties,则可以对其进行修改。 对于数组类型属性,如果该属性已设置为 private(set),则无法在当前类的范围之外操作数组(添加元素、删除元素等)。 set 的可见性不能比 get 的可见性更宽。 对于类继承或接口协定,可见性不能更严格,也可以更广泛。 在 readonly中定义的属性(在 PHP 8.1 中引入)和 public private(set) 中定义的属性之间的差异非常小,但值得一提。上面定义的不对称可见性将具有相同的效果,只是它允许内部更改。换句话说, readonly 限制了 mutation,并且在实例化期间还具有唯一写入的效果。 管独立于 Property Hook 运行,但这两种机制可以结合使用。此处提供了这两种功能的示例。 对惰性对象的原生支持 惰性对象 是其实际实例化将被推迟到实际需要的时间(因为它们的实例化通常很昂贵)的对象。出于性能原因,它们在 Doctrine 和 Symfony 中被大量使用。 Martin Fowler 在他的理论定义中建立了四种可能的实现。其中两个是不需要修改现有对象的实现:Ghost 和 Proxy。这些是通过在 PHP Reflection API 中添加方法保留和访问的。 在这两种情况下,都会创建一个初始化函数。对于 Ghosts,该函数将直接作用于对象。对于 Proxy,它是实例化惰性对象的函数,然后将交互反馈给真实实例。 在这两种情况下,实例化机制都是通过访问真实对象的 state 来触发的:读取或写入属性、测试属性是否具有值、克隆等。可以通过特定函数对特定属性禁用此行为,在某些情况下,可以定义或参数化,例如用于调试或序列化。 由于它是为非常有限且根据定义相当抽象的用例保留的,因此我们邀请您阅读 RFC 以发现代码示例和两种不同实现的详细功能。 不带括号的类实例化 更有趣的是,这种演变通过在实例化新对象时使括号变得多余,从而减轻了语法的负担。 <?php // Avant et toujours valide $o = (new Operation(0))->add(10)->multiply(2); // Depuis PHP 8.4 $o = new Operation(0)->add(10)->multiply(2);解析 HTML5 创建了一个新的 DOM\HTMLDocument 类来允许 HTML5 解析,为了确保与 HTML4 的向后兼容性,当前类将保持不变。这两个类保持相同的 API,因此可以以相同的方式使用。只有构造逻辑已更改,并且需要使用其中一个可用的工厂。用 C 语言编写的底层库是 Lexbor。 新的函数 添加了四个作用于数组的新函数,它们补充了现有函数。 array_find array_find 将返回传递给它的回调函数的第一个匹配项 <?php $array = ['A', 'AA', 'AAA']; $arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3]; array_find($array, static fn(string $value): bool => strlen($value) > 2);// returns AAA array_find($array, static fn(string $value): bool => strlen($value) > 3);// returns null array_find($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns 1array_find_key array_find_key 的工作方式与上一个函数相同,但返回 key 而不是 value: <?php $array = ['A', 'AA', 'AAA']; $arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3]; array_find_key($array, static fn(string $value): bool => strlen($value) > 2); // returns 2 array_find_key($array, static fn(string $value): bool => strlen($value) > 3); // returns null array_find_key($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns Aarray_any 如果数组中至少有一个元素与回调函数匹配,array_any 将返回布尔值 true: <?php $array = ['A', 'AA', 'AAA']; $arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3]; array_any($array, static fn(string $value): bool => strlen($value) > 2)); // returns true array_any($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns truearray_all 如果数组中的所有元素都与回调函数匹配,array_all 将返回布尔值为 true <?php $array = ['A', 'AA', 'AAA']; $arrayWithKeys = ['A' => 1, 'AA' => 2, 'AAA' => 3]; array_all($array, static fn(string $value): bool => strlen($value) < 4)); // returns true array_all($arrayWithKeys, static fn(int $value, string $key): bool => $value === strlen($key)); // returns true改进和错误修复 除其他事项外,我们保留了以下更改: 添加了新的多字节函数来操作字符串 mb_trim、mb_ltrim、mb_rtrim、mb_ucfirst mb_lcfirst。 添加了用于从时间戳创建 DateTime 对象的新函数。 exit 和 die 的元素失去了它们的地位,取而代之的是特殊功能。在不破坏向后兼容性的情况下,这允许对函数进行类似的操作,例如,更精确地键入输入参数。 以下扩展正在从核心中移出以加入 PECL:Pspel、IMAP、OCI8 和 PDO-OCI。 为舍入功能添加了四种新的舍入模式 在 Sodium 中添加了两种新的加密算法,并升级了 OpenSSL。 添加了 cURL 的新选项。 完整的更新日志:https://www.php.net/ChangeLog-8.php
技术教程
# PHP
易航
6天前
0
21
0
2024-11-23
高燃CG视频
高燃CG视频
文创娱乐
易航
11月23日
0
69
2
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前端
易航
11月23日
0
40
0
2024-11-23
身体出现这3个高危迹象,说明你真的累过头了!
图片 图片 图片 图片 图片 图片 图片 图片 图片
技术教程
易航
11月23日
0
35
2
1
2
...
20
下一页
易航博客