基于 PHP 与 Dojo DnD 模块实现用户界面布局拖拽保存

码头散步
码头散步
发布时间:2026-10-13| 5人浏览过
原创

本文介绍如何利用 PHP 后端配合 Dojo Toolkit 的 HtmlDragSource 与 HtmlDropTarget 模块,实现网页界面的动态布局拖拽。通过 JS 收集模块 ID 与容器 ID 的对应关系,利用隐藏表单提交至 PHP 解析,最终将定制化布局持久化存储于数据库中,支持用户个性化配置。

实现目标

允许用户通过鼠标拖拽方式,在网页的不同容器(如侧边栏、主内容区)之间自由移动功能模块(Widgets/Modules),并将最终的布局状态保存至数据库,以便下次登录时恢复用户的个性化布局。

准备工作

1. 环境要求:

  • 服务器端:安装支持 mssql 扩展的 PHP 环境。
  • 客户端:需加载 Dojo Toolkit 库。本示例基于经典版本进行演示,建议在实际生产环境中使用维护更新的 Dojo 版本或现代前端框架。

2. 数据库表结构示意:

  • module:存储所有可用的功能模块信息(ID、名称、标记等)。
  • geren:存储用户个性化布局数据(mokuaiid:模块ID, biaogeid:布局区域ID, gh:用户编号/GH)。

具体操作顺序

第1步:初始化拖拽环境与 DOM 结构

目的:建立可拖拽的源元素和多个可放置的目标容器,并定义容器间的合法拖拽路径。

关键代码逻辑:

  1. 加载 Dojo 包:引入 dojo.style 和 dojo.dnd.*。
  2. 注册拖拽源:遍历具有 .divdrag 类的元素,使用 dojo.dnd.HtmlDragSource 将其注册为可拖动项,并指定其父级容器 ID。
  3. 注册放置目标:创建一个根容器 container0 作为“回收站”或初始池,并为每个具体的布局区域(如 container1, container2 等)创建 dojo.dnd.HtmlDropTarget,设置允许的拖放来源列表,确保模块可以在不同区域及根容器间流动。
<script type="text/javascript">
// 引用以下两个 dojo 包 
dojo.require("dojo.style");
dojo.require("dojo.dnd.*");

function init(){
    // 利用 classname 取到元素列表,将其注册为 dojo.dnd.HtmlDragSource
    var arr = dojo.html.getElementsByClass('divdrag');
    for(var i=0; i<arr.length; i++){
        // 注意:原稿代码此处变量引用略有瑕疵,实际应指向 arr[i]
        var parentDiv = arr[i].parentNode.id; 
        new dojo.dnd.HtmlDragSource(arr[i], parentDiv);
    }
    
    // 动态生成 DropTarget 的逻辑通常结合后端返回的 num 值进行循环构造
    // 此处展示概念结构
    new dojo.dnd.HtmlDropTarget("container0", ['container0', /* 其他容器ID列表 */]);
}
window.onload=function(){init();}
</script>

第2步:构建页面与渲染模块

目的:根据当前登录用户的权限,从数据库获取未分配模块显示在根容器,并根据已保存的布局数据显示在特定容器中。

PHP 处理逻辑:

  • 验证 Session($_SESSION['gh'])。
  • 查询 module 表获取模块总数。
  • 在 HTML 中动态生成 CSS 样式及 Dojo 配置脚本。
  • 渲染两个主要的布局列(通过奇偶数区分 biaogeid),并填充对应的模块。
<?php
session_start();
if ($_SESSION['gh']=='') {
    header('location:login.php');
}
include("config.php");
$sql="select * from module";
$result=mssql_query($sql,$conn);
$num=mssql_num_rows($result);
?>

<!-- 页面主体结构略 -->
<div id="container0">
    <?php 
    // 获取未分配给任何布局区域的模块,放入根容器供用户拖入任意位置
    $sql='select * from module where id not in (select mokuaiid from geren where gh ='.$_SESSION['gh'].')';
    $result=mssql_query($sql,$conn);
    while($myrow=mssql_fetch_array($result)){
        echo '<span class="divdrag" id="mokuai'.$myrow['id'].'" style="border:1px dotted #990033;height: 20px;width:100px;margin: 5px;" title="'.$myrow['mmark'].'">'.$myrow['mn'].'</span>';
    }
    ?>
</div>

第3步:组装拖拽结果数据

目的:当用户点击保存时,JS 需要遍历所有模块,获取它们当前所在的容器 ID,并将其组合成便于 PHP 处理的字符串格式。

动作说明:

  1. 构建一个函数 bjsave()。
  2. 遍历所有模块元素(mokuai1, mokuai2...)。
  3. 检查元素的 parentElement.id,如果不在根容器 container0 中,则记录该模块 ID 及其父容器 ID。
  4. 拼接格式:模块ID|容器ID$模块ID|容器ID...(使用 $ 分隔每组记录,| 分隔键值)。
  5. 将结果赋值给隐藏字段 form1.gr 并提交表单。
<script type="text/javascript">
function bjsave() {
    gr=""
    <?php 
    $sql='select id from module';
    $result=mssql_query($sql,$conn);
    while($myrow=mssql_fetch_array($result)){
        // 生成 JS 条件判断语句
        echo 'if (mokuai'.$myrow['id'].'.parentElement.id !="container0") {';
        echo 'gr=gr+'.$myrow['id'].'+"|"+ mokuai'.$myrow['id'].'.parentElement.id+ "$"';
        echo '}';
    }
    ?>
    form1.gr.value=gr;
    form1.submit();
}
</script>

<form id="form1" name="form1" method="post" action="savegr.php">
    <input name="gr" type="hidden" value="" />
</form>
<input type="button" name="Submit" value="保存布局" onclick="bjsave();" />

第4步:后端解析与持久化

目的:接收提交的字符串,清除旧数据,插入新的布局映射关系。

操作入口:savegr.php

核心步骤:

  1. 清理数据:执行 DELETE FROM geren WHERE gh=[当前用户],清空该用户的历史布局,防止累积脏数据。
  2. 解析数据:
    • 移除字符串中的 container 前缀(如需纯净数字 ID)。
    • 首先按 $ 分割数组。
    • 再按 | 分割每个元素,分别得到 mokuaiid 和 biaogeid。
  3. 写入数据库:循环遍历解析后的数组,执行 INSERT INTO geren (mokuaiid, biaogeid, gh) VALUES (...)`。
<?php
session_start();
if ($_SESSION['gh']=='') {
    header('location:login.php');
}
include("config.php");

// 1. 删除旧布局
$sql='delete from geren where gh='.$_SESSION['gh'];
mssql_query($sql);

// 2. 解析 POST 数据
$gr=str_replace("container","",$_POST['gr']);
$array=explode("$", $gr);

// 3. 循环插入新布局
for ($i=0; $i<count($array)-2; $i++){ // 注意边界处理
    $add=explode("|",$array[$i]);
    $sql='insert into geren (mokuaiid,biaogeid,gh) values ("'.$add[0].'" ,"'.$add[1].'","'.$_SESSION['gh'].'")';
    mssql_query($sql);
}

header("location:view.php");
?>

完成判断

用户在界面上拖拽模块到新位置后,点击“保存布局”,页面跳转回视图页。此时若刷新页面,模块应保持在新位置;且断开连接重新登录后,布局依然存在,即表示数据保存成功。

简要总结

该方案展示了早期 Web 开发中利用 Dojo 强大的拖拽组件与 PHP 服务端交互,实现轻量级 CMS 或 Dashboard 布局个性化的思路。核心在于前端 JS 对 DOM 状态的采集以及后端对特定格式字符串的解析与 SQL 构建。需要注意的是,随着浏览器原生 HTML5 Drag and Drop API 的普及,现代开发更倾向于使用无依赖的原生方案或 Vue/React 等现代框架来实现类似功能,以获得更好的兼容性和性能。

以上就是基于 PHP 与 Dojo DnD 实现用户界面布局拖拽保存的详细内容,更多关于 PHP 前端交互与数据库设计的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。