Open corneliusabel opened 3 years ago
Hi ! Thanks for your feedback ! Glad you like it.
First i would like to know which items are currently displayed on the screen (not in the DOM outside the screen) to present some extra info like a date range. Is there a function like getVisibleItems() which gives you an arry of the displayed items, or how can that be achived??
I guess gallery.visibleCollection
is not what you want ?!
Are you talking about the images visible in the viewport ? If the users scrolls, the list change ?
Second i would like to jump (scroll) to a certain image (which has not necessarily been loaded). Is there a way to calculate the position and do some scrollTop so it??
I would say this is not something that should be included in the gallery because the navigation is part of the consuming application. For example : the element that triggers the scroll action does not belong to the gallery. It's something external in your own GUI. Furthermore, the management of the scroll may depend on many factors (the scrollElement can contain more than just the gallery). Manipulate the scroll from the gallery can be too much intrusive for some use cases and it's better to provide full control to the parent's app developper.
For those reasons, I don't think it's relevant to implement such feature.
At this point I think there is no reliable solution to fulfill your need. I see two things I could implement to allow that :
1) Add an ID to the inputed model and use it as an unique attribute in the DOM
2) Change the item-added-to-dom
event to include a reference to related DOM element.
Both methods allow the developer to get a reference to the DOM element that matches a model. Using it's coordinates, this allows to trigger the scroll action.
This would work only for items already added to the DOM. For those that are in still the buffer or not yet retrieved from the server, the only solution is to start a scroll loop until the wanted item is added to DOM.
It's definitely something too specific and too intrusive (on the scroll and on the server) to be implemented into this gallery, but I can implement the tools to make it achievable.
First i would like to know which items are currently displayed on the screen
I'm interested in this too.
I'm guessing the only way is to iterate over all elements and check if they are within the current viewport?
If I do this, is there any easy way to get the item data for a given image element?
My use case is that I want to update the url as the user scrolls so that if they refresh the page I can start them where they left off.
Edit:
Ah, just saw what you said about adding item ids to the DOM elements, that would be very useful.
So far I've come up with this:
function onScroll(event: Event) {
let firstColumn = document.querySelector(".column") as HTMLElement;
let imageElements = firstColumn.querySelectorAll(".figure.loaded");
let firstVisible = Array.from(imageElements).find(el => {
let rect = el.getBoundingClientRect();
return rect.bottom > 0 && rect.top < window.innerHeight;
});
console.log(firstVisible);
};
This should get you the first visible image on the page, and you'd want to debounce this function.
The awkward thing right now is getting the item data for that image element. I'm going to have to do something horrible like parse the ID out of the background image url and then use that to look up the item in a separate item map or something..
@johtso
collection / visibleCollection both expose both html element reference and image item object
I'm using this to get first currently visible item (only before reload in my case):
let visibilityCheck = (rect) => {
return rect.bottom > 0 && rect.top < window.innerHeight;
};
let getModelIdField = () => {
return getPField(); // custom get id field name method here
};
let firstVisibleItem = naturalGalleryObj.visibleCollection.find(
(item) => {
return visibilityCheck(
item._element.getBoundingClientRect()
);
}
);
let firstVisibleItemId =
firstVisibleItem?.model[getModelIdField()] || "";
console.log(firstVisibleItemId);
just wrote that actually as I went to check what I had there before and realized it didn't work for masonry mode, heh
anyways, I think that should solve the problem of finding image ID?
@kfsz that's awesome, thank you! Didn't know item had that _element
property.
I'm still not completely clear what visibleCollection
contains. I think it's all elements that have at some point been seen and had their image loaded?
@johtso
yeah, visibleCollection
contains all elements visible in the DOM - from start to the bottom of the page (including these not yet seen by user but which have their space in DOM reserved - and are currently probably loading)
collection
additionally contains elements which have been passed to NG via setItems
/ addItems
, but user has not yet scrolled far enough to display them - basically, when you set 100 images via setItems
NG will display only like ~30 initially, and as user scrolls down add next ~10, then next ~10, and so on - updating visibleCollection
not exactly sure how many images NG adds at once or when images are exactly added (after scroll) but that's more or less how it works 😃
@kfsz thanks for clearing that up for me!
I guess the advantage of finding the elements via the DOM is I can ignore all images that aren't in the first column, saving a lot of iterations if there are a lot of images loaded. Maybe not significant enough to worry about though.
@johtso
also, hmm, NG emits pagination
event when it loads new items (and updates visibleCollection
) - maybe you could update query params then? it won't update when user scrolls up to see previous items, but maybe that would be enough?
and good point about searching first column, item
also has last
private property which indicates if it's last item in the row - maybe we could use that, hm - I changed my code to check for that before getBoundingClientRect()
, which probably doesn't really change anything, but it should be fast enough for my case.
DOM would be faster, yeah, but hm, you could probably (at least in natural gallery mode) find index of that element in parent div and you should be able to access this element with naturalGalleryObj.visibleCollection[index]
or add image.setAttribute('natural-gallery-id', "" + this.model.id);
if you don't mind changing this library's source 😛
First of all, really great gallery!!! I used it with a django backend to serve and display photo in my home cloud.
However, Iam missing two features: First i would like to know which items are currently displayed on the screen (not in the DOM outside the screen) to present some extra info like a date range. Is there a function like getVisibleItems() which gives you an arry of the displayed items, or how can that be achived??
Second i would like to jump (scroll) to a certain image (which has not necessarly been loaded). Is there a way to calculate the position and do some scrollTop so it??
Best,
Cornelius