问题
According to this link : up/down arrow key issue with typeahead control (angular bootstrap UI)
i have added these line in my js:
.directive('shouldFocus', function(){
return {
restrict: 'A',
link: function(scope,element,attrs){
scope.$watch(attrs.shouldFocus,function(newVal,oldVal){
element[0].scrollIntoView(false);
});
}
};
})
while scrolling, we get some more disturb, scroll was not smoothy. Before adding this code, scroll was normal and smoothy. Please anyone help me?
回答1:
Hi here is another code only for keyup event to adjust the scroll height while up/down keypress you need to add a function only to keyup in the typeahead directive in angular ui
search directive('typeahead' in the angular ui js file find fireRecalculating function before it paste the following function
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));
}
}
});
}
now find keyup function attached. call the above function
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;
}
}
});
}
I bumped into the same issue with latest version of angular bootstrap 0.14.3 as of 27/11/2015.
Comments:
I placed the function in the element.bind("keydown") since it didn't work where you suggested. (function wasn't in proper scope and was undefined)
The first "if" wasn't triggered for me so i changed the logic a bit. When user reaches the end the dropdown scrolls to top properly in my case.
Modified it to work for plain javascript.
Thank you for your solution!
回答3:
I had previously resolved this issue using the "shouldFocus" directive but I had to make more tweaks to get this to work. Perhaps this version will work for you.
.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);
}
}
});
}
}
})
Here is the modified template for those who don't know where to add the directive:
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" +
"");
}]);
来源:https://stackoverflow.com/questions/31760938/angular-ui-bootstrap-typeahead-suggestion-scroll