我的应用程序中有一个由jquery驱动的动态树菜单,我正在尝试实现粘性。树中的所有父节点最初都会折叠,如果用户打开父节点,则滚动到父节点,我希望父字段粘贴到菜单的顶部,直到用户滚动到最后一个子节点。在那个时候,父母会解开。
有些孩子也是父母。因此,在很多情况下,我希望多个父母被困在最顶层。我的工作几乎没问题,但有些奇怪。
当滚过孩子们时,字段会粘在顶部并按预期消失。但是如果两个父母是开放的,那么第二个节点就不会像它想象的那样解开;它无论如何都会在顶部挂起。
我尝试使用console.log进行调试,但每当我写入控制台时,它都会抛出一个js异常" replace不是未定义的成员"。
jquery,css和html如下。非常感谢任何帮助。
JQuery的
var _currentGenertion;
var _loaded;
var _initialTop;
function ManageFieldListScroller() {
$(".fields-list").scroll(function () {
var divTop = $(".fields-list").position().top;
var newTop = $('.field-item').position().top;
if(newTop < _initialTop) {
stickParentFields(divTop) //scroll up
} else {
restickParentFields(divTop) //scroll down
}
_initialTop = newTop;
});
}
function restickParentFields(divTop) {
$(".openedParent.unstuck").each(function () {
var $nextParent = $(this);
var top = $nextParent.position().top - 1; //"-1" because browsers are stupid
var distanceToTopOfList = top - divTop
var doIt = distanceToTopOfList <= 0
$("div[path='" + $nextParent.attr('fieldid') + "']").each(function (i, item) {
var $nextChild = $('#' + item.id);
var nextChildTop = $nextChild.position().top
var maxChildTop;
if(i==0) {
minChildTop = nextChildTop;
maxChildTop = nextChildTop;
} else {
if(nextChildTop < minChildTop) {
minChildTop = nextChildTop;
} else if(nextChildTop > maxChildTop) {
maxChildTop = nextChildTop;
}
}
if (maxChildTop > divTop) {
_currentGenertion = _currentGenertion + 1;
var className = 'sticky' + _currentGenertion
$nextParent.removeClass('unstuck');
$nextParent.addClass('sticky');
$nextParent.addClass(className);
}
});
});
$(".openedParent.sticky").each(function () {
var $nextParent = $(this);
var top = $nextParent.position().top - 1; //"-1" because browsers are stupid
var distanceToTopOfList = top - divTop
var doIt = distanceToTopOfList <= 0
$("div[path='" + $nextParent.attr('fieldid') + "']").each(function (i, item) {
var $nextChild = $('#' + item.id);
var nextChildTop = $nextChild.position().top
var minChildTop;
if(i==0) {
minChildTop = nextChildTop;
} else {
if(nextChildTop < minChildTop) {
minChildTop = nextChildTop;
}
}
if (minChildTop > divTop) {
var parentClasses = $nextParent.attr('class')
var parentClassesArray = parentClasses.split(/\s+/)
$nextParent.addClass('unstuck');
$.each(parentClassesArray, function (i, css) {
var $currentClass = $(css)
if (css.indexOf('sticky') >= 0) {
$nextParent.removeClass(css);
Unstuck = true
}
});
if (Unstuck == true) {
_currentGenertion = _currentGenertion - 1;
}
}
});
});
}
function stickParentFields(divTop) {
$(".openedParent").not('.unstuck').each(function () {
var $nextParent = $(this);
var top = $nextParent.position().top - 1; //"-1" because browsers are stupid
var distanceToTopOfList = top - divTop
var doIt = distanceToTopOfList <= 0.5
var className = 'sticky' + _currentGenertion;
if (doIt) {
stickParentField(className, divTop, $nextParent)
var scrolledPastField = true;
$("div[path='" + $nextParent.attr('fieldid') + "']").each(function (i, item) {
var $nextChild = $('#' + item.id);
var nextChildTop = $nextChild.position().top
var topDifference = nextChildTop - top;
if (nextChildTop > top) {
scrolledPastField = false;
}
});
// ------------------------------------------------ Unstick Fields ---------------------------------------------
if (scrolledPastField == false) {
//return false;
}
else {
var parentClasses = $nextParent.attr('class')
var parentClassesArray = parentClasses.split(/\s+/)
$nextParent.addClass('unstuck');
$.each(parentClassesArray, function (i, css) {
var $currentClass = $(css)
if (css.indexOf('sticky') >= 0) {
$nextParent.removeClass(css);
}
});
_currentGenertion = _currentGenertion - 1;
}
}
});
}
function stickParentField(className, divTop, $nextParent) {
var parentClasses = $nextParent.attr('class')
if (parentClasses.indexOf(className) < 0) {
var stickyDivCount;
var nextClassName;
var nextClassTop;
className = 'sticky' + _currentGenertion
stickyDivCount = $('.sticky').length
_currentGenertion = stickyDivCount + 1
nextClassName = 'sticky' + _currentGenertion
nextClassTop = (stickyDivCount * 30) + divTop
$("<style type='text/css'> ." + nextClassName + "{ top:" + nextClassTop + "px;} </style>").appendTo("head");
var newUpperMargin = _currentGenertion * 20;
var newHeight = $(".fields-list").height() - 20;
$nextParent.addClass('sticky');
$(".fields-list").css("margin-top", newUpperMargin);
$(".fields-list").height(newHeight);
$nextParent.removeClass('unstuck');
$nextParent.addClass(nextClassName);
$nextParent.css();
}
$(document).ready(function () {
if (_loaded != true) {
_loaded = true;
_currentGenertion = 1;
_initialTop = $('.field-item').position().top
}
ManageFieldListScroller();
});
CSS
.sticky {
position:fixed;
}
.sticky1 {
/* 94.66 is the top of fields-list div, where we want sticky to start */
top:94.66px;
}
.unstuck {
position:relative;
}
HTML
</HeaderTemplate>
<ItemTemplate>
<div id="divNinjaViewField" runat="server" objecttype="field" datatype='<%#Container.DataItem.DataType%>' haschildren='<%#If(Container.DataItem.HasChildren, True, False)%>' class='<%#If((Container.DataItem.IsSibling Or Container.DataItem.HasChildren) And (Container.DataItem.IsNumeric Or Container.DataItem.HasNumericChildren), "parentFieldItem nondrag isNumeric",
If((Container.DataItem.IsSibling Or Container.DataItem.HasChildren), "parentFieldItem nondrag",
If(Container.DataItem.IsNumeric Or Container.DataItem.HasNumericChildren, "field-item isNumeric",
"field-item")))%>'
style="margin-left: 0;" fieldid='<%# Container.DataItem.ID%>' path="" onclick="ParentDivClicked(this, true)" isnumeric='<%# Container.DataItem.IsNumeric %>'>
<div class="clearfix viewField" onmouseover="$(this).css('background-color', '#eee');" onmouseout="$(this).css('background-color', '');">
<span class='<%#If(Container.DataItem.HasChildren, "ui-icon ui-icon-triangle-1-e", "icon-placeholder")%> <%#If(Container.DataItem.IsNumeric, "isNumeric", "")%>' style='float: left; margin-top: -2px; margin-right: .3em;'></span>
<%# Container.DataItem.FriendlyName%>
</div>
</div>
</ItemTemplate>
<FooterTemplate>
<div id="divAdvancedOptions" onclick="AdvancedOptionsDivClicked(this, true)" class="advancedSourceOptions">
<div id="divAdvancedColumnOptions" runat="server" class="AdvancedOptions">
<div class="clearfix" style="color: #000; font-weight: bold; cursor: pointer; padding: 4px; margin-left: 12px;" onmouseover="$(this).css('background-color', '#eee');" onmouseout="$(this).css('background-color', '');">
<span class="ui-icon ui-icon-triangle-1-e advancedColumnOptions" style='float: left; margin-top: -2px; margin-right: .3em;'></span>
Advanced Column Options
<div class="specificAdvancedColumnOptions" style="display: none; font-weight: normal; padding: 4px; margin-left: 24px;">
<div class="advancedOptionItem">
<a id="calculatedFieldLink" href="#" onclick="toggleExpressionEditor(0, true);" class="db_link" style="width: 100%; padding-bottom: 200px;">Calculated Column</a>
</div>
<div class="advancedOptionItem">
<a id="conditionalFieldLink" href="#" runat="server" onserverclick="conditionalFieldLink_ServerClick" class="db_link" style="width: 100%;">Conditional Column</a>
</div>
</div>
</div>
</div>
</div>
</FooterTemplate>