我正在使用显示聊天消息的离子编写应用程序。当项目在列表中可见时,是否有任何角度指令或离子解决方案来获取回调?
提前致谢 - 图萨尔
答案 0 :(得分:2)
我很长时间都在寻找解决方案。最后,我通过手动循环浏览项目并检查每个项目在屏幕中的位置来做到这一点。这不是一个很好的解决方案,但没有找到任何其他简单的解决方案。我也进行了一些优化以减少循环。这是摘录代码 -
function startProcessingMessageReadingStatus() {
var lastItemVisibilityStatus = new MessageDisplayStatus(false, 0);
for (var i = $scope.messagesToBeDisplayed.length - 1; i >= 0; i--) {
if (isScrollingStarted === true) {
break; // quit processing message visibility as user started scrolling again
}
console.log('checking message : ' + i);
var message = $scope.messagesToBeDisplayed[i];
var isAlreadyMarkedAsRead = isMessageMarkedAsRead(message);
if (isAlreadyMarkedAsRead === false) {
var visibilityStatus = isMessageItemVisible(message);
if (visibilityStatus.visible === true) {
lastItemVisibilityStatus = visibilityStatus;
markMessageAsRead(message);
} else { // item not visible
// check if last item above the current one was ALSO not visible, if so then better to avoid un-neccessary looping to check for visibility.
// Also, new message items while paginating are added on top, so only avoiding the checking of bottom elements outside the screen may be sufficient.
if ( (lastItemVisibilityStatus.visible === false) && (lastItemVisibilityStatus.offset > 0) && (visibilityStatus.offset > 0) && ((visibilityStatus.offset - lastItemVisibilityStatus.offset) > 0) ) {
lastItemVisibilityStatus = visibilityStatus;
console.log('Was going further below offscreen, Stopping loop at: ' + i);
break;
} else if ( (lastItemVisibilityStatus.visible === false) && (lastItemVisibilityStatus.offset < 0) && (visibilityStatus.offset < 0) && ((lastItemVisibilityStatus.offset - visibilityStatus.offset) > 0) ) {
lastItemVisibilityStatus = visibilityStatus;
console.log('Was going further top offscreen, Stopping loop at: ' + i);
break;
}
lastItemVisibilityStatus = visibilityStatus;
}
}
}
}
function isMessageItemVisible(message) { // this method returns an object of MessageDisplayStatus
var item = document.getElementById('message-item-'+message.id); // each element has an id starting with 'message-item-'
if (item === undefined) {
return new MessageDisplayStatus(false, 0);
}
var scrollPosition = scrollDelegate.getScrollPosition();
var scrollWindowHeight = scrollView.getBoundingClientRect().height;
var itemPosition = ionic.DomUtil.getPositionInParent(item);
var topDistance = scrollPosition.top + scrollWindowHeight;
var itemBottom = itemPosition.top + item.getBoundingClientRect().height;
// ------ --------------- -----------------------------
// /|\ | | /|\
// | | | | ---> scrollPosition.top
// i | | | |
// t | |_____________| _____________________\|/___
// e | [ ] /|\
// m | [ ] |
// | [ ] |
// p | [ ] |
// o | [ ] |
// s | [ ] |----> scrollWindowHeight ( Scrollable window )
// i | [ ] |
// t | [ ] |
// i | [ ] |
// o | [_____________] __\|/_____
// n | | |
// ____\|/___ | ___________ | ______
// || An Item || \_____ itemHeight
// ||___________|| ______/
// | |
// | |
// ---------------
//
if ((itemBottom < topDistance) && (itemPosition.top > scrollPosition.top)) {
console.log('MessageId: ' + message.id + ' is completely visible. Text: ' + message.text.slice(0,100));
var itemVisibilityStatus = new MessageDisplayStatus(true, null);
return itemVisibilityStatus;
} else if ((itemBottom < topDistance) && ((itemPosition.top + numberOfVerticalPixelsInMessageAllowedOutsideOfVisibleArea) > scrollPosition.top)) {
console.log('MessageId: ' + message.id + ' is almost fully visible from top : Text: ' + message.text.slice(0,50));
var itemVisibilityStatus = new MessageDisplayStatus(true, null);
return itemVisibilityStatus;
} else if ((itemBottom < topDistance) && (itemPosition.top > scrollPosition.top)) {
console.log('MessageId: ' + message.id + ' is almost fully visible from bottom : Text: ' + message.text.slice(0,50));
var itemVisibilityStatus = new MessageDisplayStatus(true, null);
return itemVisibilityStatus;
} else if (topDistance < itemBottom) {
var itemVisibilityStatus = new MessageDisplayStatus(false, itemBottom - topDistance);
return itemVisibilityStatus;
} else if (itemPosition.top < scrollPosition.top) {
var itemVisibilityStatus = new MessageDisplayStatus(false, itemPosition.top - scrollPosition.top);
return itemVisibilityStatus;
} else {
return new MessageDisplayStatus(false, 0);
}
}
这是一个有效的解决方案,但我会寻找更好的性能解决方案。希望这会有所帮助并提醒一下。