HTML5 拖拽 API 深度解析

一、HTML5 拖拽 API 深度解析
1.1 背景与发展
HTML5 的拖拽 API 是为了解决传统拖拽操作复杂而设计的。传统方法依赖鼠标事件和复杂的逻辑计算,而 HTML5 提供了标准化的拖拽事件和数据传递机制,使得开发者能够快速实现从一个元素拖拽到另一个元素的交互。
1.2 拖拽 API 的核心工作原理
HTML5 拖拽 API 的核心包括以下几个步骤:
-
定义可拖拽元素
设置 HTML 元素的draggable属性为true:<div id="drag-item" draggable="true">可拖拽元素</div> -
处理拖拽事件
拖拽相关事件包括:dragstart:拖拽开始。drag:拖拽中(可用于实时显示位置)。dragend:拖拽结束。dragover:目标区域悬停。drop:放置到目标区域。
-
数据传递机制
使用dataTransfer对象存储拖拽时传递的数据:event.dataTransfer.setData("text/plain", event.target.id);
1.3 dataTransfer 对象详解
dataTransfer 是 HTML5 拖拽 API 的核心对象,用于在拖拽操作中传递数据。常用方法包括:
setData(format, data):设置数据。getData(format):获取数据。clearData():清除数据。
示例:
function dragStart(event) {event.dataTransfer.setData("text/plain", event.target.id);
}
二、需求分析
2.1 用户场景与功能拆解
实现一个课程表的核心目标是简化用户的课程安排操作,同时提供良好的交互体验。为了实现这些目标,我们需要从多个角度拆解用户的场景和功能需求。
2.1.1 用户场景
- 学生场景
- 学生可以根据自己的课程需求,自由安排每周的课程表。例如,用户可以将数学课安排在周一上午 9 点,并在拖拽过程中动态调整课程顺序。
- 用户希望避免时间冲突,例如将两个课程拖到同一时间段,系统应该给出明确的提示,并阻止冲突安排。
- 需要课程表的持久化功能,用户希望安排好的课程表能在下次打开页面时自动加载,而不需要重新编辑。
- 教师场景
- 教师可以拖动课程安排授课时间,避免重复调整。
- 支持批量拖动课程,例如一门课分为多个时间段,可以快速将课程拖放到多个时间段中。
- 教师需要避免误操作,例如误将课程拖到错误时间段的功能需要撤销或调整。
- 管理员场景
- 课程管理员可以通过后台数据动态生成课程表,支持根据学生或教师的需求提供个性化课程安排模板。
- 拖拽交互需要支持多角色数据权限控制。例如,管理员可能需要调整多个学生的课程安排,但不能修改教师的授课时间。
2.1.2 功能拆解
为了满足上述用户场景,我们可以将课程表的功能需求拆解如下:
- 基础功能:拖拽课程到时间段
- 课程表需要左侧提供可拖拽的课程元素。
- 时间表按天和时间段分为多个区域,允许用户将课程拖拽到指定时间段中。
- 拖拽时提供即时的视觉反馈,例如高亮显示拖拽目标区域。
- 冲突检测与提示
- 在同一时间段只能安排一门课程,如果用户尝试将多个课程拖入同一时间段,系统应实时检测冲突,并通过提示框、警告样式或动画效果提醒用户。
- 课程安排冲突时,课程返回初始位置,不影响其他已安排的课程。
- 数据持久化
- 使用
localStorage或后端 API 保存用户的课程安排。用户关闭页面后再次打开时,可以加载之前的安排。 - 支持导出课程表为 JSON 格式,便于与后端系统对接。
- 使用
- 撤销与重置
- 用户可以撤销最近一次操作,将课程恢复到拖拽前的位置。
- 提供一键重置功能,清空当前所有课程安排。
- 扩展功能
- 支持移动端操作,例如触摸屏拖拽课程到时间段。
- 多用户支持,允许不同用户登录后加载属于自己的课程表。
- 添加课程备注功能,用户可以为每门课程添加备注信息,例如课室、教师等。
2.2 课程表的交互设计
2.2.1 界面布局
- 左侧课程列表
- 左侧为垂直排列的课程列表,包含所有可供拖拽的课程。每个课程元素以方块形式显示课程名称,颜色区分课程类型(例如数学为蓝色,英语为绿色)。
- 列表支持滚动,便于在大量课程中快速找到目标课程。
- 右侧时间表
- 时间表按周展示,分为多个天(如周一至周五)。每一天分为固定的时间段(如上午、下午、晚上)。
- 每个时间段是一个可拖拽的目标区域,当用户拖拽课程到该区域时,显示高亮边框。
- 时间段内显示当前安排的课程。如果没有课程,显示占位文本(例如“拖拽课程到此处”)。
2.2.2 视觉反馈设计
- 拖拽反馈
- 当用户开始拖拽课程时,课程元素变为半透明状态,表示该课程已被选中。
- 鼠标移动到目标时间段时,时间段高亮显示,表示可以放置课程。
- 冲突提示
- 如果拖拽课程到已被占用的时间段,时间段边框变为红色,显示错误提示“时间冲突”。
- 放置失败时,课程返回到原位置,并弹出警告提示。
- 保存状态提示
- 用户点击保存按钮后,显示“保存成功”提示,并在页面顶部显示保存时间。
2.2.3 用户操作流程
以下是典型的用户交互流程:
- 用户浏览左侧课程列表,选择需要安排的课程(例如“数学”)。
- 拖动课程到右侧时间表的目标时间段(如周一上午 9 点)。
- 如果时间段为空,课程成功放置。
- 如果时间段已被占用,课程返回到原位置,并显示冲突提示。
- 用户点击“保存”按钮,将当前课程安排保存到本地或后端。
- 刷新页面后,课程表根据保存的数据自动加载。
2.2.4 交互案例分析
以下为几个典型交互案例及其逻辑设计:
- 成功放置课程
- 场景:用户将“数学”课程拖动到周一上午 9 点,时间段为空。
- 预期行为:
- 时间段接收“数学”课程,课程从左侧列表消失。
- 课程表更新,显示“数学”课程。
- 时间冲突
- 场景:用户尝试将“英语”课程拖动到已被“数学”课程占用的时间段。
- 预期行为:
- 显示冲突提示,时间段边框变为红色。
- 课程返回原位置,用户需要重新选择时间段。
- 保存并恢复
- 场景:用户完成课程安排后,点击“保存”按钮。
- 预期行为:
- 数据保存到
localStorage或后端。 - 用户刷新页面后,课程表自动加载之前保存的内容。
- 数据保存到
2.2.5 功能模块化设计
为确保代码结构清晰,我们将课程表功能划分为以下模块:
- 课程管理模块
- 负责加载、显示和操作课程列表。
- 提供课程数据的动态加载与更新接口。
- 时间表模块
- 负责生成右侧时间表的布局和交互逻辑。
- 提供时间段与课程的关联关系管理。
- 拖拽模块
- 监听拖拽事件,处理数据传递与放置逻辑。
- 提供冲突检测与错误提示功能。
- 数据存储模块
- 负责课程表数据的保存与加载。
- 支持本地存储和后端接口两种方式。
- UI 反馈模块
- 提供高亮、动画等视觉反馈功能。
- 集成错误提示与状态消息展示
三、实现课程表:详细代码与逐步讲解
3.1 静态 HTML 结构
首先,课程表的静态HTML结构需要清晰地定义课程列表和时间表。以下是完整的HTML结构:
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>课程表实现</title><style>body {font-family: Arial, sans-serif;margin: 0;padding: 20px;display: flex;flex-direction: row;justify-content: space-between;}.courses, .schedule {border: 1px solid #ccc;border-radius: 5px;padding: 10px;background: #f9f9f9;}.courses {width: 200px;}.course {background: lightblue;margin: 5px 0;padding: 10px;cursor: move;text-align: center;border: 1px solid #007bff;border-radius: 5px;}.schedule {flex: 1;display: flex;flex-direction: column;}.day {margin-bottom: 15px;}.day h3 {margin: 0;padding: 5px;background: #007bff;color: white;text-align: center;border-radius: 5px;}.time-slot {border: 1px dashed #ccc;padding: 20px;margin: 5px 0;background: #fff;border-radius: 5px;text-align: center;}.time-slot:hover {border-color: #007bff;}</style>
</head>
<body><div class="courses"><h3>课程列表</h3><div class="course" id="course1" draggable="true">数学</div><div class="course" id="course2" draggable="true">英语</div><div class="course" id="course3" draggable="true">历史</div></div><div class="schedule"><div class="day" id="monday"><h3>周一</h3><div class="time-slot" ondrop="drop(event)" ondragover="allowDrop(event)">09:00 - 10:00</div><div class="time-slot" ondrop="drop(event)" ondragover="allowDrop(event)">10:00 - 11:00</div></div><div class="day" id="tuesday"><h3>周二</h3><div class="time-slot" ondrop="drop(event)" ondragover="allowDrop(event)">09:00 - 10:00</div><div class="time-slot" ondrop="drop(event)" ondragover="allowDrop(event)">10:00 - 11:00</div></div></div><script src="drag-drop.js"></script>
</body>
</html>
展开
解释:
- 课程列表:左侧区域,使用
.courses类来定义。课程通过.course类定义为可拖拽的元素。 - 时间表:右侧区域,使用
.schedule类定义。分为天(如周一、周二),每天包含多个时间段.time-slot。
3.2 样式优化
在基本结构样式的基础上,我们添加了一些视觉效果:
- 课程元素:
- 使用圆角边框和浅蓝背景区分课程。
- 鼠标悬停时增加光标样式反馈。
- 时间段:
- 使用虚线边框表示空闲区域。
- 鼠标悬停时,边框颜色变为蓝色,提示用户该区域可放置课程。
3.3 JavaScript 功能实现
3.3.1 拖拽功能基础实现
拖拽操作分为三个核心事件:dragstart、dragover 和 drop。
// 开始拖拽:记录被拖拽元素的ID
function dragStart(event) {event.dataTransfer.setData("text/plain", event.target.id);console.log(`开始拖拽:${event.target.id}`);
}// 允许放置:阻止默认行为
function allowDrop(event) {event.preventDefault();
}// 放置到目标区域
function drop(event) {event.preventDefault();const courseId = event.dataTransfer.getData("text/plain");const course = document.getElementById(courseId);// 检查目标是否为空if (event.target.classList.contains("time-slot") && event.target.children.length === 0) {event.target.appendChild(course);console.log(`课程 ${courseId} 已放置到时间段`);} else {alert("时间段已被占用!");}
}
核心逻辑分析:
dragStart:- 当用户开始拖拽课程时,将课程的ID存入
dataTransfer对象中,以便在drop事件中获取。
- 当用户开始拖拽课程时,将课程的ID存入
allowDrop:- 默认情况下,HTML元素不允许拖拽放置。通过
event.preventDefault(),显式允许拖拽操作。
- 默认情况下,HTML元素不允许拖拽放置。通过
drop:- 当课程放置到时间段中时,检查时间段是否为空。
- 如果为空,则将课程追加到目标时间段;否则,提示冲突。
3.3.2 冲突检测与用户反馈
为了防止时间冲突,我们在放置时加入检测逻辑:
function drop(event) {event.preventDefault();const courseId = event.dataTransfer.getData("text/plain");const course = document.getElementById(courseId);if (event.target.classList.contains("time-slot")) {if (event.target.children.length === 0) {event.target.appendChild(course);event.target.style.borderColor = "green"; // 提供成功反馈} else {alert("时间段已被占用,请选择其他时间!");event.target.style.borderColor = "red"; // 提供错误反馈setTimeout(() => {event.target.style.borderColor = "#ccc"; // 恢复边框颜色}, 1000);}}
}
3.3.3 数据持久化
我们使用localStorage实现课程表数据的保存和加载。
保存课程表:
function saveSchedule() {const scheduleData = {};document.querySelectorAll(".time-slot").forEach((slot, index) => {if (slot.children.length > 0) {scheduleData[index] = slot.children[0].id;}});localStorage.setItem("schedule", JSON.stringify(scheduleData));alert("课程表已保存!");
}
加载课程表:
function loadSchedule() {const scheduleData = JSON.parse(localStorage.getItem("schedule"));if (scheduleData) {Object.keys(scheduleData).forEach((index) => {const courseId = scheduleData[index];const slot = document.querySelectorAll(".time-slot")[index];const course = document.getElementById(courseId);slot.appendChild(course);});}
}
window.onload = loadSchedule;
保存按钮:
在HTML中添加保存按钮:
<button onclick="saveSchedule()">保存课程表</button>
3.4 测试与调试
- 功能测试:
- 拖拽课程到空闲时间段,课程应正确显示。
- 同一时间段不能安排多个课程。
- 保存后刷新页面,课程表应自动恢复。
- 错误处理:
- 如果
localStorage不可用,提示用户保存失败。 - 当用户拖拽到非法区域(非
.time-slot),课程应回到原位。
- 如果
通过这些实现,我们完成了课程表的核心功能,包括拖拽、冲突检测和数据持久化。接下来可以进行扩展,例如响应式布局、动画效果等。
四、高级功能扩展
在基础功能实现的基础上,我们可以通过数据持久化、响应式设计、高级用户交互等功能进一步扩展课程表的能力。以下是详细的高级功能扩展方案。
4.1 数据持久化
数据持久化是课程表的重要功能,用户可以保存课程表的当前状态并在刷新或重新打开页面时自动加载。
4.1.1 保存课程表到 localStorage
以下代码将课程表中的数据保存为 JSON 格式并存储到浏览器的 localStorage:
function saveSchedule() {const slots = document.querySelectorAll(".time-slot");const schedule = {}; // 用于保存课程安排的数据slots.forEach((slot, index) => {if (slot.children.length > 0) {schedule[index] = slot.children[0].id; // 保存课程 ID 与时间段索引的对应关系}});localStorage.setItem("schedule", JSON.stringify(schedule));alert("课程表已成功保存!");
}
4.1.2 加载课程表数据
当页面加载时,我们可以读取 localStorage 中保存的课程表数据并自动将课程安排到对应的时间段中:
function loadSchedule() {const schedule = JSON.parse(localStorage.getItem("schedule"));if (schedule) {Object.keys(schedule).forEach(index => {const courseId = schedule[index];const course = document.getElementById(courseId);const slot = document.querySelectorAll(".time-slot")[index];if (course && slot) {slot.appendChild(course); // 恢复课程到对应的时间段}});}
}// 在页面加载时调用 loadSchedule
window.onload = loadSchedule;
4.1.3 删除课程表数据
增加一个功能,用于清空保存的课程表数据:
function clearSchedule() {localStorage.removeItem("schedule");alert("课程表数据已清空!");location.reload(); // 刷新页面以恢复默认状态
}
扩展按钮:
在 HTML 中添加保存和清除按钮:
<button onclick="saveSchedule()">保存课程表</button>
<button onclick="clearSchedule()">清除课程表</button>
4.2 响应式设计与移动端适配
4.2.1 响应式布局
在移动设备上,课程表应能自动调整布局。例如,将时间表从横向排列改为纵向排列。以下是适配方案:
/* 针对桌面端 */
.schedule {display: flex;justify-content: space-between;
}/* 针对移动端 */
@media (max-width: 600px) {.schedule {flex-direction: column; /* 将时间表改为纵向排列 */}.time-table {margin-bottom: 20px;}
}
4.2.2 触摸屏支持
在触摸屏上使用原生拖拽可能不够友好,可以使用 JavaScript 手势库(如 Hammer.js)来支持触摸拖动。例如:
// 简单触摸拖动示例(需要引入手势库)
let draggedElement = null;function touchStart(event) {draggedElement = event.target; // 记录触摸的课程元素
}function touchMove(event) {const touch = event.touches[0];draggedElement.style.position = "absolute";draggedElement.style.left = `${touch.pageX}px`;draggedElement.style.top = `${touch.pageY}px`;
}function touchEnd(event) {draggedElement.style.position = "static"; // 放置后恢复原样draggedElement = null;
}
绑定触摸事件到课程元素:
document.querySelectorAll('.course').forEach(course => {course.addEventListener('touchstart', touchStart);course.addEventListener('touchmove', touchMove);course.addEventListener('touchend', touchEnd);
});
4.3 增强交互反馈
4.3.1 拖拽动画效果
在拖拽时为课程添加动画效果,使用户操作更流畅:
.course {transition: transform 0.2s ease; /* 拖拽时平滑移动 */
}.course.dragging {opacity: 0.5;transform: scale(1.2); /* 放大效果 */
}
在拖拽事件中添加样式:
function dragStart(event) {event.target.classList.add("dragging");event.dataTransfer.setData("text/plain", event.target.id);
}function dragEnd(event) {event.target.classList.remove("dragging");
}
绑定事件:
document.querySelectorAll('.course').forEach(course => {course.addEventListener('dragstart', dragStart);course.addEventListener('dragend', dragEnd);
});
4.3.2 高亮目标区域
当拖拽课程悬停到时间段时,为时间段添加高亮效果:
.time-slot.drag-over {background-color: #e0f7fa;border-color: #007bff;
}
在 dragover 和 dragleave 事件中添加逻辑:
function allowDrop(event) {event.preventDefault();event.target.classList.add("drag-over");
}function dragLeave(event) {event.target.classList.remove("drag-over");
}
绑定事件:
document.querySelectorAll('.time-slot').forEach(slot => {slot.addEventListener('dragover', allowDrop);slot.addEventListener('dragleave', dragLeave);
});
五、性能优化与最佳实践
5.1 DOM 操作优化
频繁操作 DOM 会导致性能瓶颈,尤其是在课程表元素较多时。以下是优化策略:
5.1.1 使用 DocumentFragment
批量操作时使用 DocumentFragment,减少重绘和重排:
function createSchedule(days, timeSlots) {const fragment = document.createDocumentFragment();days.forEach(day => {const dayContainer = document.createElement('div');dayContainer.className = 'day';const header = document.createElement('h3');header.textContent = day;dayContainer.appendChild(header);timeSlots.forEach(slot => {const timeSlot = document.createElement('div');timeSlot.className = 'time-slot';timeSlot.setAttribute('ondrop', 'drop(event)');timeSlot.setAttribute('ondragover', 'allowDrop(event)');timeSlot.textContent = slot;dayContainer.appendChild(timeSlot);});fragment.appendChild(dayContainer);});document.querySelector('.schedule').appendChild(fragment);
}
5.1.2 减少事件监听
避免为每个课程或时间段单独绑定事件,改为事件委托:
document.querySelector('.schedule').addEventListener('dragover', event => {if (event.target.classList.contains('time-slot')) {allowDrop(event);}
});document.querySelector('.schedule').addEventListener('drop', event => {if (event.target.classList.contains('time-slot')) {drop(event);}
});
六、拓展应用场景
6.1 文件拖拽上传
拖拽文件上传是拖拽 API 的常见应用场景:
const dropZone = document.getElementById('drop-zone');dropZone.addEventListener('dragover', event => {event.preventDefault();dropZone.classList.add('drag-over');
});dropZone.addEventListener('drop', event => {event.preventDefault();dropZone.classList.remove('drag-over');const files = event.dataTransfer.files;// 显示文件列表Array.from(files).forEach(file => {console.log(`上传文件:${file.name}`);});
});
HTML:
<div id="drop-zone" style="border: 2px dashed #ccc; padding: 20px; text-align: center;">将文件拖到此处上传
</div>
6.2 看板系统
在看板系统中,用户可以将任务卡片拖放到不同列(如待办、进行中、已完成):
function dropTask(event) {const taskId = event.dataTransfer.getData('text/plain');const task = document.getElementById(taskId);if (event.target.classList.contains('task-column')) {event.target.appendChild(task);}
}

七、总结
通过高级功能扩展,课程表的功能变得更加强大和实用。我们实现了数据持久化、响应式设计、触摸屏支持、拖拽动画等功能,并探讨了性能优化策略和其他应用场景(如文件上传和看板系统)。这些功能的实现使得课程表不仅限于简单的拖拽交互,还可以扩展为复杂的多功能应用。

相关文章:
HTML5 拖拽 API 深度解析
一、HTML5 拖拽 API 深度解析 1.1 背景与发展 HTML5 的拖拽 API 是为了解决传统拖拽操作复杂而设计的。传统方法依赖鼠标事件和复杂的逻辑计算,而 HTML5 提供了标准化的拖拽事件和数据传递机制,使得开发者能够快速实现从一个元素拖拽到另一个元素的交互…...
GO--基于令牌桶和漏桶的限流策略
至于为什么要限流,字面意思已经很清楚了,就是为了减轻服务器的压力 下面我们将介绍两个限流策略----漏桶和令牌桶。 漏桶 原理介绍 漏桶,顾名思义就是一个漏斗,漏斗嘴的大小是固定的,所以不管漏斗现容量多大&#…...
MongoDB性能监控工具
mongostat mongostat是MongoDB自带的监控工具,其可以提供数据库节点或者整个集群当前的状态视图。该功能的设计非常类似于Linux系统中的vmstat命令,可以呈现出实时的状态变化。不同的是,mongostat所监视的对象是数据库进程。mongostat常用于…...
Axure设计之模拟地图人员移动轨迹
在产品原型设计时,为了更好的表达和呈现预期的效果,让客户或开发看一眼就能理解要实现的功能,往往需要在产品设计时尽量去接近现实,这就需要我们在使用Axure制作原型时应具有高度细节和逼真度的原型设计。原型设计不仅包含了产品的…...
Android环境搭建
Android环境搭建 第一步:安装 Homebrew 执行以下命令来安装 Homebrew: /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"检测是否安装成功: brew --version第二步:安装 No…...
前端工程化面试题(一)
如何使用 Docker 部署前端项目? 使用 Docker 部署前端项目通常涉及以下几个步骤: 创建项目:首先,需要在本地创建并配置好前端项目。 准备 Docker 文件: .dockerignore:这个文件用于排除不需要上传到 Dock…...
模型案例:| 手机识别模型!
导读 2023年以ChatGPT为代表的大语言模型横空出世,它的出现标志着自然语言处理领域取得了重大突破。它在文本生成、对话系统和语言理解等方面展现出了强大的能力,为人工智能技术的发展开辟了新的可能性。同时,人工智能技术正在进入各种应用领…...
期权懂|个股期权交割操作流程是什么样的?
期权小懂每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 个股期权交割操作流程是什么样的? 一、行权申报: 期权买方在行权日通过其经纪商提交行权指令,表明其决定行使期权权利。 二、行权匹配…...
【openGauss】openGauss execute执行update语句,获取更新的行数
【openGauss】openGauss execute执行update语句,获取更新的行数 在openGauss中,可以使用execute语句执行update语句,并通过GET DIAGNOSTICS语句获取更新的行数。下面是一个示例: DO $$ DECLAREupdated_rows INTEGER; BEGINEXECUT…...
P8780 [蓝桥杯 2022 省 B] 刷题统计
题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 𝑎道题目,周六和周日每天做 𝑏 道题目。请你帮小明计算,按照计划他将在第几天实现做题数大于等于 𝑛 题? 输入格式 输入一行包含三…...
切比雪夫不等式:方差约束下的概率估计
切比雪夫不等式:方差约束下的概率估计 背景 在概率分析中,切比雪夫不等式是一个常用的工具,它通过引入随机变量的 方差信息,给出了偏离均值的概率界限。这一不等式是对 马尔科夫不等式 的自然扩展,结合了更丰富的分布…...
使用CancellationTokenSource来控制长时间sql查询中断
前端 <!-- 透明的覆盖层,显示在页面上方,包含进度条 --><Grid Visibility"{Binding IsLoading}" Background"Transparent" HorizontalAlignment"Stretch" VerticalAlignment"Stretch" ZIndex"1&…...
小红薯最新x-s 算法补环境教程12-06更新(下)
在上一篇文章中已经讲了如何去定位x-s生成的位置,本篇文章就直接开始撸代码吧 如果没看过的话可以看:小红薯最新x-s算法分析12-06(x-s 56)(上)-CSDN博客 1、获取加密块代码 首先来到参数生成的位置&…...
wazuh-modules-sca
wazuh中安全配置评估模块主线程执行wm_sca_main最后在wm_sca_start中循环执行,不会返回 // Module main function. It wont return #ifdef WIN32 DWORD WINAPI wm_sca_main(void *arg) {wm_sca_t *data (wm_sca_t *)arg; #else void * wm_sca_main(wm_sca_t * dat…...
Uniapp的App环境下使用Map获取缩放比例
概述 目前我试过的就是你用vue后缀是拿不到比例的你可以用nvue当然uniapp的uvue应该是更加可以的我使用的是高德所以你得在高德的后台声请原生的Android的key才可以如果是vue3的开发模式的话不用使用this来获取当前对象使用scale对象来接受和改变缩放比例会比较友好然后直接走…...
微信小程序配置less并使用
1.在VScode中下载Less插件 2.在微信小程序中依次点击如下按钮 选择 从已解压的扩展文件夹安装… 3.选中刚在vscode中下载安装的插件文件 如果没有修改过插件的安装目录,一般是在c盘下C:\用户\用户名.vscode\extensions\mrcrowl.easy-less-2.0.2 我的路径是…...
“全面支持公路数字化转型升级四大任务”视频孪生解决方案
数字经济的加速布局,对交通领域数字化转型、智能化升级提出明确要求。2024年上半年,为深入贯彻落实中共中央、国务院关于加快建设交通强国、数字中国等决策部署,推进公路水路交通基础设施数字转型、智能升级、融合创新,加快发展新…...
顶顶通电话机器人开发接口对接大语言模型之实时流TTS对接介绍
大语言模型一般都是流式返回文字,如果等全部文字返回了一次性去TTS,那么延迟会非常严重,常用的方法就是通过标点符号断句,返回了一句话就提交给TTS。随着流TTS的出现,就可以直接把大模型返回的文字灌给流TTS࿰…...
P3379 【模板】最近公共祖先(LCA)
【模板】最近公共祖先(LCA) https://www.luogu.com.cn/problem/P3379 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。 输入格式 第一行包含三个正整数 N , M , S N,M,S N,M,S,分别表示…...
2030. gitLab A仓同步到B仓
文章目录 1 A 仓库备份 到 B 仓库2 B 仓库修改main分支的权限 1 A 仓库备份 到 B 仓库 #!/bin/bash# 定义变量 REPO_DIR"/home/xhome/opt/git_sync/zz_xx_xx" # 替换为你的本地库A的实际路径 REMOTE_ORIGIN"http://192.168.1.66:8181/zzkj_software/zz_xx_xx.…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...
边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
