上篇搭建了 EasyUI Layout 框架,本篇实现左侧手风琴菜单点击 → 右侧动态打开/切换 Tab 页 → iframe 加载业务页面的完整交互闭环。
<div data-options="region:'west', title:'系统操作', split:true" style="width:200px">
<div id="menu" class="easyui-accordion" data-options="fit:true">
<div title="基础操作" data-options="iconCls:'icon-save'">
<ul>
<li><a href="#" data-url="send_category_query.action">分类管理</a></li>
<li><a href="#" data-url="send_product_query.action">商品管理</a></li>
</ul>
</div>
<div title="其他操作" data-options="iconCls:'icon-reload'">
<ul>
<li><a href="#" data-url="send_order_query.action">订单管理</a></li>
</ul>
</div>
</div>
</div>
<div data-options="region:'center', title:'后台操作页面'">
<div id="tabs" class="easyui-tabs" data-options="fit:true">
<div title="系统首页" data-options="closable:false">
欢迎使用易购商城后台管理系统
</div>
</div>
</div>
关键设计:data-url 存储目标 Action 地址,不使用 href 避免页面跳转,实现单页应用体验。
<script>
$(function() {
// 事件委托:菜单区域所有带 data-url 的链接
$('#menu a[data-url]').click(function(e) {
e.preventDefault();
var $this = $(this);
var title = $this.text().trim();
var url = $this.data('url');
openTab(title, url);
});
function openTab(title, url) {
var $tabs = $('#tabs');
// 1. 已存在 → 直接选中
if ($tabs.tabs('exists', title)) {
$tabs.tabs('select', title);
return;
}
// 2. 不存在 → 新建 Tab,iframe 加载
$tabs.tabs('add', {
title: title,
closable: true, // 显示关闭按钮
iconCls: 'icon-standard', // 默认图标
content: createIframe(url) // iframe 字符串
});
}
function createIframe(url) {
return '<iframe src="' + url + '" frameborder="0" ' +
'style="width:100%;height:100%;border:none;"></iframe>';
}
});
</script>
<style>
#menu ul { list-style: none; padding: 0; margin: 0; }
#menu ul li { border-bottom: 1px solid #fff; }
#menu ul li a {
display: block;
padding: 8px 12px;
background: #00a6ac;
color: #fff;
text-decoration: none;
transition: background 0.2s;
}
#menu ul li a:hover { background: #008792; }
#menu ul li a:active { background: #007078; }
</style>
// SendAction.java
@Action(value = "send_*_*", results = {
@Result(name = "send", location = "/WEB-INF/{1}/{2}.jsp")
})
public class SendAction extends ActionSupport {
public String execute() { return "send"; }
}
配合 data-url="send_category_query.action" 自动映射 /WEB-INF/category/query.jsp,新增页面只需在对应目录建 JSP,零配置。
<%@ include file="/public/head.jspf" %>
<body>
<div id="toolbar" style="padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" onclick="add()">新增</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-edit" onclick="edit()">编辑</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-remove" onclick="remove()">删除</a>
</div>
<table id="dg" class="easyui-datagrid"
data-options="
url:'category_queryJoinAccount.action',
toolbar:'#toolbar',
pagination:true,
fitColumns:true,
singleSelect:true
">
<thead>
<tr>
<th data-options="field:'ck',checkbox:true"></th>
<th data-options="field:'id',width:80">编号</th>
<th data-options="field:'type',width:150">分类名称</th>
<th data-options="field:'hot',width:80,formatter:hotFmt">热销</th>
<th data-options="field:'account.login',width:150">管理员</th>
</tr>
</thead>
</table>
<script>
function hotFmt(val) {
return val ? '<input type="checkbox" checked disabled>' : '<input type="checkbox" disabled>';
}
function add() { /* 打开编辑对话框 */ }
function edit() { /* 获取选中行打开编辑 */ }
function remove() { /* 批量删除确认 */ }
</script>
</body>
| 特性 | iframe 模式 (推荐) | href 模式 |
|---|---|---|
| 页面隔离 | 完全隔离,样式/JS 不冲突 | 共享主页上下文,易冲突 |
| 加载性能 | 完整页面加载,稍慢 | 仅片段加载,较快 |
| 交互通信 | 需 postMessage/父子窗口通信 | 直接调用主页 JS 函数 |
| 适用场景 | 复杂业务页面、第三方嵌入 | 简单片段、表单弹窗内容 |