导读:本期聚焦于小伙伴创作的《HTML如何通过UI将多个记录关联到多个记录》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《HTML如何通过UI将多个记录关联到多个记录》有用,将其分享出去将是对创作者最好的鼓励。

在Web应用开发中,多对多记录关联是非常常见的需求,比如一个用户可以拥有多个角色,一个角色也可以分配给多个用户,这类场景就需要在UI层面实现多个记录到多个记录的关联操作。下面我们就一步步实现这个功能。

HTML如何通过UI将多个记录关联到多个记录

实现思路

要实现多对多记录关联的UI,核心逻辑分为几个部分:首先需要展示待关联的两组记录列表,然后提供选择交互让用户选中需要关联的记录,最后将选中的关联关系动态展示出来,同时支持取消关联操作。

基础页面结构

我们先搭建基础的HTML结构,分为左侧待选列表、中间操作区域、右侧已关联列表三个部分:

<div class="container">
  <div class="list-section">
    <h3>待选用户</h3>
    <ul id="userList">
      <li data-id="1">张三</li>
      <li data-id="2">李四</li>
      <li data-id="3">王五</li>
    </ul>
  </div>
  <div class="operate-section">
    <button id="addBtn">关联到选中角色></button>
    <button id="removeBtn">移除选中关联</button>
  </div>
  <div class="list-section">
    <h3>待选角色</h3>
    <ul id="roleList">
      <li data-id="101">管理员</li>
      <li data-id="102">编辑</li>
      <li data-id="103">访客</li>
    </ul>
  </div>
</div>
<div class="result-section">
  <h3>已关联关系</h3>
  <ul id="relationList"></ul>
</div>

样式补充

为了让列表可交互,我们给可点击的列表项添加基础样式,区分选中状态:

.container {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}
.list-section {
  width: 200px;
  border: 1px solid #ccc;
  padding: 10px;
}
.list-section ul {
  list-style: none;
  padding: 0;
}
.list-section li {
  padding: 8px;
  margin: 5px 0;
  border: 1px solid #eee;
  cursor: pointer;
}
.list-section li.selected {
  background-color: #e6f7ff;
  border-color: #1890ff;
}
.operate-section {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
}
.result-section {
  border: 1px solid #ccc;
  padding: 10px;
  width: 600px;
}
.result-section li {
  padding: 8px;
  margin: 5px 0;
  border-bottom: 1px solid #eee;
}

交互逻辑实现

接下来编写JavaScript逻辑,实现列表项选中、关联关系添加和移除的功能:

// 存储当前选中的用户和角色
let selectedUser = null;
let selectedRole = null;
// 存储所有关联关系
let relations = [];

// 初始化列表项选中事件
function initSelectEvent(listId) {
  const list = document.getElementById(listId);
  list.addEventListener('click', function(e) {
    if (e.target.tagName === 'LI') {
      // 清除同列表其他选中状态
      const items = list.querySelectorAll('li');
      items.forEach(item => item.classList.remove('selected'));
      // 设置当前选中
      e.target.classList.add('selected');
      // 根据列表id存储选中值
      if (listId === 'userList') {
        selectedUser = { id: e.target.dataset.id, name: e.target.textContent };
      } else if (listId === 'roleList') {
        selectedRole = { id: e.target.dataset.id, name: e.target.textContent };
      }
    }
  });
}

// 添加关联关系
function addRelation() {
  if (!selectedUser || !selectedRole) {
    alert('请先选中用户和角色');
    return;
  }
  // 检查是否已存在相同关联
  const exist = relations.some(item => item.userId === selectedUser.id && item.roleId === selectedRole.id);
  if (exist) {
    alert('该关联关系已存在');
    return;
  }
  // 添加关联
  relations.push({
    userId: selectedUser.id,
    userName: selectedUser.name,
    roleId: selectedRole.id,
    roleName: selectedRole.name
  });
  // 更新展示
  renderRelations();
}

// 移除关联关系
function removeRelation() {
  const relationList = document.getElementById('relationList');
  const selectedRelation = relationList.querySelector('.selected');
  if (!selectedRelation) {
    alert('请先选中要移除的关联关系');
    return;
  }
  const index = parseInt(selectedRelation.dataset.index);
  relations.splice(index, 1);
  // 更新展示
  renderRelations();
}

// 渲染已关联关系列表
function renderRelations() {
  const relationList = document.getElementById('relationList');
  relationList.innerHTML = '';
  relations.forEach((item, index) => {
    const li = document.createElement('li');
    li.textContent = `${item.userName} - ${item.roleName}`;
    li.dataset.index = index;
    li.addEventListener('click', function() {
      const items = relationList.querySelectorAll('li');
      items.forEach(i => i.classList.remove('selected'));
      this.classList.add('selected');
    });
    relationList.appendChild(li);
  });
}

// 初始化事件绑定
initSelectEvent('userList');
initSelectEvent('roleList');
document.getElementById('addBtn').addEventListener('click', addRelation);
document.getElementById('removeBtn').addEventListener('click', removeRelation);

功能说明

上述代码实现的功能逻辑如下:

  • 点击左侧用户列表或右侧角色列表的条目,会高亮显示选中状态,同时存储当前选中的记录信息
  • 选中一个用户和一个角色后,点击中间关联到选中角色按钮,会在下方已关联关系列表中新增一条关联记录
  • 点击已关联关系列表中的条目选中后,点击移除选中关联按钮,会删除对应的关联关系
  • 重复添加相同的关联关系时会给出提示,避免重复数据

扩展说明

如果需要支持同时选中多个用户或多个角色,只需要调整选中逻辑,将selectedUserselectedRole改为数组存储,同时在添加关联时遍历数组生成所有可能的组合即可。如果数据需要从后端获取,只需要在页面加载时通过接口请求数据,动态生成对应的列表项就可以适配实际业务场景。

HTMLJavaScript多对多关联UI交互DOM操作修改时间:2026-06-02 03:57:58

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。