我想在时间轴日历中制作一个交叉点悬停效果。
我用CSS在日历和交叉点悬停效果上做了另一个表。
它工作正常,但如果我们有一个事件,有一个描述在多行(或多个事件在同一时间),行高是不同的,我的悬停效果不工作OK -它重叠,如下图所示。代码可在https://codepen.io/timotejmedved/pen/vYVepaQ?editors=0110上获得
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'today prev,next',
center: 'title',
right: 'resourceTimelineDay,resourceTimelineWeek'
},
aspectRatio: 1.6,
initialView: 'resourceTimelineDay',
resourceGroupField: 'building',
slotDuration: '00:15:00',
resources: [
{ id: '1', title: 'Resource A' },
{ id: '2', title: 'Resource B' },
{ id: '3', title: 'Resource C' },
{ id: '4', title: 'Resource A' },
{ id: '5', title: 'Resource B' },
{ id: '6', title: 'Resource C' },
{ id: '11', title: 'Resource A' },
{ id: '21', title: 'Resource B' },
{ id: '31', title: 'Resource C' },
{ id: '41', title: 'Resource A' },
{ id: '51', title: 'Resource B' },
{ id: '61', title: 'Resource C' },
{ id: '111', title: 'Resource A' },
{ id: '211', title: 'Resource B' },
{ id: '311', title: 'Resource C' },
{ id: '411', title: 'Resource A' },
{ id: '511', title: 'Resource B' },
{ id: '611', title: 'Resource C' },
{ id: '19', title: 'Resource A' },
{ id: '29', title: 'Resource B' },
{ id: '39', title: 'Resource C' },
{ id: '49', title: 'Resource A' },
{ id: '59', title: 'Resource B' },
{ id: '69', title: 'Resource C' },
{ id: '191', title: 'Resource A' },
{ id: '291', title: 'Resource B' },
{ id: '319', title: 'Resource C' },
{ id: '419', title: 'Resource A' },
{ id: '519', title: 'Resource B' },
{ id: '619', title: 'Resource C' },
{ id: '1191', title: 'Resource A' },
{ id: '2191', title: 'Resource B' },
{ id: '3191', title: 'Resource C' },
{ id: '4191', title: 'Resource A' },
{ id: '5191', title: 'Resource B' },
{ id: '6191', title: 'Resource C' },
],
events: [
{ resourceId: '1', start: '2023-05-02T02:00:00', end: '2023-05-02T07:00:00', title: 'event 1' },
{ resourceId: '2', start: '2023-05-02T05:00:00', end: '2023-05-02T09:00:00', title: 'event 2' },
{ resourceId: '3', start: '2023-05-02T03:00:00', end: '2023-05-02T08:00:00', title: 'event 3' },
{ resourceId: '4', start: '2023-05-02T06:00:00', end: '2023-05-02T12:00:00', title: 'event 4' },
{ resourceId: '5', start: '2023-05-02T08:00:00', end: '2023-05-02T13:00:00', title: 'event 5' },
{ resourceId: '6', start: '2023-05-02T10:00:00', end: '2023-05-02T14:00:00', title: 'event 6' },
{ resourceId: '1', start: '2023-05-02T13:00:00', end: '2023-05-02T18:00:00', title: 'event 7' },
{ resourceId: '2', start: '2023-05-02T10:00:00', end: '2023-05-02T14:00:00', title: 'event 8' },
{ resourceId: '3', start: '2023-05-02T08:00:00', end: '2023-05-02T12:30:00', title: 'event 9' }
],
eventContent: function (arg) {
var event = arg.event;
var customHtml = '';
customHtml += "<span class='r10 font-xxs font-bold' style='overflow: hidden;'>" + event.title + "</span>";
customHtml += "<span class='r10 highlighted-badge font-xxs font-bold'> <br/> jkaSDHLKJahsdlkjAHS</span>";
return { html: customHtml }
},
eventDidMount: function (info) {
},
viewDidMount: function (info) {
var rowHeights = document.querySelectorAll('.fc-timeline-body .fc-scrollgrid-sync-table tbody tr');
var numResources = document.querySelectorAll('table.fc-datagrid-body tbody tr').length;
var resourcesHeights = document.querySelectorAll('table.fc-datagrid-body tbody tr')
console.log(resourcesHeights.item(1))
console.log(resourcesHeights.values())
var tt = resourcesHeights.item(0);
const compStyles = window.getComputedStyle(tt);
var height = compStyles.getPropertyValue("height");
console.log(height)
// create new table element
var hoverTable = document.createElement('table');
hoverTable.classList.add('hover-table');
// get the main table element
var mainTable = document.querySelector('.fc-timeline-body table');
console.log("maintable");
console.log(mainTable.offsetHeight * 3);
//var cellWidth = mainTable.querySelector('td').offsetWidth;
//var rowHeight = mainTable.querySelector('tr').offsetHeight;
var cellWidth = 30;
// var rowHeight = 34.4;
var rowHeight = 34;
//console.log(rowHeight)
// set the position, width, and height of the hover table
hoverTable.style.position = 'absolute';
hoverTable.style.top = mainTable.offsetTop + 'px';
hoverTable.style.left = mainTable.offsetLeft + 'px';
hoverTable.style.width = (cellWidth * 3) + 'px';
hoverTable.style.height = (rowHeight * 3) + 'px';
hoverTable.style.border = 'none';
hoverTable.style.borderRadius = '0';
hoverTable.style.boxShadow = 'none';
hoverTable.style.backgroundColor = 'transparent';
hoverTable.style.borderWidth = '0';
// add rows and cells to the hover table
for (var i = 0; i < numResources + 1; i++) {
var row = document.createElement('tr');
if (i == 0) {
row.style.height = '32.5 px';
} else {
row.style.height = rowHeight + 'px';
}
for (var j = 0; j < 48; j++) {
var cell = document.createElement('td');
cell.style.width = cellWidth + 'px';
row.appendChild(cell);
}
hoverTable.appendChild(row);
}
// add the hover table to the DOM
mainTable.parentNode.insertBefore(hoverTable, mainTable.nextSibling);
// add event listeners to the cells of the hover table
var hoverCells = hoverTable.querySelectorAll('td');
hoverCells.forEach(function (cell) {
cell.addEventListener('mouseenter', function () {
cell.classList.add('hover');
});
cell.addEventListener('mouseleave', function () {
cell.classList.remove('hover');
});
});
}
});
calendar.render();
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
/*.fc-timeline-slot-lane:hover{
background-color: lightgray;
}
.fc-timeline-lane:hover{
background-color: lightgray;
}*/
.fc-time-grid-container .fc-slats td:hover,
.fc-time-grid-container .fc-major td:hover {
background-color:red;
}
.hover{
background-color: red;
}
.overlay {
position: absolute;
z-index: 1;
top: 0;
left: 0;
pointer-events: none;
}
.overlay-cell {
position: absolute;
pointer-events: auto;
transition: background-color 0.2s;
}
.overlay-cell.hover {
background-color: rgba(0, 0, 0, 0.1);
}
.hover-table{
background-color: grey;
}
.hover-table {
overflow: hidden;
}
.hover-table tr:hover {
background-color: rgba(215, 215, 215, 0.29);
}
.hover-table td, th {
position: relative;
}
.hover-table td:hover::after,
.hover-table th:hover::after {
content: "";
position: absolute;
background-color: rgba(215, 215, 215, 0.29);
left: 0;
top: -5000px;
height: 10000px;
width: 100%;
z-index: -1;
}
/*
.hover-table td:first-child {
background-color: rebeccapurple;
}
.hover-table tr:first-child {
background-color: rebeccapurple;
}*/
.hover-table td {
border: none;
}
/*način 2 za row hover*/
/*
.hover-table {
pointer-events: none;
background-color: transparent;
}
.fc-timeline-slots{
pointer-events: none;
background-color: transparent;
}
.fc-timeline-body .fc-scrollgrid-sync-table tbody tr:hover{
background-color: red;
}
*/
<script src="https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@6.1.6/index.global.min.js"></script>
<div id='calendar'></div>
我尝试了不同的方法,例如尝试获取每行的clientHeight
属性,但我没有获取当前值。然后我尝试使用鼠标位置。我也试过使用pointer-events: none;
,但是我只能显示行悬停,而不能同时显示列和行。我还尝试了mouseenter
事件,但由于fullcalendar
在行元素之上有列,所以我只得到列的hover元素。
1条答案
按热度按时间7nbnzgx91#
列突出显示可以通过将CSS应用于悬停的
.fc-timeline-slot-lane
元素来完成:但是对于行,我们不能使用相同的
:hover
选择器,因为上面的.fc-timeline-slot-lane
覆盖了行,所以我们需要添加一些JavaScript来帮助我们。我们可以重写viewDidMount
来帮助我们:对于单元格的红色矩形,我们可以使用列,并使用更多JavaScript调整其背景,以定位红色矩形以匹配我们悬停的行:
CSS变量
--top
和--height
将从JavaScript传递过来:这里是所有放在一起: