当前位置: 首页 > news >正文

HTML5 拖拽 API 深度解析

在这里插入图片描述

一、HTML5 拖拽 API 深度解析

1.1 背景与发展

HTML5 的拖拽 API 是为了解决传统拖拽操作复杂而设计的。传统方法依赖鼠标事件和复杂的逻辑计算,而 HTML5 提供了标准化的拖拽事件和数据传递机制,使得开发者能够快速实现从一个元素拖拽到另一个元素的交互。

1.2 拖拽 API 的核心工作原理

HTML5 拖拽 API 的核心包括以下几个步骤:

  1. 定义可拖拽元素
    设置 HTML 元素的 draggable 属性为 true

    <div id="drag-item" draggable="true">可拖拽元素</div>
    
  2. 处理拖拽事件
    拖拽相关事件包括:

    • dragstart:拖拽开始。
    • drag:拖拽中(可用于实时显示位置)。
    • dragend:拖拽结束。
    • dragover:目标区域悬停。
    • drop:放置到目标区域。
  3. 数据传递机制
    使用 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 用户场景
  1. 学生场景
    • 学生可以根据自己的课程需求,自由安排每周的课程表。例如,用户可以将数学课安排在周一上午 9 点,并在拖拽过程中动态调整课程顺序。
    • 用户希望避免时间冲突,例如将两个课程拖到同一时间段,系统应该给出明确的提示,并阻止冲突安排。
    • 需要课程表的持久化功能,用户希望安排好的课程表能在下次打开页面时自动加载,而不需要重新编辑。
  2. 教师场景
    • 教师可以拖动课程安排授课时间,避免重复调整。
    • 支持批量拖动课程,例如一门课分为多个时间段,可以快速将课程拖放到多个时间段中。
    • 教师需要避免误操作,例如误将课程拖到错误时间段的功能需要撤销或调整。
  3. 管理员场景
    • 课程管理员可以通过后台数据动态生成课程表,支持根据学生或教师的需求提供个性化课程安排模板。
    • 拖拽交互需要支持多角色数据权限控制。例如,管理员可能需要调整多个学生的课程安排,但不能修改教师的授课时间。
2.1.2 功能拆解

为了满足上述用户场景,我们可以将课程表的功能需求拆解如下:

  1. 基础功能:拖拽课程到时间段
    • 课程表需要左侧提供可拖拽的课程元素。
    • 时间表按天和时间段分为多个区域,允许用户将课程拖拽到指定时间段中。
    • 拖拽时提供即时的视觉反馈,例如高亮显示拖拽目标区域。
  2. 冲突检测与提示
    • 在同一时间段只能安排一门课程,如果用户尝试将多个课程拖入同一时间段,系统应实时检测冲突,并通过提示框、警告样式或动画效果提醒用户。
    • 课程安排冲突时,课程返回初始位置,不影响其他已安排的课程。
  3. 数据持久化
    • 使用 localStorage 或后端 API 保存用户的课程安排。用户关闭页面后再次打开时,可以加载之前的安排。
    • 支持导出课程表为 JSON 格式,便于与后端系统对接。
  4. 撤销与重置
    • 用户可以撤销最近一次操作,将课程恢复到拖拽前的位置。
    • 提供一键重置功能,清空当前所有课程安排。
  5. 扩展功能
    • 支持移动端操作,例如触摸屏拖拽课程到时间段。
    • 多用户支持,允许不同用户登录后加载属于自己的课程表。
    • 添加课程备注功能,用户可以为每门课程添加备注信息,例如课室、教师等。

2.2 课程表的交互设计

2.2.1 界面布局
  1. 左侧课程列表
    • 左侧为垂直排列的课程列表,包含所有可供拖拽的课程。每个课程元素以方块形式显示课程名称,颜色区分课程类型(例如数学为蓝色,英语为绿色)。
    • 列表支持滚动,便于在大量课程中快速找到目标课程。
  2. 右侧时间表
    • 时间表按周展示,分为多个天(如周一至周五)。每一天分为固定的时间段(如上午、下午、晚上)。
    • 每个时间段是一个可拖拽的目标区域,当用户拖拽课程到该区域时,显示高亮边框。
    • 时间段内显示当前安排的课程。如果没有课程,显示占位文本(例如“拖拽课程到此处”)。
2.2.2 视觉反馈设计
  1. 拖拽反馈
    • 当用户开始拖拽课程时,课程元素变为半透明状态,表示该课程已被选中。
    • 鼠标移动到目标时间段时,时间段高亮显示,表示可以放置课程。
  2. 冲突提示
    • 如果拖拽课程到已被占用的时间段,时间段边框变为红色,显示错误提示“时间冲突”。
    • 放置失败时,课程返回到原位置,并弹出警告提示。
  3. 保存状态提示
    • 用户点击保存按钮后,显示“保存成功”提示,并在页面顶部显示保存时间。
2.2.3 用户操作流程

以下是典型的用户交互流程:

  1. 用户浏览左侧课程列表,选择需要安排的课程(例如“数学”)。
  2. 拖动课程到右侧时间表的目标时间段(如周一上午 9 点)。
    • 如果时间段为空,课程成功放置。
    • 如果时间段已被占用,课程返回到原位置,并显示冲突提示。
  3. 用户点击“保存”按钮,将当前课程安排保存到本地或后端。
  4. 刷新页面后,课程表根据保存的数据自动加载。

2.2.4 交互案例分析

以下为几个典型交互案例及其逻辑设计:

  1. 成功放置课程
    • 场景:用户将“数学”课程拖动到周一上午 9 点,时间段为空。
    • 预期行为:
      • 时间段接收“数学”课程,课程从左侧列表消失。
      • 课程表更新,显示“数学”课程。
  2. 时间冲突
    • 场景:用户尝试将“英语”课程拖动到已被“数学”课程占用的时间段。
    • 预期行为:
      • 显示冲突提示,时间段边框变为红色。
      • 课程返回原位置,用户需要重新选择时间段。
  3. 保存并恢复
    • 场景:用户完成课程安排后,点击“保存”按钮。
    • 预期行为:
      • 数据保存到 localStorage 或后端。
      • 用户刷新页面后,课程表自动加载之前保存的内容。

2.2.5 功能模块化设计

为确保代码结构清晰,我们将课程表功能划分为以下模块:

  1. 课程管理模块
    • 负责加载、显示和操作课程列表。
    • 提供课程数据的动态加载与更新接口。
  2. 时间表模块
    • 负责生成右侧时间表的布局和交互逻辑。
    • 提供时间段与课程的关联关系管理。
  3. 拖拽模块
    • 监听拖拽事件,处理数据传递与放置逻辑。
    • 提供冲突检测与错误提示功能。
  4. 数据存储模块
    • 负责课程表数据的保存与加载。
    • 支持本地存储和后端接口两种方式。
  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 样式优化

在基本结构样式的基础上,我们添加了一些视觉效果:

  1. 课程元素:
    • 使用圆角边框和浅蓝背景区分课程。
    • 鼠标悬停时增加光标样式反馈。
  2. 时间段:
    • 使用虚线边框表示空闲区域。
    • 鼠标悬停时,边框颜色变为蓝色,提示用户该区域可放置课程。

3.3 JavaScript 功能实现

3.3.1 拖拽功能基础实现

拖拽操作分为三个核心事件:dragstartdragoverdrop

// 开始拖拽:记录被拖拽元素的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("时间段已被占用!");}
}

核心逻辑分析:

  1. dragStart
    • 当用户开始拖拽课程时,将课程的ID存入dataTransfer对象中,以便在drop事件中获取。
  2. allowDrop
    • 默认情况下,HTML元素不允许拖拽放置。通过event.preventDefault(),显式允许拖拽操作。
  3. 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 测试与调试

  1. 功能测试:
    • 拖拽课程到空闲时间段,课程应正确显示。
    • 同一时间段不能安排多个课程。
    • 保存后刷新页面,课程表应自动恢复。
  2. 错误处理:
    • 如果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;
}

dragoverdragleave 事件中添加逻辑:

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 是为了解决传统拖拽操作复杂而设计的。传统方法依赖鼠标事件和复杂的逻辑计算&#xff0c;而 HTML5 提供了标准化的拖拽事件和数据传递机制&#xff0c;使得开发者能够快速实现从一个元素拖拽到另一个元素的交互…...

Vue 的生命周期钩子函数是什么?常见的生命周期钩子有哪些?

Vue 的生命周期钩子函数 Vue 的生命周期钩子函数是 Vue 组件在不同生命周期阶段自动调用的函数。生命周期分为创建、挂载、更新和销毁等阶段。理解这些钩子函数对于开发和调试 Vue 应用至关重要&#xff0c;因为它们使我们能够在组件生命周期的不同阶段执行特定的操作。 目录…...

uniapp中导入uview或者uview plus

关于SCSS uview-plus依赖SCSS&#xff0c;您必须要安装此插件&#xff0c;否则无法正常运行。 如果您的项目是由HBuilder X创建的&#xff0c;相信已经安装scss插件&#xff0c;如果没有&#xff0c;请在HX菜单的 工具->插件安装中找到"scss/sass编译"插件进行安…...

3D 生成重建017-StyleGaussian用文本或图像对你的3DGS内容进行风格迁移

3D 生成重建017-StyleGaussian用文本或图像对你的3DGS内容进行风格迁移 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 论文 “StyleGaussian: Instant 3D Style Transfer with Gaussian Splatting” 介绍了一种新颖的3D风格迁移方法 StyleGaussian&#xff0c;该方法通…...

【adb】iqoo系统精简垃圾内置应用

免责声明 这个得谨慎点&#xff0c;虽然我验证过两部手机和不同版本的系统&#xff0c;但是总会有特殊的存在、 本教程来自于互联网搜集整理&#xff0c; 按照本教程造成的用户设备硬件或数据损失&#xff0c;本人概不承担任何责任&#xff0c;如您不同意此协议&#xff0c;请不…...

Golang 字符串字面量表示方法

文章目录 1.普通字符串字面量&#xff08;Double-Quoted String Literals&#xff09;2.原始字符串字面量&#xff08;Raw String Literals&#xff09;3.字节字符串字面量&#xff08;Byte Slice Literals&#xff09;4.码值表示字符串字面量Unicode 转义序列UTF8 转义序列十六…...

【uni-app 微信小程序】新版本发布提示用户进行更新

知识准备 uni.getUpdateManager文档介绍 不支持APP与H5&#xff0c;所以在使用的时候要做好平台类型的判断&#xff0c;如何判断&#xff0c;参考条件编译处理多端差异 代码参考 export const updateApp () > {const updateManager uni.getUpdateManager()updateManag…...

Leetcode 739-每日温度

请根据每日 气温 列表 temperatures &#xff0c;请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 题解&#xff08;单调递减栈&#xff09; 什么时候用单调栈呢&#xff1f; 通常是一维数组&#xff0c;要寻找任…...

Gitee配置以及如何将本地项目提交到远程仓库

文章目录 准备远程仓库配置注册新建仓库 配置git 生成ssh&#xff0c;输入以下命令&#xff0c;然后连敲三次回车键配置公钥本地代码上传 准备 1.本地下载git 2.注册远程仓库账号 远程仓库配置 注册 官网&#xff1a;https://gitee.com 完成注册 新建仓库 头像->设置-…...

爬虫项目基础知识详解

文章目录 Python爬虫项目基础知识一、爬虫与数据分析1.1 Python中的requests库Requests 库的安装Requests 库的 get() 方法爬取网页的通用代码框架HTTP 协议及 Requests 库方法Requests 库主要方法解析 1.2 python中的json库1.3 xpath学习之python中lxml库html了解html结构html…...

【Leetcode Top 100 - 扩展】876. 链表的中间结点

问题背景 给你单链表的头结点 h e a d head head&#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 数据约束 链表的结点数范围是 [ 1 , 100 ] [1, 100] [1,100] 1 ≤ N o d e . v a l ≤ 100 1 \le Node.val \le 100 1≤…...

16-01、JVM系列之:内存与垃圾回收篇(一)

JVM系列之&#xff1a;内存与垃圾回收篇&#xff08;一&#xff09; ##本篇内容概述&#xff1a; 1、JVM结构 2、类加载子系统 3、运行时数据区之&#xff1a;PC寄存器、Java栈、本地方法栈一、JVM与JAVA体系结构 JAVA虚拟机与JAVA语言并没有必然的联系&#xff0c;它只是与特…...

经典蓝牙(BT/EDR)蓝牙配对与连接

经典蓝牙的连接过程包括跳频&#xff0c;扫描&#xff0c;配置交换等过程。对ACL链路以及sco的连接过程也做详细的分析。 1. 为什么不配对便无法建立连接&#xff1f; 任何无线通信技术都存在被监听和破解的可能&#xff0c;蓝牙SIG为了保证蓝牙通信的安全性&#xff0c;采用…...

用 Python 从零开始创建神经网络(十四):L1 和 L2 正则化(L1 and L2 Regularization)

L1 和 L2 正则化&#xff08;L1 and L2 Regularization&#xff09; 引言1. Forward Pass2. Backward pass到此为止的全部代码&#xff1a; 引言 正则化方法旨在降低泛化误差。我们首先讨论的正则化形式是L1正则化和L2正则化。L1和L2正则化用于计算一个数值&#xff08;称为惩…...

特殊的数学性质

一个数模9的结果等于它的每一位数相加和模9...

最长递增子序列&什么是继承性?C++中如何实现继承?继承的好处和注意事项有哪些?

最长递增子序列 方法一&#xff1a;暴力二维dp&#xff0c;初始状态&#xff1a;每个元素至少和自己构成一个上升序列&#xff0c;大小为1&#xff0c;状态转移&#xff1a;找到前面结尾数字小于当前数组元素的最长序列&#xff0c;当前位置的长度就是lenpre1. class Solutio…...

汽车IVI中控开发入门及进阶(三十五):架构QML App Architecture Best Practices

在Qt/QML工程的架构中,架构很重要,虽然本身它有分层,比如QML调用资源文件(图片等)显示GUI界面,后面的CPP文件实现界面逻辑,但是这个分类还有点粗。在实际开发中,界面逻辑也就是基于类cpp的实现,也开始使用各种面向对象的设计模式,实现更加优秀的开发架构,这点尤其在…...

面试题整理(二)

芯冰乐知识星球入口:芯冰乐...

编码及其代码

编码 形成文字所需bit点------有相应代号&#xff08;编码---有好多种8/16/24/32&#xff09;都已提前形成好&#xff0c;放哪哪就会形成那个文字 同一个文字在不同编码存的码不一样 用一种编码存的话&#xff0c;如果用另一种编码解析就会出现乱码 Windows默认编码为ANSI …...

python selenium(4+)+chromedriver最新版 定位爬取嵌套shadow-root(open)中内容

废话不多说&#xff0c;直接开始 本文以无界作为本文测试案例&#xff0c;抓取shadow-root&#xff08;open&#xff09;下的内容 shadow Dom in selenium&#xff1a; 首先先讲一下shadow Dom in selenium 版本的区别&#xff0c;链接指向这里 在Selenium 4版本 以及 chrom…...

AutoClass加载预训练实例

AutoClass 由于 Transformer 架构种类繁多&#xff0c;AtuoClass可以创建一个你想要的做模型架构。作为 &#x1f917; Transformer 核心理念的一部分&#xff0c;使库易于使用、简单且灵活&#xff0c;可以AutoClass从给定的检查点自动推断和加载正确的架构。该from_pretrain…...

在 CentOS 上安装 NFS 服务器

文章目录 1. 在 CentOS 上安装 NFS 服务器1.1 安装 NFS 服务器软件包1.2 配置 NFS 共享目录1.3 配置 NFS 导出文件1.4 启动并启用 NFS 服务1.5 导出共享目录1.6 配置防火墙1.7 检查 NFS 状态 2. 在 CentOS 上安装 NFS 客户端2.1 安装 NFS 客户端软件包2.2 挂载 NFS 共享2.3 配置…...

utf8mb4_unicode_ci、utf8mb4_general_ci、utf8mb4_0900_ai_ci; Mysql 排序字符集的优缺点和选择

标题内容 Mysql的排序字符集真让人头疼&#xff0c;如果两个表的排序字符集不一致&#xff0c;还会导致在进行字段比较的时候直接报错。下面分析几个常用的字符集的优劣和选择。 utf8mb4_unicode_ci 特点 Unicode 标准兼容性高&#xff1a;它是基于 Unicode 标准的排序规则&a…...

星宸SSC8836Q/SSC8836Q-H

SSC8836Q产品是高度集成的多媒体片上系统(SoC)产品&#xff0c;适用于汽车和运动/运动相机等高分辨率智能视频录制和播放应用。 该芯片包括64位双核RISC处理器&#xff0c;先进的图像信号处理器(ISP)&#xff0c;高性能的H.265/H。264/MJPEG视频编解码器&#xff0c;智能处理单…...

rk3576 , android14 , 编译, 卡死,android.bp , ninja

问题&#xff1a;我在 编译 &#xff41;&#xff4e;&#xff44;&#xff52;&#xff4f;&#xff49;&#xff44;&#xff11;&#xff14; 的时候&#xff0c; 卡死再 analysing android.bp 这里 &#xff0c;卡了 3&#xff0c;4 个小时。肯定是有问题的。 如图&…...

3、.Net UI库:MaterialSkin - 开源项目研究文章

MaterialSkin 是一个开源的 WinForms 第三方库&#xff0c;提供了许多仿谷歌设计风格的组件&#xff0c;使得 WinForms 窗体程序更加美观。以下是 MaterialSkin 的一些关键特点和使用方法&#xff1a; 主要特点&#xff1a; 仿谷歌设计风格&#xff1a;MaterialSkin 提供了大量…...

2024年构建PHP应用开发环境

文章目录 前言选择合适的PHP版本安装与配置PHP环境Windows平台Linux平台macOS平台 集成Web服务器数据库连接与管理使用Composer进行依赖管理调试工具的选择代码质量管理部署与持续集成安全性考虑参考资料结语 前言 随着互联网的发展&#xff0c;PHP作为一门成熟的服务器端编程…...

苹果手机iPad投屏到安卓电视,不只有AirPlay一种方法,还可以无线远程投屏!

苹果品牌的设备一般都可以使用airplay功能&#xff0c;将一个屏幕投射到另一个屏幕上。如果是跨品牌或跨系统投屏&#xff0c;airplay就未必能够适应。 提供无线投屏和airplay投屏两种方式的AirDroid Cast已经推出TV版本。苹果手机或iPad可以选择无线&#xff08;远程&#xff…...

什么是内网什么是外网?区别是什么

内网和外网是计算机网络中的两个基本概念&#xff0c;它们在定义、特点和使用场景上有显著的区别。‌虎观代理小二将带大家详细了解内网与外网的定义以及它们之间的主要差异&#xff0c;帮助读者更好地理解和应用这两种网络。 内网&#xff08;局域网&#xff0c;LAN&#xff0…...

基于Springboot+Vue的在线答题闯关系统

基于SpringbootVue的在线答题闯关系统 前言&#xff1a;随着在线教育的快速发展&#xff0c;传统的教育模式逐渐向互联网教育模式转型。在线答题系统作为其中的一个重要组成部分&#xff0c;能够帮助用户通过互动式的学习方式提升知识掌握度。本文基于Spring Boot和Vue.js框架&…...

html css 图片背景透明

html css图标背景透明 css属性&#xff1a; background-color:transparent; mix-blend-mode: multiply; 完整HTML代码&#xff1a; <html><head><title>Test</title></head><body><div id"test" style"background-col…...

Servlet

一 Servlet Servlet (server applet) 是运行在服务端(tomcat)的Java小程序&#xff0c;是sun公司提供一套定义动态资源规范; 从代码层面上来讲Servlet就是一个接口 用来接收、处理客户端请求、响应给浏览器的动态资源。在整个Web应用中&#xff0c;Servlet主要负责接收处理请求…...

MySQL用法---MySQL Workbench创建数据库和表

1. 连接数据库 打开软件&#xff0c;点击左下角卡片&#xff0c;输入设置的数据库密码&#xff0c;勾选单选框 2. 了解主页面的组成部分 3. 创建数据库 先点击工具栏的创建按钮 再输入数据库名称 点击 Apply 创建 4. 创建数据表 展开数据库&#xff0c;在Tables上右键&…...

WordPress Elementor Page Builde 任意文件读取漏洞复现(CVE-2024-9935)

0x01 产品描述: WordPress Elementor Page Builder 是一款 WordPress 插件,它允许用户以可视化方式创建和编辑网页。0x02 漏洞描述: WordPress 的 Elementor Page Builder 插件的 PDF 生成器插件在 1.7.5 之前的所有版本中都容易受到路径遍历的攻击,包括 1.7.5 rtw_pgaepb_…...

静态链接和动态链接的特点

静态链接 链接方式‌&#xff1a;在编译时&#xff0c;所有依赖的库代码被直接打包到生成的可执行文件中。这意味着在程序运行时&#xff0c;不需要再加载任何外部库文件‌。 优点‌&#xff1a; 独立性强‌&#xff1a;生成的可执行文件可以在没有依赖库的系统上直接运行&am…...

内核流对象(Kernel Streaming Objects)

内核流对象(Kernel Streaming Objects)是 Windows 系统中用于处理音频、视频等流媒体数据的重要机制。让我详细解释其作用和主要组件&#xff1a; 1. 主要作用&#xff1a; c // 内核流的核心功能 - 音频/视频数据的实时处理 - 多媒体设备驱动开发 - 硬件与软件之间的数据流传…...

Java 在Json对象字符串中查找和提取特定的数据

1、在处理JSON数据时&#xff0c;需要提出个别字段的值&#xff0c;通过正则表达式提取特定的数据 public static void main(String[] args) {//定义多个JSON对象字符串类型&#xff0c;假设每个对象有a,b,c 字段String strJson "{\"a\":1.23,\"b\"…...

21、结构体成员分布

结构体中的成员并不是紧挨着分布的&#xff0c;内存分布遵循字节对齐的原则。 按照成员定义的顺序&#xff0c;遵循字节对齐的原则存储。 字节对齐的原则&#xff1a; 找成员中占据字节数最大的成员&#xff0c;以它为单位进行空间空配 --- 遇到数组看元素的类型 每一个成员距离…...

【深度学习】四大图像分类网络之ResNet

ResNet网络是在2015年由微软实验室中的何凯明等几位提出&#xff0c;在CVPR 2016发表影响深远的网络模型&#xff0c;由何凯明团队提出来&#xff0c;在ImageNet的分类比赛上将网络深度直接提高到了152层&#xff0c;前一年夺冠的VGG只有19层。斩获当年ImageNet竞赛中分类任务第…...

zookeeper学习

解决什么问题&#xff1f; 首先来分析下业务对象&#xff0c;才能对解决的问题进行归纳和总结。它解决的事分布式应用的问题&#xff0c;那么分布式应用会存在哪里问题是由它的业务特性来决定的&#xff0c;这些问题已是为了解决业务的问题。分布式的业务特征有哪些&#xff1…...

Monkey结合appium模拟操作特定界面

目录 1. 使用 Monkey 操作特定界面&#xff08;通过UI标识来限制&#xff09; 2. 结合 uiautomator 或 appium 定位特定元素 步骤&#xff1a; 3. 使用 Monkey Appium 控制特定界面点击 4. 如何结合 Appium 与 Monkey 5. 限制 Monkey 只点击固定界面上的元素 使用 --pc…...

智能指针【C++11】

文章目录 智能指针std::auto_ptr std::unique_ptrstd::shared_ptrstd::shared_ptr的线程安全问题std::weak_ptr 智能指针 std::auto_ptr 管理权转移 auto_ptr是C98中引入的智能指针&#xff0c;auto_ptr通过管理权转移的方式解决智能指针的拷贝问题&#xff0c;保证一个资源…...

plsql 执行存储过程 SYS_REFCURSOR

关键字&#xff1a;plsql 执行存储过程 SYS_REFCURSOR 在PL/SQL中&#xff0c;SYS_REFCURSOR是一种特殊的数据类型&#xff0c;用于表示引用游标&#xff0c;可以用来返回查询结果或者操作数据库中的结果集。 以下是一个使用SYS_REFCURSOR执行存储过程的例子&#xff1a; CR…...

git修改某次commit(白痴版)

第一步 在bash窗口运行 git rebase --interactive commitId^ 比如要改的commitId是 abcedf git rebase --interactive abcedf^键盘 按 i 或者 ins 进入编辑状态 进入insert 编辑状态 在bash窗口手动把对应commit前面的pick改为e或edit 按 esc 进入退出程序 输入 :wq 保存退出…...

设计模式:19、桥接模式

目录 0、定义 1、桥接模式的四种角色 2、桥接模式的UML类图 3、示例代码 0、定义 将抽象部门与实现部分分离&#xff0c;使它们都可以独立地变化。 1、桥接模式的四种角色 抽象&#xff08;Abstraction&#xff09;&#xff1a;一个抽象类&#xff0c;包含实现者&#xf…...

闭包函数的基础知识

上期文章 1. 函数装饰器 2.闭包 2.1变量作用域 python有3种变量作用域 模块全局作用域:在类或函数外部分配定义的。函数局部作用域:通过参数或者在函数主体中定义的。第3种作用域:闭包中的变量环境 2.2全局变量和局部变量 def fun(a):print(a)print(b)fun(10)10---------…...

python3D圣诞树

import pygame import math from pygame.locals import *# 初始化Pygame pygame.init()# 设置屏幕尺寸和标题 width, height 800, 600 screen pygame.display.set_mode((width, height)) pygame.display.set_caption(3D 圣诞树)# 设置颜色 GREEN (34, 139, 34) BROWN (139,…...

博物馆导览系统方案(一)背景需求分析与核心技术实现

维小帮提供多个场所的室内外导航导览方案&#xff0c;如需获取博物馆导览系统解决方案可前往文章最下方获取&#xff0c;如有项目合作及技术交流欢迎私信我们哦~撒花&#xff01; 一、博物馆导览系统的背景与市场需求 在数字化转型的浪潮中&#xff0c;博物馆作为文化传承和知…...

[代码随想录09]字符串2的总结

前言 处理字符串主要是有思路&#xff0c;同时总结方法。 题目链接 151. 反转字符串中的单词 - 力扣&#xff08;LeetCode&#xff09; 55. 右旋字符串&#xff08;第八期模拟笔试&#xff09; 一、翻转字符串里的单词 这个题目的主要思路&#xff0c;代码采用从后往前遍历字…...

C语言程序设计P5-3【应用函数进行程序设计 | 第三节】——知识要点:函数的嵌套调用和递归调用

知识要点&#xff1a;函数的嵌套调用和递归调用 视频 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 本任务要求用递归法求 n!。 我们知道n!n(n-1)(n-2)……1n(n-1)!递归公式为&#xff1a; 1.上面公式分解为n!n(n-1)!&#xff0c;即将求n!的问题变为…...