el-table
文件 element-ui/packages/table/src/table-body.js
截取部分代碼
export default {
render(h) {
return (
<table>
<tbody>
{/* 表格內(nèi)容 ... */}
{/* 一個(gè)表格 只渲染一個(gè) tooltip */}
<el-tooltip effect={this.table.tooltipEffect} placement="top" ref="tooltip" content={this.tooltipContent}></el-tooltip>
</tbody>
</table>
);
},
created() {
this.activateTooltip = debounce(50, tooltip => tooltip.handleShowPopper());
},
methods: {
handleCellMouseEnter(event, row) { // 鼠標(biāo)移入表格項(xiàng) 觸發(fā)事件
const table = this.table;
const cell = getCell(event);
if (cell) {
const column = getColumnByCell(table, cell);
const hoverState = table.hoverState = { cell, column, row };
table.$emit('cell-mouse-enter', hoverState.row, hoverState.column, hoverState.cell, event);
}
// 判斷是否text-overflow, 如果是就顯示tooltip
const cellChild = event.target.querySelector('.cell');
if (!(hasClass(cellChild, 'el-tooltip') && cellChild.childNodes.length)) {
return;
}
// use range width instead of scrollWidth to determine whether the text is overflowing
// to address a potential FireFox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1074543#c3
const range = document.createRange();
range.setStart(cellChild, 0);
range.setEnd(cellChild, cellChild.childNodes.length);
const rangeWidth = range.getBoundingClientRect().width;
const padding = (parseInt(getStyle(cellChild, 'paddingLeft'), 10) || 0) +
(parseInt(getStyle(cellChild, 'paddingRight'), 10) || 0);
if ((rangeWidth + padding > cellChild.offsetWidth || cellChild.scrollWidth > cellChild.offsetWidth) && this.$refs.tooltip) {
// 1. 判斷: 如果寬度溢出
const tooltip = this.$refs.tooltip;
// TODO 會(huì)引起整個(gè) Table 的重新渲染,需要優(yōu)化
this.tooltipContent = cell.innerText || cell.textContent; // 2. 表格項(xiàng)內(nèi)容 賦值給 tooltip顯示
tooltip.referenceElm = cell; // 3. 替換referenceElm, tooltip通過Popper.js 計(jì)算顯示的tooltip和referenceElm的相對(duì)位置
tooltip.$refs.popper && (tooltip.$refs.popper.style.display = 'none');
tooltip.doDestroy(); // 取消tooltip上一系列綁定事件
tooltip.setExpectedState(true);
this.activateTooltip(tooltip); // 4. 顯示tooltip
}
},
handleCellMouseLeave(event) { // 鼠標(biāo)溢出表格項(xiàng) 觸發(fā)事件
const tooltip = this.$refs.tooltip;
if (tooltip) {
tooltip.setExpectedState(false);
tooltip.handleClosePopper(); // 隱藏tooltip
}
const cell = getCell(event);
if (!cell) return;
const oldHoverState = this.table.hoverState || {};
this.table.$emit('cell-mouse-leave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event);
},
}
}
記錄點(diǎn)
- 鼠標(biāo)事件
mouseenter
/mouseleave
(新),mouseover
/mouseout
(舊)
新的鼠標(biāo)移入移出事件,去掉了冒泡和捕獲的特性- mouseenter:鼠標(biāo)第一次移動(dòng)到元素區(qū)域時(shí)觸發(fā) (新)
- mouseleave:移出時(shí)觸發(fā)(新)
- mousemove:在元素上移動(dòng)時(shí)觸發(fā)(一直觸發(fā))
- mouseover:鼠標(biāo)移動(dòng)到元素上時(shí)觸發(fā)(舊)
- mouseout:從元素上移開時(shí)觸發(fā)(舊)
- 步驟
-
el-tooltip
是tbody
的子節(jié)點(diǎn),一個(gè)表格,只渲染一個(gè)el-tooltip
- 監(jiān)聽鼠標(biāo)移入事件
mouseenter
,判斷表格項(xiàng)內(nèi)容是否溢出 - 如果溢出
- 表格項(xiàng)內(nèi)容賦值給 tooltipContent 顯示隱藏內(nèi)容
- 替換
referenceElm
, tooltip通過Popper.js
計(jì)算顯示的tooltip
和referenceElm
的相對(duì)位置 - 顯示 tooltip
- 監(jiān)聽鼠標(biāo)移開事件
mouseleave
,隱藏 tooltip
-
el-tooltip
文件 element-ui/packages/tooltip/src/main.js
截取部分代碼文章來源:http://www.zghlxwxcb.cn/news/detail-495133.html
const PopperJS = require('element-ui/src/utils/popper.js');
export default {
beforeCreate() {
this.popperVM = new Vue({
data: { node: '' },
render(h) {
return this.node;
}
}).$mount();
this.debounceClose = debounce(200, () => this.handleClosePopper());
},
render(h) {
if (this.popperVM) {
this.popperVM.node = (
<transition
name={ this.transition }
onAfterLeave={ this.doDestroy }>
<div
onMouseleave={ () => { this.setExpectedState(false); this.debounceClose(); } }
onMouseenter= { () => { this.setExpectedState(true); } }
ref="popper"
role="tooltip"
id={this.tooltipId}
aria-hidden={ (this.disabled || !this.showPopper) ? 'true' : 'false' }
v-show={!this.disabled && this.showPopper}
class={
['el-tooltip__popper', 'is-' + this.effect, this.popperClass]
}>
{/* 具名插槽 content 渲染在tooltip */}
{ this.$slots.content || this.content }
</div>
</transition>);
}
const firstElement = this.getFirstElement();
if (!firstElement) return null;
const data = firstElement.data = firstElement.data || {};
data.staticClass = this.addTooltipClass(data.staticClass);
return firstElement; // 找到默認(rèn)插槽 default 顯示在組件位置
},
mounted() {
this.referenceElm = this.$el;
// 給 referenceElm 綁定一系列事件, 包括: mouseenter mouseleave
// ...
if (this.value && this.popperVM) {
this.popperVM.$nextTick(() => {
if (this.value) {
this.updatePopper();
}
});
}
},
methods: {
updatePopper() {
const popperJS = this.popperJS;
if (popperJS) {
popperJS.update();
if (popperJS._popper) {
popperJS._popper.style.zIndex = PopupManager.nextZIndex();
}
} else {
this.createPopper();
}
},
createPopper() { // 省略...只剩下需要的邏輯
let reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference;
const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper; // 提示信息ref 對(duì)應(yīng)的DOM
const options = this.popperOptions;
if (!popper || !reference) return;
if (this.appendToBody) document.body.appendChild(this.popperElm); // 渲染在body節(jié)點(diǎn)下
/**
* reference: 默認(rèn)插槽/鼠標(biāo)移入移出顯示tooltip相對(duì)的元素
* popper: 提示信息ref 對(duì)應(yīng)的DOM (tooltip)
* option: 一些配置
*/
this.popperJS = new PopperJS(reference, popper, options);
// ...
}
}
}
記錄點(diǎn):文章來源地址http://www.zghlxwxcb.cn/news/detail-495133.html
- render
- 找到默認(rèn)插槽
default
顯示在組件位置 - 提示信息:
transition
+ 具名插槽content
,鼠標(biāo)移入referenceElm
,顯示提示信息
- 找到默認(rèn)插槽
- mounted:給 referenceElm 綁定一系列事件, 包括:
mouseenter
、mouseleave
,調(diào)用updatePopper
- 調(diào)用
createPopper
- 通過
Popper.js
計(jì)算顯示的 提示信息 和 referenceElm 的相對(duì)位置 - 關(guān)鍵代碼:
this.popperJS = new PopperJS(reference, popper, options);
- reference: 默認(rèn)插槽/
referenceElm
,鼠標(biāo)移入移出顯示 提示信息 相對(duì)的元素 - popper: 提示信息ref 對(duì)應(yīng)的DOM (tooltip)
- option: 一些配置
- reference: 默認(rèn)插槽/
- 通過
到了這里,關(guān)于el-table溢出隱藏 鼠標(biāo)移入顯示tooltip邏輯的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!