【问题标题】:Angular ui-bootstrap typeahead suggestion - scrollAngular ui-bootstrap typeahead 建议 - 滚动
【发布时间】:2015-08-01 10:40:48
【问题描述】:
【问题讨论】:
标签:
angularjs
angular-ui-bootstrap
bootstrap-typeahead
【解决方案1】:
嗨,这里是另一个仅用于 keyup 事件的代码,用于在向上/向下按键时调整滚动高度
您只需要在 angular ui 中的 typeahead 指令中的 keyup 中添加一个函数
在angular ui js文件中搜索directive('typeahead'
在粘贴以下函数之前找到 fireRecalculating 函数
function makeSureVisible(){
$timeout(function(){
$el = popUpEl.find('.active');
if($el.length>0)
{
var elTop, elBottom, nodeScrollTop, nodeHeight;
elTop = $el.position().top;
console.log(elTop);
elBottom = elTop + $el.outerHeight(true);
nodeScrollTop = popUpEl.scrollTop();
nodeHeight = popUpEl.height() + parseInt(popUpEl.css("paddingTop"), 10) + parseInt(popUpEl.css("paddingBottom"), 10);
if (elTop < 0) {
popUpEl.scrollTop(nodeScrollTop + elTop);
} else if (nodeHeight < elBottom) {
popUpEl.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
}
}
});
}
现在找到附加的 keyup 功能。调用上面的函数
element.bind('keydown', function(evt) {
//typeahead is open and an "interesting" key was pressed
if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {
return;
}
// if there's nothing selected (i.e. focusFirst) and enter or tab is hit, clear the results
if (scope.activeIdx === -1 && (evt.which === 9 || evt.which === 13)) {
resetMatches();
scope.$digest();
return;
}
evt.preventDefault();
if (evt.which === 40) {
scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
scope.$digest();
makeSureVisible();
} else if (evt.which === 38) {
scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1;
scope.$digest();
makeSureVisible();
} else if (evt.which === 13 || evt.which === 9) {
scope.$apply(function () {
scope.select(scope.activeIdx);
});
} else if (evt.which === 27) {
evt.stopPropagation();
resetMatches();
scope.$digest();
}
});
【解决方案2】:
function makeSureVisible() {
$timeout(function () {
$el = popUpEl[0].querySelector('.active');
if ($el) {
var elTop, elBottom, nodeScrollTop, nodeHeight;
elTop = $el.offsetTop;
elBottom = elTop + $el.offsetHeight;
nodeScrollTop = popUpEl[0].scrollTop;
nodeHeight = popUpEl[0].offsetHeight - (parseInt(window.getComputedStyle(popUpEl[0], null).getPropertyValue('padding-top')) + parseInt(window.getComputedStyle(popUpEl[0], null).getPropertyValue('padding-bottom')));
if (elTop < nodeScrollTop) {
popUpEl[0].scrollTop = elTop;
} else if (nodeHeight < elBottom) {
popUpEl[0].scrollTop = nodeScrollTop + elBottom - nodeHeight;
}
}
});
}
截至 2015 年 11 月 27 日,我在 angular bootstrap 0.14.3 的最新版本中遇到了同样的问题。
评论:
我将该函数放在 element.bind("keydown") 中,因为它在您建议的地方不起作用。 (函数不在适当的范围内且未定义)
我没有触发第一个“如果”,所以我稍微改变了逻辑。在我的情况下,当用户到达末尾时,下拉菜单会正确滚动到顶部。
将其修改为适用于纯 javascript。
感谢您的解决方案!
【解决方案3】:
我之前使用“shouldFocus”指令解决了这个问题,但我必须进行更多调整才能使其正常工作。也许这个版本对你有用。
.directive('shouldFocus', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(attrs.shouldFocus, function (newVal, oldVal) {
if (newVal && element.prop("class").indexOf("active")) {
var par = element.parent("ul");
var cellHeight = element.children().innerHeight();
var maxHeight = par.height();
var startIndex = Math.floor(maxHeight / cellHeight);
if (scope.$index > startIndex) {
var scroll = (scope.$index - startIndex) * cellHeight;
par.scrollTop(scroll);
}
if (scope.$index === 0) {
par.scrollTop(0);
}
}
});
}
}
})
这里是修改后的模板,供不知道在哪里添加指令的人使用:
angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/typeahead/typeahead-popup.html",
"<ul class=\"dropdown-menu\" ng-show=\"isOpen() && !moveInProgress\" ng-style=\"{top: position().top+'px', left: position().left+'px'}\" style=\"display: block;\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
" <li ng-repeat=\"match in matches track by $index\" should-focus=\"isActive($index)\" ng-class=\"{active: isActive($index) }\" ng-click=\"selectMatch($index)\" role=\"option\" id=\"{{::match.id}}\">\n" +
" <div typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
" </li>\n" +
"</ul>\n" +
"");
}]);