基于 PHP 与 Dojo DnD 模块实现用户界面布局拖拽保存
本文介绍如何利用 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 结构
目的:建立可拖拽的源元素和多个可放置的目标容器,并定义容器间的合法拖拽路径。
关键代码逻辑:
- 加载 Dojo 包:引入
dojo.style和dojo.dnd.*。 - 注册拖拽源:遍历具有
.divdrag类的元素,使用dojo.dnd.HtmlDragSource将其注册为可拖动项,并指定其父级容器 ID。 - 注册放置目标:创建一个根容器
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 处理的字符串格式。
动作说明:
- 构建一个函数
bjsave()。 - 遍历所有模块元素(
mokuai1,mokuai2...)。 - 检查元素的
parentElement.id,如果不在根容器container0中,则记录该模块 ID 及其父容器 ID。 - 拼接格式:
模块ID|容器ID$模块ID|容器ID...(使用$分隔每组记录,|分隔键值)。 - 将结果赋值给隐藏字段
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
核心步骤:
- 清理数据:执行
DELETE FROM geren WHERE gh=[当前用户],清空该用户的历史布局,防止累积脏数据。 - 解析数据:
- 移除字符串中的
container前缀(如需纯净数字 ID)。 - 首先按
$分割数组。 - 再按
|分割每个元素,分别得到mokuaiid和biaogeid。
- 移除字符串中的
- 写入数据库:循环遍历解析后的数组,执行
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 前端交互与数据库设计的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













