Angularjs: 如何在div中滚动到滚动条底部时触发事件?
Angularjs: How to trigger event when scroll reaches to the bottom of the scroll bar in div?
我试图在滚动条到达末尾时触发一个事件。我找到了这个 this example。这是我的代码。问题是它根本不调用 loadmore() 。
控制台语句的值是:
848
899
in scroll
881
899
in scroll
892
899
in scroll
897
899
in scroll
900
899
好像从来没有到那个if语句!奇怪的是,如果我在 inspect element 中调试它,它就会触发事件。
.....
我的指令:
directive('scrolly', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var raw = element[0];
console.log('loading directive');
element.bind('scroll', function () {
console.log('in scroll');
console.log(raw.scrollTop + raw.offsetHeight);
console.log(raw.scrollHeight);
if (raw.scrollTop + raw.offsetHeight == raw.scrollHeight) { //at the bottom
scope.$apply(attrs.scrolly);
}
})
}
}
请检查 if 语句中的左侧是否大于右侧,而不是检查是否相等,因为滚动条位于底部就是这种情况。
raw.scrollTop + raw.offsetHeight > raw.scrollHeight
这是工作 jsfiddle。
我一直在寻找一个片段来帮助我做到这一点,但找不到任何有价值的东西,所以我想出了这个相当容易使用的指令来做到这一点
'use strict';
// Tested with Angular 1.3, 1.4.8
angular.module('scrollToEnd', [])
/**
* @ngdoc directive
* @name scrollToEnd:scrollToEnd
* @scope
* @restrict A
*
* @description
* Supply a handler to be called when this element is scrolled all the way to any extreme.
* The callback must have the following signature:
* void function (direction:'top'|'bottom'|'left'|'right')
* If the `bindToWindow` attribute is truthy, the callback will be issued for the window
* instead of the element that the directive is on.
*
* Example usage:
* `<div scroll-to-end="scrollToEndWindow" bind-to-window="true">`
* This will call the controller's `scrollToEndWindow` function whenever the window reaches
* the edges when scrolling. If the div itself is a scrollable element for which the
* handler should be called instead, remove the bind-to-window attribute entirely.
*
* @param {function} emScrollToEnd Callback to be invoked
* @param {boolean} bindToWindow Bind to the window instead of the element
*
*/
.directive('scrollToEnd', function ($window) {
// Get the specified element's computed style (height, padding, etc.) in integer form
function getStyleInt(elem, prop) {
try {
return parseInt(window.getComputedStyle(elem, null).getPropertyValue(prop), 10);
} catch (e) {
return parseInt(elem.currentStyle[prop], 10);
}
}
// Get the 'innerHeight' equivalent for a non-window element, including padding
function getElementDimension(elem, prop) {
switch (prop) {
case 'width':
return getStyleInt(elem, 'width') +
getStyleInt(elem, 'padding-left') +
getStyleInt(elem, 'padding-right');
case 'height':
return getStyleInt(elem, 'height') +
getStyleInt(elem, 'padding-top') +
getStyleInt(elem, 'padding-bottom');
/*default:
return null;*/
}
}
return {
restrict: 'A',
scope: {
callback: '=scrollToEnd'
},
link: function (scope, elem, attr) {
var callback = scope.callback || function () {};
var boundToWindow = attr.bindToWindow;
var body = document.body;
var html = document.documentElement;
var boundElement = boundToWindow ? angular.element($window) : elem;
var oldScrollX = 0;
var oldScrollY = 0;
var handleScroll = function () {
// Dimensions of the content, including everything scrollable
var contentWidth;
var contentHeight;
// The dimensions of the container with the scrolling, only the visible part
var viewportWidth;
var viewportHeight;
// The offset of how much the user has scrolled
var scrollX;
var scrollY;
if (boundToWindow) {
// Window binding case - Populate Dimensions
contentWidth = Math.max(
body.scrollWidth,
body.offsetWidth,
html.clientWidth,
html.scrollWidth,
html.offsetWidth
);
contentHeight = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight
);
viewportWidth = window.innerWidth;
viewportHeight = window.innerHeight;
scrollX = (window.pageXOffset || html.scrollLeft) - (html.clientLeft || 0);
scrollY = (window.pageYOffset || html.scrollTop) - (html.clientTop || 0);
} else {
// DOM element case - Populate Dimensions
var domElement = boundElement[0];
contentWidth = domElement.scrollWidth;
contentHeight = domElement.scrollHeight;
viewportWidth = getElementDimension(domElement, 'width');
viewportHeight = getElementDimension(domElement, 'height');
scrollX = domElement.scrollLeft;
scrollY = domElement.scrollTop;
}
var scrollWasInXDirection = oldScrollX !== scrollX;
var scrollWasInYDirection = oldScrollY !== scrollY;
oldScrollX = scrollX;
oldScrollY = scrollY;
if (scrollWasInYDirection && scrollY === 0) {
callback('top');
} else if (scrollWasInYDirection && scrollY === contentHeight - viewportHeight) {
callback('bottom');
} else if (scrollWasInXDirection && scrollX === 0) {
callback('left');
} else if (scrollWasInXDirection && scrollX === contentWidth - viewportWidth) {
callback('right');
}
};
boundElement.bind('scroll', handleScroll);
// Unbind the event when scope is destroyed
scope.$on('$destroy', function () {
boundElement.unbind('scroll', handleScroll);
});
}
};
});
https://gist.github.com/podrezo/f80f35d6d0655f4d550cac4747c110ff
这里有一个 jsfiddle 可供试用:
https://jsfiddle.net/va4x5r26/2/
适用于 Angular 1.3 和 1.4.8,并在 IE10 和 Chrome 55 上测试。
你给了我一些很好的提示......这是一个完整的工作示例,供任何偶然发现此问题的人使用 post:
JS:
app.controller("controller", function ($scope) {
$scope.test = function () {
alert("hello!");
}
}
HTML:
<div class="br-section1" on-scroll-to-bottom="test()">
</div>
应用指令:
app.directive('onScrollToBottom', function ($document) {
//This function will fire an event when the container/document is scrolled to the bottom of the page
return {
restrict: 'A',
link: function (scope, element, attrs) {
var doc = angular.element($document)[0].body;
$document.bind("scroll", function () {
//console.log('in scroll');
//console.log("scrollTop + offsetHeight:" + (doc.scrollTop + doc.offsetHeight));
//console.log("scrollHeight: " + doc.scrollHeight);
if (doc.scrollTop + doc.offsetHeight >= doc.scrollHeight) {
//run the event that was passed through
scope.$apply(attrs.onScrollToBottom);
}
});
}
};
});
当浏览器的滚动条向下移动时,我们需要触发一个事件。以下代码适用于 Angular 6.
import { HostListener } from '@angular/core';
@HostListener('window:scroll', ['$event'])
onScroll(): void {
if ((window.innerHeight + window.scrollY) >= (document.documentElement.scrollHeight - 1)) {
// Place your code here
}
}
我采用了 Mark 的代码并进行了一些更改以添加对 div 元素的支持。
请注意,您可以定义另一个属性来配置阈值(在我的例子中为 50)。
angular.module('O2DigitalSite').directive('onScrollToBottom', function ($document) {
//This function will fire an event when the container/document is scrolled to the bottom of the page
return {
restrict: 'A',
link: function (scope, element, attrs) {
var ele = element[0];
element.bind("scroll", function () {
//console.log((ele.scrollTop + ele.offsetHeight) + " / " + (ele.scrollHeight));
if (ele.scrollTop + ele.offsetHeight >= ele.scrollHeight - 50) {
//run the event that was passed through
scope.$apply(attrs.onScrollToBottom);
}
});
}
};
});
我试图在滚动条到达末尾时触发一个事件。我找到了这个 this example。这是我的代码。问题是它根本不调用 loadmore() 。 控制台语句的值是:
848
899
in scroll
881
899
in scroll
892
899
in scroll
897
899
in scroll
900
899
好像从来没有到那个if语句!奇怪的是,如果我在 inspect element 中调试它,它就会触发事件。 ..... 我的指令:
directive('scrolly', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var raw = element[0];
console.log('loading directive');
element.bind('scroll', function () {
console.log('in scroll');
console.log(raw.scrollTop + raw.offsetHeight);
console.log(raw.scrollHeight);
if (raw.scrollTop + raw.offsetHeight == raw.scrollHeight) { //at the bottom
scope.$apply(attrs.scrolly);
}
})
}
}
请检查 if 语句中的左侧是否大于右侧,而不是检查是否相等,因为滚动条位于底部就是这种情况。
raw.scrollTop + raw.offsetHeight > raw.scrollHeight
这是工作 jsfiddle。
我一直在寻找一个片段来帮助我做到这一点,但找不到任何有价值的东西,所以我想出了这个相当容易使用的指令来做到这一点
'use strict';
// Tested with Angular 1.3, 1.4.8
angular.module('scrollToEnd', [])
/**
* @ngdoc directive
* @name scrollToEnd:scrollToEnd
* @scope
* @restrict A
*
* @description
* Supply a handler to be called when this element is scrolled all the way to any extreme.
* The callback must have the following signature:
* void function (direction:'top'|'bottom'|'left'|'right')
* If the `bindToWindow` attribute is truthy, the callback will be issued for the window
* instead of the element that the directive is on.
*
* Example usage:
* `<div scroll-to-end="scrollToEndWindow" bind-to-window="true">`
* This will call the controller's `scrollToEndWindow` function whenever the window reaches
* the edges when scrolling. If the div itself is a scrollable element for which the
* handler should be called instead, remove the bind-to-window attribute entirely.
*
* @param {function} emScrollToEnd Callback to be invoked
* @param {boolean} bindToWindow Bind to the window instead of the element
*
*/
.directive('scrollToEnd', function ($window) {
// Get the specified element's computed style (height, padding, etc.) in integer form
function getStyleInt(elem, prop) {
try {
return parseInt(window.getComputedStyle(elem, null).getPropertyValue(prop), 10);
} catch (e) {
return parseInt(elem.currentStyle[prop], 10);
}
}
// Get the 'innerHeight' equivalent for a non-window element, including padding
function getElementDimension(elem, prop) {
switch (prop) {
case 'width':
return getStyleInt(elem, 'width') +
getStyleInt(elem, 'padding-left') +
getStyleInt(elem, 'padding-right');
case 'height':
return getStyleInt(elem, 'height') +
getStyleInt(elem, 'padding-top') +
getStyleInt(elem, 'padding-bottom');
/*default:
return null;*/
}
}
return {
restrict: 'A',
scope: {
callback: '=scrollToEnd'
},
link: function (scope, elem, attr) {
var callback = scope.callback || function () {};
var boundToWindow = attr.bindToWindow;
var body = document.body;
var html = document.documentElement;
var boundElement = boundToWindow ? angular.element($window) : elem;
var oldScrollX = 0;
var oldScrollY = 0;
var handleScroll = function () {
// Dimensions of the content, including everything scrollable
var contentWidth;
var contentHeight;
// The dimensions of the container with the scrolling, only the visible part
var viewportWidth;
var viewportHeight;
// The offset of how much the user has scrolled
var scrollX;
var scrollY;
if (boundToWindow) {
// Window binding case - Populate Dimensions
contentWidth = Math.max(
body.scrollWidth,
body.offsetWidth,
html.clientWidth,
html.scrollWidth,
html.offsetWidth
);
contentHeight = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight
);
viewportWidth = window.innerWidth;
viewportHeight = window.innerHeight;
scrollX = (window.pageXOffset || html.scrollLeft) - (html.clientLeft || 0);
scrollY = (window.pageYOffset || html.scrollTop) - (html.clientTop || 0);
} else {
// DOM element case - Populate Dimensions
var domElement = boundElement[0];
contentWidth = domElement.scrollWidth;
contentHeight = domElement.scrollHeight;
viewportWidth = getElementDimension(domElement, 'width');
viewportHeight = getElementDimension(domElement, 'height');
scrollX = domElement.scrollLeft;
scrollY = domElement.scrollTop;
}
var scrollWasInXDirection = oldScrollX !== scrollX;
var scrollWasInYDirection = oldScrollY !== scrollY;
oldScrollX = scrollX;
oldScrollY = scrollY;
if (scrollWasInYDirection && scrollY === 0) {
callback('top');
} else if (scrollWasInYDirection && scrollY === contentHeight - viewportHeight) {
callback('bottom');
} else if (scrollWasInXDirection && scrollX === 0) {
callback('left');
} else if (scrollWasInXDirection && scrollX === contentWidth - viewportWidth) {
callback('right');
}
};
boundElement.bind('scroll', handleScroll);
// Unbind the event when scope is destroyed
scope.$on('$destroy', function () {
boundElement.unbind('scroll', handleScroll);
});
}
};
});
https://gist.github.com/podrezo/f80f35d6d0655f4d550cac4747c110ff
这里有一个 jsfiddle 可供试用:
https://jsfiddle.net/va4x5r26/2/
适用于 Angular 1.3 和 1.4.8,并在 IE10 和 Chrome 55 上测试。
你给了我一些很好的提示......这是一个完整的工作示例,供任何偶然发现此问题的人使用 post:
JS:
app.controller("controller", function ($scope) {
$scope.test = function () {
alert("hello!");
}
}
HTML:
<div class="br-section1" on-scroll-to-bottom="test()">
</div>
应用指令:
app.directive('onScrollToBottom', function ($document) {
//This function will fire an event when the container/document is scrolled to the bottom of the page
return {
restrict: 'A',
link: function (scope, element, attrs) {
var doc = angular.element($document)[0].body;
$document.bind("scroll", function () {
//console.log('in scroll');
//console.log("scrollTop + offsetHeight:" + (doc.scrollTop + doc.offsetHeight));
//console.log("scrollHeight: " + doc.scrollHeight);
if (doc.scrollTop + doc.offsetHeight >= doc.scrollHeight) {
//run the event that was passed through
scope.$apply(attrs.onScrollToBottom);
}
});
}
};
});
当浏览器的滚动条向下移动时,我们需要触发一个事件。以下代码适用于 Angular 6.
import { HostListener } from '@angular/core';
@HostListener('window:scroll', ['$event'])
onScroll(): void {
if ((window.innerHeight + window.scrollY) >= (document.documentElement.scrollHeight - 1)) {
// Place your code here
}
}
我采用了 Mark 的代码并进行了一些更改以添加对 div 元素的支持。 请注意,您可以定义另一个属性来配置阈值(在我的例子中为 50)。
angular.module('O2DigitalSite').directive('onScrollToBottom', function ($document) {
//This function will fire an event when the container/document is scrolled to the bottom of the page
return {
restrict: 'A',
link: function (scope, element, attrs) {
var ele = element[0];
element.bind("scroll", function () {
//console.log((ele.scrollTop + ele.offsetHeight) + " / " + (ele.scrollHeight));
if (ele.scrollTop + ele.offsetHeight >= ele.scrollHeight - 50) {
//run the event that was passed through
scope.$apply(attrs.onScrollToBottom);
}
});
}
};
});