Ok wizards,有人知道怎么做......
我有一个非常复杂的自定义控件,可以呈现x个人的可用性信息(可能是1个可能是100个)。 日历呈现控件属性中指定的任何给定日期范围。
这意味着控件可能会很长,所有这些数据都会呈现为html表。
每个人姓名出现在第一列中,我希望修复该列,并让表格的其余部分水平滚动,以便用户浏览整个日期范围,但可以看到人名。
那么我如何修复表格中的第一列,看起来像下面的代码...
<table>
<tr><td></td><td colspan='31'>Jan</td><td colspan='28'>feb</td>...</tr>
<tr><td></td><td>1</td><td>2</td><td>3</td> ...<tr/>
<tr><td>Person 1</td><td></td><td></td><td>Busy</td> ...<tr/>
<tr><td>Person 2</td><td></td><td>Busy</td><td>Busy</td> ...<tr/>
</table>
如果它以任何方式有用,这是一个C#应用程序(asp.net),如果需要我可以使用javascript。
谢谢你们:)
答案 0 :(得分:3)
Here's a solution by Markku Uttula通过CSS和HTML的组合实现这一点(下图)。令我惊讶的是,即使在IE6上也能以合理的性能运行。五,令人印象深刻由于某些原因,Chrome,Opera和Firefox上的滚动条最终位于冻结的列/行下方,但希望条形图足够大以至于不会出现问题......
CSS:
body { margin: 0; height: 100% }
.b { border-collapse: collapse }
.b td { border: 1px solid #f80; vertical-align: top }
p { margin: 1px; padding: 0; font-size: 9px; font-family: Arial }
p.c { text-align: center; font-size: 12px }
p span { font-size: 12px; white-space:nowrap; color: #888 }
/* TopLeft fixed corner */
td.bg101 { background-color: #ffc }
/* Top fixed rows */
td.bg000 { background-color: #f8c }
td.bg001 { background-color: #f4c }
/* Left fixed rows */
td.bg110 { background-color: #fcc }
td.bg111 { background-color: #fcf }
/* The scrollable content area */
td.bg010 { background-color: #fff }
td.bg011 { background-color: #ff4 }
JavaScript的:
var ieBug = ((document.all) && (!window.opera)); // IE doesn't really handle fixed elements well :)
var fpElement = false;
function fpCW() { return document.documentElement ? document.documentElement.clientWidth : document.clientWidth; }
function fpCH() { return document.documentElement ? document.documentElement.clientHeight : document.clientHeight; }
function fpTopLeft(elementNode, iTop, iLeft) {
elementNode.style.top = (iTop)+"px";
elementNode.style.left = (iLeft)+"px";
}
function fpDefaults(elementNode) {
elementNode.style.position = ieBug ? "absolute" : "fixed";
fpTopLeft(elementNode,0,0);
return elementNode;
}
function fpClone(elementNode, cloneZindex) {
var clone = fpDefaults(elementNode.cloneNode(true));
clone.style.background = "#fff";
clone.style.overflow = "hidden";
clone.style.border = "none";
clone.style.zIndex = cloneZindex;
return clone;
}
function fpInitFreezePanes(fpTableElementId, fpTableContainerDivElementId, fpPivotCellId, fpDisableBodyScrollbars) {
if (fpElement !== false) {
alert("Page already contains an element with fixed panes.");
} else {
var fpTableElement = document.getElementById(fpTableElementId);
var fpTableContainerDivElement = document.getElementById(fpTableContainerDivElementId);
var fpPivotCell = document.getElementById(fpPivotCellId);
if ((!fpTableElement) || (!fpTableContainerDivElement) || (!fpPivotCell)) {
alert("Unable to find table, container or pivoting cell?");
} else {
fpElement = fpTableContainerDivElement;
if (fpDisableBodyScrollbars) {
var x = document.getElementsByTagName("body")[0];
x.style.overflow = "hidden";
x = document.getElementsByTagName("html")[0];
x.style.overflow = "hidden";
}
fpTableContainerDivElement = fpDefaults(fpTableContainerDivElement);
fpTableContainerDivElement.style.width = (fpCW()-2)+"px";
fpTableContainerDivElement.style.height = (fpCH()-2)+"px";
fpTableContainerDivElement.fpPT = fpPivotCell.offsetTop;
fpTableContainerDivElement.fpPL = fpPivotCell.offsetLeft;
var copy1 = fpClone(fpTableContainerDivElement, 4);
copy1.style.width = (fpTableContainerDivElement.fpPL)+"px";
copy1.style.height = (fpTableContainerDivElement.fpPT)+"px";
var copy2 = fpClone(fpTableContainerDivElement, 3);
copy2.style.width = (fpTableElement.offsetWidth)+"px";
copy2.style.height = (fpTableContainerDivElement.fpPT)+"px";
var copy3 = fpClone(fpTableContainerDivElement, 2);
copy3.style.width = (fpTableContainerDivElement.fpPL)+"px";
copy3.style.height = (fpTableElement.offsetHeight)+"px";
fpTableContainerDivElement.style.zIndex = 1;
fpTableContainerDivElement.appendChild(copy1);
fpTableContainerDivElement.copy1 = copy1;
fpTableContainerDivElement.appendChild(copy2);
fpTableContainerDivElement.copy2 = copy2;
fpTableContainerDivElement.appendChild(copy3);
fpTableContainerDivElement.copy3 = copy3;
fpTableContainerDivElement.repositioning = false;
fpTableContainerDivElement.oldST = -1;
fpTableContainerDivElement.oldSL = -1;
fpTableContainerDivElement.style.overflow = "scroll";
/* JUST SOME STYLING HERE */
copy1.style.borderRight = "1px dashed #000";
copy1.style.borderCollapse = "collapse";
copy2.style.borderBottom = "1px dashed #000";
copy2.style.borderCollapse = "collapse";
copy3.style.borderRight = "1px dashed #000";
copy3.style.borderCollapse = "collapse";
/* JUST SOME STYLING HERE */
// if (ieBug) {
if (fpTableContainerDivElement.style.setExpression) {
function fpIeBugFix(elementNode, containerNodeId, arrayOfExpressionsToSet) {
for (var i in arrayOfExpressionsToSet) {
if (arrayOfExpressionsToSet[i][2]) {
elementNode.style.setExpression(arrayOfExpressionsToSet[i][0], arrayOfExpressionsToSet[i][1]+"document.getElementById('"+containerNodeId+"')."+arrayOfExpressionsToSet[i][2]+"+'px'");
} else {
elementNode.style.setExpression(arrayOfExpressionsToSet[i][0], arrayOfExpressionsToSet[i][1]);
}
}
}
fpIeBugFix(fpTableContainerDivElement.copy3, fpTableContainerDivElementId, [["top","","scrollTop"],["left","","scrollLeft"],["marginTop","-","scrollTop"]]);
fpIeBugFix(fpTableContainerDivElement.copy2, fpTableContainerDivElementId, [["top","","scrollTop"],["left","","scrollLeft"],["marginLeft","-","scrollLeft"]]);
fpIeBugFix(fpTableContainerDivElement.copy1, fpTableContainerDivElementId, [["top","","scrollTop"],["left","","scrollLeft"]]);
fpIeBugFix(fpTableContainerDivElement, fpTableContainerDivElementId, [["width","fpCW()+'px'"],["height","fpCH()+'px'"]]);
document.recalc(true);
} else {
fpElement.onmousemove = fpElement.onscroll = function() {
if (!this.repositioning) {
this.repositioning = true;
var st = this.scrollTop;
var sl = this.scrollLeft;
if ((this.oldST != st) || (this.oldSL != sl)) {
this.oldST = st;
this.oldSL = sl;
// this.copy3.previousDisplay = this.copy3.style.display;
// this.copy3.style.display = "none";
this.copy3.style.marginTop = "-"+(st)+"px";
// this.copy3.style.display = this.copy3.previousDisplay;
// this.copy2.previousDisplay = this.copy2.style.display;
// this.copy2.style.display = "none";
this.copy2.style.marginLeft = "-"+(sl)+"px";
// this.copy2.style.display = this.copy2.previousDisplay;
}
fpElement.repositioning = false;
}
};
window.onresize = function() {
fpElement.style.width = fpCW()+"px";
fpElement.style.height = fpCH()+"px";
}
}
}
}
}
答案 1 :(得分:1)
好的,所以根据上面的表格,我已经有了我必须假设固定的列有固定的宽度,但我设法做到了这一点......
<div style="position:relative;">
<div style="width:100%; overflow:scroll; height:400px;">
<table style="margin-left:100px;">
<tr><td style="position:absolute;"></td><td colspan='31'>Jan</td><td colspan='28'>feb</td>...</tr>
<tr><td style="position:absolute;"></td><td>1</td><td>2</td><td>3</td> ...<tr/>
<tr><td style="position:absolute;">Person 1</td><td></td><td></td><td>Busy</td> ...<tr/>
<tr><td style="position:absolute;">Person 2</td><td></td><td>Busy</td><td>Busy</td> ...<tr/>
</table>
</div>
</div>
这导致标记的单元格在左侧占据绝对位置,并且表格仍然可滚动... 需要做一些工作来清理它并使它看起来很漂亮,但基本上我的代码在提取时看起来像这样......
<style type="text/css">
.Calendar { max-height:400px; border-collapse:collapse; table-layout:fixed; margin-left:105px; }
.Calendar .Resources { width:100px; position:absolute; left:0px; background:white; }
.Calendar tr { vertical-align:top; }
.Calendar td { border:solid 1px black; vertical-align:top; padding:2px; border:solid 1px #EFEFEF; }
.Calendar .day { background:#FFFBD6; border:solid 1px #FEEFB3; }
.Calendar .dayWithEvent { background:white; border:solid 1px #FEEFB3; border-top:solid 1px blue; }
</style>
<div style="position:relative;">
<div style="width:100%; overflow:scroll; height:400px;">
<table class="Calendar">
<asp:Repeater ID="ui_calMonths" runat="server" onitemdatabound="ui_calMonths_ItemDataBound">
<HeaderTemplate>
<tr><td class="Resources" style="background:white; border:none;"> </td>
</HeaderTemplate>
<ItemTemplate>
<td colspan='<%# ((Month)Container.DataItem).Days.Length %>'><%# Eval("Name") %></td>
</ItemTemplate>
<FooterTemplate>
</tr>
<tr><td class="Resources" style="background:white; border:none;"> </td>
<asp:Repeater ID="ui_calDays" runat="server">
<ItemTemplate>
<td><%# ((DateTime)Container.DataItem).ToString("dd") %></td>
</ItemTemplate>
</asp:Repeater>
</tr>
</FooterTemplate>
</asp:Repeater>
<asp:Repeater ID="ui_grdResources" runat="server">
<HeaderTemplate><tr></HeaderTemplate>
<ItemTemplate>
<td class="Resources"><%# Eval("Text") %></td>
<%# ResourceEvents(((RowContext)Container.DataItem)) %>
</ItemTemplate>
<FooterTemplate></tr></FooterTemplate>
</asp:Repeater>
</table>
</div>
</div>
基本上代码隐藏计算每行要渲染多少个单元格(转发器是这个工作的基础,但结果基本上是一个格式很好的表,其中包含第一行中给定日期范围的月份名称,日期对于那些在第二个和第三个月的固定列,包含名称和从我的内部API日历项目动态填充...非常酷!!!
答案 2 :(得分:0)
获取jquery datatables fixedcolumns插件