扫码关注官方订阅号
工具推荐
中文短剧剧本制作平台
AI短剧一键生成成片
AI短剧协同制作平台
低成本歌曲 MV、视频生成
正文
星瑶君_6231
发布时间:2025-10-06 14:59:00
932人浏览过
来源于php中文网
原创
在现代web开发中,为了实现更丰富的用户体验和更灵活的ui设计,我们常常需要对原生的html 元素进行定制。这包括添加图片、自定义样式,甚至完全重构其交互逻辑。然而,当页面中存在多个这样的自定义组件时,如何确保它们能够独立工作,互不干扰,是一个常见的挑战。本文将通过一个带图片的自定义下拉选择框示例,详细讲解如何利用jquery解决多实例组件的事件隔离和内容管理问题。
为了实现自定义的下拉选择框,我们通常会隐藏原生的 元素,然后使用其他HTML元素(如 、、、)来模拟其外观和行为。以下是构成单个自定义下拉框的HTML结构示例:<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <div class="box" id="one"> <!-- 原生select,用于存储数据,但会被隐藏 --> <select class="vodiapicker"> <option>Select one</option> <option value="en" class="test" data-thumbnail="images/3.png"> English </option> <option value="au" data-thumbnail="images/3.png">Engllish (AU)</option> </select> <!-- 自定义下拉框的显示部分 --> <div class="lang-select"> <!-- 按钮,显示当前选中的项 --> <button class="btn-select" value=""></button> <!-- 下拉列表容器 --> <div class="b"> <!-- 实际的下拉选项列表 --> <ul id="a"></ul> </div> </div> </div> <div class="box" id="two"> <!-- 另一个独立的自定义下拉框 --> <select class="vodiapicker"> <option>Select one</option> <option value="fr" class="test" data-thumbnail="images/3.png"> French </option> <option value="ca" data-thumbnail="images/3.png">French (CA)</option> </select> <div class="lang-select"> <button class="btn-select" value=""></button> <div class="b"> <ul id="a"></ul> </div> </div> </div>结构说明: .box:作为每个独立自定义下拉框的外部容器,通过唯一的 id (如 one, two) 来区分不同实例。 .vodiapicker:这是原生的 元素,它被设置为 display: none; 隐藏起来,但其 option 标签中的 value 和 data-thumbnail 属性是我们需要提取的数据源。 .lang-select:包含自定义下拉框的可见部分。 .btn-select:一个 元素,用于显示当前选中的项(包含图片和文本),并作为触发下拉列表显示/隐藏的开关。 .b:下拉列表的容器,初始状态为 display: none;。 ul#a:实际的下拉选项列表,其中的 元素将通过JavaScript动态生成。 重要提示: 在上述HTML结构中,ul 元素使用了相同的 id="a"。虽然在jQuery中可以通过上下文查找来避免直接冲突,但从HTML规范和最佳实践来看,ID应该在文档中是唯一的。在实际项目中,建议将 id="a" 改为类名,或者生成唯一的ID,例如 ul class="dropdown-list",然后通过 $(this).find(".dropdown-list") 进行查找。本文的解决方案在现有结构下依然有效,但请注意此潜在问题。 二、 CSS样式:美化与隐藏 CSS用于隐藏原生的 元素,并为自定义的按钮和下拉列表提供样式,使其看起来像一个统一的组件。.vodiapicker { display: none; /* 隐藏原生的select元素 */ } #a { padding-left: 0px; } #a img, .btn-select img { width: 18px; /* 设置图片宽度 */ } #a li { list-style: none; /* 移除列表项默认样式 */ padding-top: 5px; padding-bottom: 5px; cursor: pointer; /* 鼠标悬停显示手型 */ } #a li:hover { background-color: #f4f3f3; /* 列表项悬停背景色 */ } #a li img { margin: 5px; } #a li span, .btn-select li span { margin-left: 30px; } /* 下拉列表容器样式 */ .b { display: none; /* 初始隐藏 */ width: 100%; max-width: 350px; box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 5px; background-color: #fff; /* 背景色 */ position: absolute; /* 确保它浮动在其他内容之上 */ z-index: 1000; /* 确保层级高于其他元素 */ } /* 按钮样式 */ .btn-select { margin-top: 10px; width: 100%; max-width: 350px; height: 34px; border-radius: 5px; background-color: #fff; border: 1px solid #ccc; text-align: left; /* 文本左对齐 */ padding: 0 10px; /* 内边距 */ cursor: pointer; display: flex; /* 使得图片和文本可以并排显示 */ align-items: center; /* 垂直居中 */ } .btn-select li { list-style: none; float: left; /* 保持图片和文本在同一行 */ padding-bottom: 0px; } .btn-select:hover { background-color: #f4f3f3; border: 1px solid transparent; box-shadow: inset 0 0px 0px 1px #ccc; } .btn-select:focus { outline: none; /* 移除焦点时的边框 */ } .lang-select { /* margin-left: 50px; */ /* 根据需要调整 */ position: relative; /* 为绝对定位的.b提供参照 */ }三、 JavaScript逻辑:实现交互与隔离 JavaScript(jQuery)是实现自定义下拉框功能的核心。它负责初始化每个下拉框、处理点击事件、更新显示内容,并确保多个实例之间互不干扰。$(function() { // 1. 初始化每个自定义下拉框 $(".box").each(function() { let langArray = []; // 声明为let,确保每个box有独立的langArray // 遍历当前box内的原生select的option,提取数据并构建自定义列表项 $(this) .find(".vodiapicker option") .each(function() { let img = $(this).attr("data-thumbnail"); let text = this.innerText; let value = $(this).val(); let item = '<li><img src="' + img + '" alt="" value="' + value + '"><span>' + text + "</span></li>"; langArray.push(item); }); // 将构建好的列表项填充到当前box的ul#a中 $(this).find("#a").html(langArray.join('')); // 使用join('')避免多余逗号 // 设置按钮的初始显示内容为第一个选项 $(this).find(".btn-select").html(langArray[0]); // 设置按钮的初始值为"en" (可根据实际需求调整) $(this).find(".btn-select").attr("value", "en"); }); // 2. 实现点击外部关闭所有下拉框的功能 $(document).click(function(event) { // 如果点击的不是.btn-select按钮,则关闭所有打开的下拉框 if (!$(event.target).closest(".lang-select").length) { $(".box").each(function() { if ($(this).find(".b").is(':visible')) { $(this).find(".b").toggle(); } }); } }); // 3. 处理列表项(li)点击事件 $("li").click(function() { // 获取被点击li项的图片、值和文本 let img = $(this).find("img").attr("src"); let value = $(this).find("img").attr("value"); let text = $(this).find("span").text(); // 确保获取到span内的文本 let item = '<li><img src="' + img + '" alt="" /><span>' + text + "</span></li>"; // 找到当前li所属的自定义下拉框的按钮,并更新其内容和值 $(this).parents("div.lang-select").find(".btn-select").html(item); $(this).parents("div.lang-select").find(".btn-select").attr("value", value); // 关闭当前li所属的下拉列表 $(this).parents("div.lang-select").find(".b").toggle(); }); // 4. 处理按钮(.btn-select)点击事件 $(".btn-select").click(function(event) { event.stopPropagation(); // 阻止事件冒泡到document,防止立即关闭 const currentBoxId = $(this).parents(".box").attr("id"); // 关闭所有其他打开的下拉框 $(".box").each(function() { if ($(this).attr("id") !== currentBoxId && $(this).find(".b").is(':visible')) { $(this).find(".b").toggle(); } }); // 切换当前点击按钮对应的下拉列表的显示状态 $(this).parents("div.lang-select").find(".b").toggle(); }); });JavaScript逻辑详解: JSON Toolkit JSON文件多功能工具。支持格式化、验证、压缩、键排序及点记法路径查询。零依赖。 下载 初始化每个自定义下拉框 ($(".box").each(...)): 使用 $(".box").each() 遍历页面上的每一个自定义下拉框容器。这是实现多实例独立性的关键。 在每个 each 循环内部,langArray 被声明为 let,确保它是一个局部变量,只存储当前 box 的选项数据,从而隔离了不同下拉框的内容。 通过 $(this).find(".vodiapicker option").each(...) 遍历当前 box 内的隐藏 选项,提取 data-thumbnail、innerText 和 value。 动态生成 HTML字符串,并将其添加到 langArray。 $(this).find("#a").html(langArray.join('')):将收集到的 元素填充到当前 box 的 ul#a 中。使用 join('') 是为了避免数组元素之间默认的逗号分隔。 $(this).find(".btn-select").html(langArray[0]):将第一个选项设置为按钮的初始显示内容。 $(this).find(".btn-select").attr("value", "en"):设置按钮的初始值。 实现点击外部关闭功能 ($(document).click(...)): 这是一个全局事件监听器,当用户点击页面上任何位置时触发。 !$(event.target).closest(".lang-select").length 判断点击事件是否发生在任何一个 .lang-select 元素内部。如果不是,则意味着点击了下拉框外部。 如果点击在外部,则遍历所有 .box,找到所有当前可见的下拉列表 (.b) 并将其关闭 (.toggle())。 处理列表项()点击事件 ($("li").click(...)): 当用户点击下拉列表中的某个 选项时触发。 $(this).parents("div.lang-select") 是关键,它向上遍历DOM树,找到当前被点击 所属的 .lang-select 容器。这样可以确保只更新和关闭正确的下拉框实例。 提取被点击 的图片 src、value 和文本,然后构建新的 HTML来更新按钮内容。 $(this).parents("div.lang-select").find(".btn-select").html(item):更新对应按钮的显示。 $(this).parents("div.lang-select").find(".btn-select").attr("value", value):更新对应按钮的值。 $(this).parents("div.lang-select").find(".b").toggle():关闭当前下拉列表。 处理按钮(.btn-select)点击事件 ($(".btn-select").click(...)): 当用户点击自定义下拉框的按钮时触发。 event.stopPropagation():非常重要!它阻止点击事件向上冒泡到 document,从而避免了在按钮点击后立即触发 $(document).click() 导致下拉列表瞬间打开又关闭的问题。 获取当前点击按钮所属的 .box 的 id (currentBoxId)。 遍历所有 .box,如果某个 box 的 id 与 currentBoxId 不同,并且它的下拉列表 (.b) 是可见的,就将其关闭。这确保了在任何时候只有一个下拉列表是打开的(互斥性)。 $(this).parents("div.lang-select").find(".b").toggle():最后,切换当前点击按钮对应的下拉列表的显示状态。 四、注意事项与最佳实践 作用域管理: 在处理多个组件实例时,始终使用 $(this)、find()、parents() 等jQuery方法来限定操作范围,避免使用全局选择器(如直接 $("#a"))导致操作影响所有实例。 重复ID问题: 尽管jQuery的上下文查找在一定程度上缓解了重复ID的问题,但为了符合HTML规范和提高代码可维护性,强烈建议确保页面中所有ID都是唯一的。可以考虑使用类名代替,或者在初始化时为每个 ul 动态生成唯一的ID。 事件冒泡: 理解事件冒泡机制对于处理复杂交互至关重要。使用 event.stopPropagation() 可以有效控制事件传播,避免不必要的副作用。 图片与按钮点击: 原始问题提到图片可能会阻碍按钮点击。这通常发生在图片元素完全覆盖按钮,导致点击事件被图片捕获。解决方案可以是: 确保图片作为按钮内容的子元素,且按钮本身有足够的 padding。 使用CSS pointer-events: none; 在图片上禁用鼠标事件,让点击事件“穿透”到下面的按钮。 将图片作为按钮的背景图片设置,而不是直接作为 元素插入。 代码可读性: 使用 let 替代 var 可以更好地管理变量作用域,减少潜在的错误。为变量和函数选择有意义的名称,并添加注释,可以大大提高代码的可读性和可维护性。 性能优化: 对于大量列表项,考虑使用事件委托 ($(document).on('click', 'li', function(){...})) 而不是直接绑定到每个 li 元素,这样可以减少事件处理器的数量,提高性能。不过,在本例中,由于列表项是动态生成的,并且 $("li").click() 也能正确工作(它会在DOM加载时绑定到所有现有和未来匹配的 li 元素,因为jQuery 3.x 默认行为),所以影响不大。 五、总结 通过上述HTML结构、CSS样式和jQuery脚本的协同工作,我们成功地创建了多个带有图片支持的自定义下拉选择框。关键在于通过 each 循环对每个实例进行独立初始化,并通过 $(this).parents(...) 等方法精确限定事件处理的作用域,同时利用 $(document).click() 实现全局关闭,并添加互斥逻辑确保只有一个下拉框打开。这种方法不仅解决了多实例组件的交互冲突,也为开发更灵活、更具视觉吸引力的Web界面提供了有力的支持。
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <div class="box" id="one"> <!-- 原生select,用于存储数据,但会被隐藏 --> <select class="vodiapicker"> <option>Select one</option> <option value="en" class="test" data-thumbnail="images/3.png"> English </option> <option value="au" data-thumbnail="images/3.png">Engllish (AU)</option> </select> <!-- 自定义下拉框的显示部分 --> <div class="lang-select"> <!-- 按钮,显示当前选中的项 --> <button class="btn-select" value=""></button> <!-- 下拉列表容器 --> <div class="b"> <!-- 实际的下拉选项列表 --> <ul id="a"></ul> </div> </div> </div> <div class="box" id="two"> <!-- 另一个独立的自定义下拉框 --> <select class="vodiapicker"> <option>Select one</option> <option value="fr" class="test" data-thumbnail="images/3.png"> French </option> <option value="ca" data-thumbnail="images/3.png">French (CA)</option> </select> <div class="lang-select"> <button class="btn-select" value=""></button> <div class="b"> <ul id="a"></ul> </div> </div> </div>
结构说明:
重要提示: 在上述HTML结构中,ul 元素使用了相同的 id="a"。虽然在jQuery中可以通过上下文查找来避免直接冲突,但从HTML规范和最佳实践来看,ID应该在文档中是唯一的。在实际项目中,建议将 id="a" 改为类名,或者生成唯一的ID,例如 ul class="dropdown-list",然后通过 $(this).find(".dropdown-list") 进行查找。本文的解决方案在现有结构下依然有效,但请注意此潜在问题。
CSS用于隐藏原生的 元素,并为自定义的按钮和下拉列表提供样式,使其看起来像一个统一的组件。
.vodiapicker { display: none; /* 隐藏原生的select元素 */ } #a { padding-left: 0px; } #a img, .btn-select img { width: 18px; /* 设置图片宽度 */ } #a li { list-style: none; /* 移除列表项默认样式 */ padding-top: 5px; padding-bottom: 5px; cursor: pointer; /* 鼠标悬停显示手型 */ } #a li:hover { background-color: #f4f3f3; /* 列表项悬停背景色 */ } #a li img { margin: 5px; } #a li span, .btn-select li span { margin-left: 30px; } /* 下拉列表容器样式 */ .b { display: none; /* 初始隐藏 */ width: 100%; max-width: 350px; box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 5px; background-color: #fff; /* 背景色 */ position: absolute; /* 确保它浮动在其他内容之上 */ z-index: 1000; /* 确保层级高于其他元素 */ } /* 按钮样式 */ .btn-select { margin-top: 10px; width: 100%; max-width: 350px; height: 34px; border-radius: 5px; background-color: #fff; border: 1px solid #ccc; text-align: left; /* 文本左对齐 */ padding: 0 10px; /* 内边距 */ cursor: pointer; display: flex; /* 使得图片和文本可以并排显示 */ align-items: center; /* 垂直居中 */ } .btn-select li { list-style: none; float: left; /* 保持图片和文本在同一行 */ padding-bottom: 0px; } .btn-select:hover { background-color: #f4f3f3; border: 1px solid transparent; box-shadow: inset 0 0px 0px 1px #ccc; } .btn-select:focus { outline: none; /* 移除焦点时的边框 */ } .lang-select { /* margin-left: 50px; */ /* 根据需要调整 */ position: relative; /* 为绝对定位的.b提供参照 */ }
JavaScript(jQuery)是实现自定义下拉框功能的核心。它负责初始化每个下拉框、处理点击事件、更新显示内容,并确保多个实例之间互不干扰。
$(function() { // 1. 初始化每个自定义下拉框 $(".box").each(function() { let langArray = []; // 声明为let,确保每个box有独立的langArray // 遍历当前box内的原生select的option,提取数据并构建自定义列表项 $(this) .find(".vodiapicker option") .each(function() { let img = $(this).attr("data-thumbnail"); let text = this.innerText; let value = $(this).val(); let item = '<li><img src="' + img + '" alt="" value="' + value + '"><span>' + text + "</span></li>"; langArray.push(item); }); // 将构建好的列表项填充到当前box的ul#a中 $(this).find("#a").html(langArray.join('')); // 使用join('')避免多余逗号 // 设置按钮的初始显示内容为第一个选项 $(this).find(".btn-select").html(langArray[0]); // 设置按钮的初始值为"en" (可根据实际需求调整) $(this).find(".btn-select").attr("value", "en"); }); // 2. 实现点击外部关闭所有下拉框的功能 $(document).click(function(event) { // 如果点击的不是.btn-select按钮,则关闭所有打开的下拉框 if (!$(event.target).closest(".lang-select").length) { $(".box").each(function() { if ($(this).find(".b").is(':visible')) { $(this).find(".b").toggle(); } }); } }); // 3. 处理列表项(li)点击事件 $("li").click(function() { // 获取被点击li项的图片、值和文本 let img = $(this).find("img").attr("src"); let value = $(this).find("img").attr("value"); let text = $(this).find("span").text(); // 确保获取到span内的文本 let item = '<li><img src="' + img + '" alt="" /><span>' + text + "</span></li>"; // 找到当前li所属的自定义下拉框的按钮,并更新其内容和值 $(this).parents("div.lang-select").find(".btn-select").html(item); $(this).parents("div.lang-select").find(".btn-select").attr("value", value); // 关闭当前li所属的下拉列表 $(this).parents("div.lang-select").find(".b").toggle(); }); // 4. 处理按钮(.btn-select)点击事件 $(".btn-select").click(function(event) { event.stopPropagation(); // 阻止事件冒泡到document,防止立即关闭 const currentBoxId = $(this).parents(".box").attr("id"); // 关闭所有其他打开的下拉框 $(".box").each(function() { if ($(this).attr("id") !== currentBoxId && $(this).find(".b").is(':visible')) { $(this).find(".b").toggle(); } }); // 切换当前点击按钮对应的下拉列表的显示状态 $(this).parents("div.lang-select").find(".b").toggle(); }); });
JavaScript逻辑详解:
JSON文件多功能工具。支持格式化、验证、压缩、键排序及点记法路径查询。零依赖。
初始化每个自定义下拉框 ($(".box").each(...)):
实现点击外部关闭功能 ($(document).click(...)):
处理列表项()点击事件 ($("li").click(...)):
处理按钮(.btn-select)点击事件 ($(".btn-select").click(...)):
通过上述HTML结构、CSS样式和jQuery脚本的协同工作,我们成功地创建了多个带有图片支持的自定义下拉选择框。关键在于通过 each 循环对每个实例进行独立初始化,并通过 $(this).parents(...) 等方法精确限定事件处理的作用域,同时利用 $(document).click() 实现全局关闭,并添加互斥逻辑确保只有一个下拉框打开。这种方法不仅解决了多实例组件的交互冲突,也为开发更灵活、更具视觉吸引力的Web界面提供了有力的支持。
相关文章
JavaScript Vite 多入口怎么配置
如何在Tailwind CSS v3中配置独立容器查询插件?
怎么用CSS解决Android和iOS上1px物理边框差异
怎么在CSS Grid布局中快速定位导致布局错乱的网格隐式轨道?
如何在原生JS中动态创建link标签加载CSS?
相关标签:
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
如何使用 AWS SES Go SDK 发送带附件的邮件
2026-11-12 15:00
如何高效转置 Polars DataFrame 中二维数组列的维度
2026-11-12 15:11
AI办公竞争从模型能力转向成本与选择权:豆包工作开放第三方模型接入
2026-11-12 15:14
CSS 实现文本项从右至左逐个省略的响应式布局方案
2026-11-12 15:19
当贝盒子H5二代系列正式开售:8K解码、4K输出,老片源也能更清晰
2026-11-12 15:22
Laravel 9 CRUD: 正确哈希存储用户密码的完整实现
阿里重磅官宣千问大模型 Qwen4:核心能力全线进化,千问 App 现已全面接入预览版
2026-11-12 15:24
ESLint 命令行不指定文件时如何自动匹配?——详解配置驱动的文件发现机制
如何在 Spring Kafka 中实现手动同步提交并确保消息重试机制生效
2026-11-12 15:25
CSS 实现元素逐个从右向左省略(而非同时截断)的响应式布局方案
2026-11-12 15:28
热门AI工具
讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。
DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。
一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。
一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。
一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。
豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。
PixPix是一款面向电商视觉生产的AI商品图生成工具。
一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。
一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。
相关专题
jquery插件有jQuery UI、jQuery Validate、jQuery DataTables、jQuery Slick、jQuery LazyLoad、jQuery Countdown、jQuery Lightbox、jQuery FullCalendar、jQuery Chosen和jQuery EasyUI等。本专题为大家提供jquery插件相关的文章、下载、课程内容,供大家免费下载体验。
621
2023.09.12
操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。
1276
2023.10.13
jquery可以通过.remove() 方法、 .detach() 方法、.empty() 方法、.unwrap() 方法、.replaceWith() 方法、.html('') 方法和.hide() 方法来删除元素。更多关于jquery相关的问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。
2362
2023.11.10
hover()是jQuery中一个常用的方法,它用于绑定两个事件处理函数,这两个函数将在鼠标指针进入和离开匹配的元素时执行。想了解更多hover()的相关内容,可以阅读本专题下面的文章。
2168
2023.12.04
在jQuery中实现分页可以使用插件或者自定义实现。想了解更多jquery分页的相关内容,可以阅读本专题下面的文章。
513
2023.12.06
jquery中隐藏元素是非常重要的一个概念,在使用jquery隐藏元素之前,需要先了解css样式中关于元素隐藏的属性,比如display、visibility、opacity等属性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。
337
2024.02.23
jquery中高亮显示是指对页面搜索关键词时进行高亮显示,其实现办法:1、先获取要高亮显示的行,获取搜索的内容,再遍历整行内容,最后添加高亮颜色;2、使用“jquery highlight”高亮插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。
906
本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。
309
2026.01.13
本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。
20
2026.11.12
热门下载
相关下载
精品课程
共0课时 | 0人学习
共6课时 | 12.1万人学习
共79课时 | 161.8万人学习
共6课时 | 54.7万人学习
最新文章
PDF工具
微信扫码关注PHP中文网服务号
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn
返回顶部