Question Description
When customizing cell content using customLayout, including Text and Image, I would like to have some custom logic when hovering over the Image. Currently, the mouse-enter event for the cell cannot distinguish between specific targets.
For DOM elements in JavaScript, the mouseenter event is triggered only once when the mouse pointer enters (moves over) the element. So is there an event like mouseenter_cell to monitor specified content in custom cells?
Solution
You can bind the mouseenter and mouseleave events to the image dom of the custom layout 'customLayout'.
Code example
You can paste it into the official editor to test:
https://visactor.io/vtable/demo/custom-render/custom-cell-layout-jsx
const VGroup = VTable.VGroup;
const VText = VTable.VText;
const VImage = VTable.VImage;
const VTag = VTable.VTag;
const option = {
container: document.getElementById('container'),
columns: [
{
field: 'bloggerId',
title: 'bloggerId'
},
{
field: 'bloggerName',
title: 'bloggerName',
width: 330,
customLayout: args => {
const { table, row, col, rect } = args;
const { height, width } = rect || table.getCellRect(col, row);
const record = table.getRecordByRowCol(col, row);
// const jsx = jsx;
const container = (
<VGroup
attribute={{
id: 'container',
width,
height,
display: 'flex',
flexWrap: 'nowrap',
justifyContent: 'flex-start',
alignContent: 'center'
}}
>
<VGroup
id="container-right"
attribute={{
id: 'container-right',
width: width - 60,
height,
fill: 'yellow',
opacity: 0.1,
display: 'flex',
flexWrap: 'nowrap',
flexDirection: 'column',
justifyContent: 'space-around',
alignItems: 'center'
}}
>
<VGroup
attribute={{
id: 'container-right-top',
fill: 'red',
opacity: 0.1,
width: width - 60,
height: height / 2,
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'flex-start',
alignItems: 'center'
}}
>
<VText
attribute={{
id: 'bloggerName',
text: record.bloggerName,
fontSize: 13,
fontFamily: 'sans-serif',
fill: 'black',
textAlign: 'left',
textBaseline: 'top',
boundsPadding: [0, 0, 0, 10]
}}
></VText>
<VImage
attribute={{
id: 'location-icon',
width: 15,
height: 15,
image:
'<svg t="1684484908497" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2429" width="200" height="200"><path d="M512 512a136.533333 136.533333 0 1 1 136.533333-136.533333 136.533333 136.533333 0 0 1-136.533333 136.533333z m0-219.272533a81.92 81.92 0 1 0 81.92 81.92 81.92 81.92 0 0 0-81.92-81.92z" fill="#0073FF" p-id="2430"></path><path d="M512 831.214933a27.306667 27.306667 0 0 1-19.2512-8.055466l-214.493867-214.357334a330.5472 330.5472 0 1 1 467.490134 0l-214.357334 214.357334a27.306667 27.306667 0 0 1-19.387733 8.055466z m0-732.091733a275.933867 275.933867 0 0 0-195.106133 471.04L512 765.269333l195.106133-195.106133A275.933867 275.933867 0 0 0 512 99.1232z" fill="#0073FF" p-id="2431"></path><path d="M514.321067 979.490133c-147.456 0-306.107733-37.000533-306.107734-118.3744 0-45.602133 51.746133-81.92 145.681067-102.4a27.306667 27.306667 0 1 1 11.605333 53.384534c-78.370133 17.066667-102.673067 41.915733-102.673066 49.015466 0 18.432 88.064 63.761067 251.4944 63.761067s251.4944-45.192533 251.4944-63.761067c0-7.3728-25.258667-32.768-106.496-49.834666a27.306667 27.306667 0 1 1 11.195733-53.384534c96.6656 20.343467 150.186667 56.9344 150.186667 103.2192-0.273067 80.964267-158.9248 118.3744-306.3808 118.3744z" fill="#0073FF" p-id="2432"></path></svg>',
boundsPadding: [0, 0, 0, 10],
cursor: 'pointer'
}}
stateProxy={stateName => {
if (stateName === 'hover') {
return {
background: {
fill: 'green',
cornerRadius: 5,
expandX: 1,
expandY: 1
}
};
}
}}
onPointerEnter={event => {
event.currentTarget.addState('hover', true, false);
event.currentTarget.stage.renderNextFrame();
}}
onPointerLeave={event => {
event.currentTarget.removeState('hover', false);
event.currentTarget.stage.renderNextFrame();
}}
></VImage>
<VText
attribute={{
id: 'locationName',
text: record.city,
fontSize: 11,
fontFamily: 'sans-serif',
fill: '#6f7070',
textAlign: 'left',
textBaseline: 'top'
}}
></VText>
</VGroup>
</VGroup>
</VGroup>
);
// decode(container)
return {
rootContainer: container,
renderDefault: false
};
}
},
{
field: 'fansCount',
title: 'fansCount',
fieldFormat(rec) {
return rec.fansCount + 'w';
},
style: {
fontFamily: 'Arial',
fontSize: 12,
fontWeight: 'bold'
}
},
{
field: 'worksCount',
title: 'worksCount',
style: {
fontFamily: 'Arial',
fontSize: 12,
fontWeight: 'bold'
}
},
{
field: 'viewCount',
title: 'viewCount',
fieldFormat(rec) {
return rec.fansCount + 'w';
},
style: {
fontFamily: 'Arial',
fontSize: 12,
fontWeight: 'bold'
}
},
{
field: 'viewCount',
title: 'viewCount',
fieldFormat(rec) {
return rec.fansCount + 'w';
},
style: {
fontFamily: 'Arial',
fontSize: 12,
fontWeight: 'bold'
}
},
{
field: '',
title: 'operation',
width: 100,
icon: ['favorite', 'message']
}
],
records: [
{
bloggerId: 6,
bloggerName: 'Virtual anchor bird',
bloggerAvatar: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/custom-render/bird.jpeg',
introduction:
'Hello everyone, I am the virtual anchor Xiaoniao. I like singing, acting and variety shows. I hope to be happy with everyone through the live broadcast.',
fansCount: 900,
worksCount: 12,
viewCount: 8,
city: 'Happy City',
tags: ['music', 'performance', 'variety']
}
],
defaultRowHeight: 80
};
const instance = new VTable.ListTable(document.getElementById(CONTAINER_ID), option);
window.tableInstance = instance;
documents
demo: https://visactor.io/vtable/demo/custom-render/custom-cell-layout-jsx
Relevant api:https://visactor.io/vtable/option/ListTable-columns-text#customLayout
Tutorial:https://visactor.io/vtable/guide/custom_define/custom_layout
github:https://github.com/VisActor/VTable
Top comments (1)