ExtJS 專案中需實現:滑鼠懸停 Grid 單元格時,ToolTip 以滑鼠位置為左上角顯示詳情表單。雖然 ExtJS 社區活躍度下降,但維護舊專案時仍需掌握此技巧。
cellSelector(每個單元格)detailType, paramsArr) 異步構建表單beforeshow 事件中動態決定是否顯示、內容何值var tip = Ext.create('Ext.tip.ToolTip', {
target: view.el, // 目標元素:Grid 整體容器
delegate: view.cellSelector, // 委派選擇器:只針對單元格觸發
mouseOffset: [-50, -20], // 關鍵:相對滑鼠偏移 (x, y)
trackMouse: false, // false: 固定位置; true: 跟隨滑鼠移動
showDelay: 0, // 立即顯示
dismissDelay: 0, // 不自動隱藏
autoHide: false, // 不自動隱藏(需手動關閉)
frame: true,
layout: 'fit',
items: [{ xtype: 'form' }], // 內容容器
listeners: {
beforeshow: function(tip, eOpts) {
// 動態構建表單邏輯...
return false; // 返回 false 可取消顯示
}
}
});
mouseOffset: [0, 0] 即可讓 ToolTip 左上角對齊滑鼠。原代碼 [-50, -20] 是向左上偏移 50px、20px,若需精確對齊請設為 [0, 0]。
listeners: {
beforeshow: function(tip, eOpts) {
var triggerEl = tip.triggerElement; // 觸發的單元格 DOM
if (!triggerEl) return false;
var detailType = triggerEl.getAttribute('detailType');
var paramsStr = triggerEl.getAttribute('paramsArr');
if (!detailType || !paramsStr) return false; // 無數據不顯示
var paramsArr = paramsStr.split(',');
var titleArr = triggerEl.getAttribute('paramsTitle')?.split(',');
var record = view.getRecord(view.findItemByChild(triggerEl));
if (!record) return false;
var form = tip.down('form');
Ext.suspendLayouts();
form.removeAll();
var fieldMap = {};
paramsArr.forEach(function(value, index) {
var val = record.get(value);
if (!Ext.isEmpty(val)) {
fieldMap[value] = val;
form.add({
xtype: 'displayfield',
name: value,
fieldLabel: titleArr ? titleArr[index] : value,
value: val
});
}
});
if (Ext.Object.isEmpty(fieldMap)) {
Ext.resumeLayouts(true);
return false;
}
// 根據類型調整寬度
switch (detailType) {
case 'orderId': form.maxWidth = 150; break;
case 'transTime': form.maxWidth = 200; break;
case 'payCustName':
case 'payCustCardNo': form.maxWidth = 200; break;
}
form.getForm().setValues(fieldMap);
Ext.resumeLayouts(true);
return true; // 允許顯示
}
}
最佳回答建議:「EXT 框架現在用的人都少了,都使用 jquery 了,換框架吧。」
確實,ExtJS 7+ 商業授權昂貴、社區萎縮。新專案強烈建議:
tippy.js (ToolTip)、ag-Grid (表格) 組合iframe 或微前端整合import tippy from 'tippy.js';
tippy('.grid-cell', {
content: (reference) => {
const form = document.createElement('div');
// 動態構建表單...
return form;
},
allowHTML: true,
interactive: true,
placement: 'right-start', // 滑鼠右側對齊
offset: [0, 0],
trigger: 'mouseenter',
hideOnClick: false
});
總結:ExtJS 中透過 mouseOffset: [0, 0] 可實現滑鼠左上角定位,配合 delegate 和 beforeshow 實現動態內容。但長遠規劃應考慮技術棧現代化遷移。