Open Le-future opened 9 years ago
It can be done, but you would need to fix the code that populates the PhotoSwipe 'slides' object. In the PhotoSwipe default example, it looks for direct children of a container element. In your case, you would need to change it to 'find' all a
anchor elements inside your .mygallery
container even when they are not direct children.
I'm looking to do the same thing, did you end up coding this up? I'd love to take a look at your implementation before I take a crack at it.
I'm still looking for a solution...
I am having the exact same issue. I guess I'm not good enough in JS to get this to work...
I gave up about this, I've organized my html code differently to get the same structure than the demo.
That's a shame. I'm thinking about paying someone for that code, that's how desperate I am :D
Extracting it from the DOM in Javascript is just an example. It's actually more limited than you might expect as it needs to extract high resolution URLs as well as dimensions from the DOM.
It's equally simple to output the code to create the "slides" object in a <script>
tag that you output along with the HTML. Actually if you have any server side coding experience and/or database with pictures, resolutions etc. that's most likely simpler.
I'm not entirely sure if I understand what you're getting at. Outputting the whole slides as objects in a inline js script doesn't seem any simpler than messing around with the default js code we have from the documentation...
Same question here :( it seems that it can't be easily done :(
Hello friends, I found a way (using jQuery): http://webdesign.tutsplus.com/tutorials/the-perfect-lightbox-using-photoswipe-with-jquery--cms-23587 but using these modifications: "the click event is more complete in the http://tutsplus.github.io/photoswipe-jquery/js/script-min.js. And finally, the line var $index = $(this).index(); should be var $index = $( "figure" ).index( this ); "
Hi,
I'm also interested in this feature. I made a change on the variable, instead of using childNode I used getElementsByTagName, and I thought that this was going to solve the issue. And it kiiiind off works, if I click on the pictures in the outer container it gets all four images but it links to an offset element.
Here is what I did: http://codepen.io/gabyferman/pen/QjzovY
I don't know much Javascript, and I think I'm lost. I suppose that it offsets the images 'cause is creating the gallery from an array of child elements, and when it finds 4, instead of linking 1a -> 1b, 2a -> 2b, 3a -> 3b, 4a -> 4b, (being 3 and 4 the ones in a outer container) it links 3a -> 1b, 4a -> 2b, etc.
Is there away to change this offset?
Hi everyone, Same problem here, I have table with text and images, and all images in cells are in separate "my-gallery" class and I wish they would all open up as continues gallery. The best way would be to make .my gallery class work for mixed content like that:
<div class="my-gallery">
<figure itemprop="associatedMedia" itemscope="itemscope" itemtype="http://schema.org/ImageObject">
<a href="/img/myimg.jpg" itemprop="contentUrl" data-size="1280x835" data-index="0">
<img src="/img/myimg.jpg" alt="">
</a>
</figure>
<p>Some content here</p>
<figure itemprop="associatedMedia" itemscope="itemscope" itemtype="http://schema.org/ImageObject">
<a href="/img/myimg.jpg" itemprop="contentUrl" data-size="1280x835" data-index="1">
<img src="/img/myimg.jpg" alt="">
</a>
</figure>
<p>And some content here for example</p>
</div>
But alas - my javascript skill is too poor to pull this one off. I wish we could have this as official codepen example.
Maybe this could help you. I've managed to do something similar, but pretty specific to my case. As far as i can see, it works well. https://github.com/akizor/PhotoSwipe-Gallery-Improvement
Like @Akizor I modified the parseThumbnailElements to suites my specific needs. I have each image inside a <div>
block.
In routine parseThumbnailElement, after checking parameter "el" to get the element clicked to be able to set the options index, I completely ignore parameter "el" that has been passed by routine openPhotoSwipe triggering parseThumbnailElements. I overwrite variable "el" by querying the DOM.
To look up the modifications in the attached search for : extension to photoswipe. There are only a few.
Note I am new to javascript. The modifications only suite my needs. There will be a lot of guys and galls out there the can modify photoswipe in a more general way.
Best responsive image plugin for sure!
Basically, I started by trying out this plugin with the default example and ended up using a table to align everything.
Javascript code assumes that each figure element is directly inside a container div.
Wasnt that hard to fix the code.
Here is what I did:
Assign the same class to all figure elements so that we can easily find them:
<figure class="find-them-all" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
Manually assign an index to each image by setting the data-index attribute:
<a href="/image/<?=$anImage->image?>" itemprop="contentUrl" data-size="<?=$size[0].'x'.$size[1]?>" data-index="<?=$count?>">
Small modifications to the JavaScript code to make it happens:
var parseThumbnailElements = function(el) { var thumbElements = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
var clickedGallery = document.querySelectorAll('.my-gallery')[0], childNodes = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
I hope that helps somebody :)
@frederickpelchat Is working, but only if I click in the first image. Don't recognize the click in a different image. Do you know what is the problem?
This is my pug `
.my-gallery(itemscope='', itemtype='http://schema.org/ImageGallery')
.my-gallery__left
.my-gallery__left-01
.my-gallery__left-01-left
figure.find-them-all(itemprop='associatedMedia', itemscope='', itemtype='http://schema.org/ImageObject')
a(href='https://farm3.staticflickr.com/2567/5697107145_a4c2eaa0cd_o.jpg', itemprop='contentUrl', data-size='1024x1024' data-index="1")
img.my-gallery__img.left-01(src='https://farm3.staticflickr.com/2567/5697107145_3c27ff3cd1_m.jpg', itemprop='thumbnail', alt='Image description')
figcaption(itemprop='caption description') Image caption 1
.my-gallery__info
p.my-gallery__title
p.my-gallery__description
.my-gallery__left-01-right
figure.find-them-all(itemprop='associatedMedia', itemscope='', itemtype='http://schema.org/ImageObject')
a(href='https://farm2.staticflickr.com/1043/5186867718_06b2e9e551_b.jpg', itemprop='contentUrl', data-size='964x1024' data-index="2")
img.my-gallery__img.left-01(src='https://farm2.staticflickr.com/1043/5186867718_06b2e9e551_m.jpg', itemprop='thumbnail', alt='Image description')
figcaption(itemprop='caption description') Image caption 2
.my-gallery__left-02
.my-gallery__left-02-left
figure.find-them-all.my-gallery__figure--height(itemprop='associatedMedia', itemscope='', itemtype='http://schema.org/ImageObject')
a(href='https://farm7.staticflickr.com/6175/6176698785_7dee72237e_b.jpg', itemprop='contentUrl', data-size='1024x683' data-index="3")
img.my-gallery__img.my-gallery__img--height(src='https://farm7.staticflickr.com/6175/6176698785_7dee72237e_m.jpg', itemprop='thumbnail', alt='Image description')
figcaption(itemprop='caption description') Image caption 3
.my-gallery__left-02-right
figure.find-them-all(itemprop='associatedMedia', itemscope='', itemtype='http://schema.org/ImageObject')
a(href='https://farm6.staticflickr.com/5023/5578283926_822e5e5791_b.jpg', itemprop='contentUrl', data-size='1024x768' data-index="4")
img.my-gallery__img(src='https://farm6.staticflickr.com/5023/5578283926_822e5e5791_m.jpg', itemprop='thumbnail', alt='Image description')
figcaption(itemprop='caption description') Image caption 4
figure.find-them-all(itemprop='associatedMedia', itemscope='', itemtype='http://schema.org/ImageObject')
a(href='https://farm2.staticflickr.com/1043/5186867718_06b2e9e551_b.jpg', itemprop='contentUrl', data-size='964x1024' data-index="5")
img.my-gallery__img(src='https://farm2.staticflickr.com/1043/5186867718_06b2e9e551_m.jpg', itemprop='thumbnail', alt='Image description')
figcaption(itemprop='caption description') Image caption 5
.my-gallery__right
figure.find-them-all(itemprop='associatedMedia', itemscope='', itemtype='http://schema.org/ImageObject')
a(href='https://farm7.staticflickr.com/6175/6176698785_7dee72237e_b.jpg', itemprop='contentUrl', data-size='1024x683' data-index="6")
img.my-gallery__img.right-01-top(src='https://farm7.staticflickr.com/6175/6176698785_7dee72237e_m.jpg', itemprop='thumbnail', alt='Image description')
figcaption(itemprop='caption description') Image caption 6
figure.find-them-all(itemprop='associatedMedia', itemscope='', itemtype='http://schema.org/ImageObject')
a(href='https://farm6.staticflickr.com/5023/5578283926_822e5e5791_b.jpg', itemprop='contentUrl', data-size='1024x768' data-index="6")
img.my-gallery__img.right-01-bottom(src='https://farm6.staticflickr.com/5023/5578283926_822e5e5791_m.jpg', itemprop='thumbnail', alt='Image description')
figcaption(itemprop='caption description') Image caption 7
`
My JS (except for your code, is the same as the demo `var initPhotoSwipeFromDOM = function (gallerySelector) {
// parse slide data (url, title, size ...) from DOM elements
// (children of gallerySelector)
var parseThumbnailElements = function (el) {
var thumbElements = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
numNodes = thumbElements.length,
items = [],
figureEl,
linkEl,
size,
item;
for (var i = 0; i < numNodes; i++) {
figureEl = thumbElements[i]; // <figure> element
// include only element nodes
if (figureEl.nodeType !== 1) {
continue;
}
linkEl = figureEl.children[0]; // <a> element
size = linkEl.getAttribute('data-size').split('x');
// create slide object
item = {
src: linkEl.getAttribute('href'),
w: parseInt(size[0], 10),
h: parseInt(size[1], 10),
};
if (figureEl.children.length > 1) {
// <figcaption> content
item.title = figureEl.children[1].innerHTML;
}
if (linkEl.children.length > 0) {
// <img> thumbnail element, retrieving thumbnail url
item.msrc = linkEl.children[0].getAttribute('src');
}
item.el = figureEl; // save link to element for getThumbBoundsFn
items.push(item);
}
return items;
};
// find nearest parent element
var closest = function closest(el, fn) {
return el && (fn(el) ? el : closest(el.parentNode, fn));
};
// triggers when user clicks on thumbnail
var onThumbnailsClick = function (e) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var eTarget = e.target || e.srcElement;
// find root element of slide
var clickedListItem = closest(eTarget, function (el) {
return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
});
if (!clickedListItem) {
return;
}
// find index of clicked item by looping through all child nodes
// alternatively, you may define index via data- attribute
var clickedGallery = document.querySelectorAll('.my-gallery')[0], childNodes = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
childNodes = clickedListItem.parentNode.childNodes,
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (var i = 0; i < numChildNodes; i++) {
if (childNodes[i].nodeType !== 1) {
continue;
}
if (childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
if (index >= 0) {
// open PhotoSwipe if valid index found
openPhotoSwipe(index, clickedGallery);
}
return false;
};
// parse picture index and gallery index from URL (#&pid=1&gid=2)
var photoswipeParseHash = function () {
var hash = window.location.hash.substring(1),
params = {};
if (hash.length < 5) {
return params;
}
var vars = hash.split('&');
for (var i = 0; i < vars.length; i++) {
if (!vars[i]) {
continue;
}
var pair = vars[i].split('=');
if (pair.length < 2) {
continue;
}
params[pair[0]] = pair[1];
}
if (params.gid) {
params.gid = parseInt(params.gid, 10);
}
return params;
};
var openPhotoSwipe = function (index, galleryElement, disableAnimation, fromURL) {
var pswpElement = document.querySelectorAll('.pswp')[0],
gallery,
options,
items;
items = parseThumbnailElements(galleryElement);
// define options (if needed)
options = {
// define gallery index (for URL)
galleryUID: galleryElement.getAttribute('data-pswp-uid'),
getThumbBoundsFn: function (index) {
// See Options -> getThumbBoundsFn section of documentation for more info
var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return { x: rect.left, y: rect.top + pageYScroll, w: rect.width };
},
};
// PhotoSwipe opened from URL
if (fromURL) {
if (options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for (var j = 0; j < items.length; j++) {
if (items[j].pid == index) {
options.index = j;
break;
}
}
} else {
// in URL indexes start from 1
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if (isNaN(options.index)) {
return;
}
if (disableAnimation) {
options.showAnimationDuration = 0;
}
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
};
// loop through all gallery elements and bind events
var galleryElements = document.querySelectorAll(gallerySelector);
for (var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute('data-pswp-uid', i + 1);
galleryElements[i].onclick = onThumbnailsClick;
}
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = photoswipeParseHash();
if (hashData.pid && hashData.gid) {
openPhotoSwipe(hashData.pid, galleryElements[hashData.gid - 1], true, true);
}
};
// execute above function initPhotoSwipeFromDOM('.my-gallery');`
@frederickpelchat Worked a perfectly, thanks for sharing
Daniel Placinta Thank you to you enormous, with your code I succeeded to carry out plan.
@frederickpelchat Worked perfectly, thanks for that!
Tried solution above, and when I refresh page with slide open I get the following error:
Uncaught TypeError: Cannot read property 'firstChild' of undefined at Object.getChildByClass (photoswipe.min.js:4) at a.init (photoswipe.min.js:4) at openPhotoSwipe (index.html:697) at initPhotoSwipeFromDOM (index.html:728) at index.html:733
My Function:
` var initPhotoSwipeFromDOM = function(gallerySelector) {
// parse slide data (url, title, size ...) from DOM elements
// (children of gallerySelector)
var parseThumbnailElements = function(el) {
var thumbElements = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
numNodes = thumbElements.length,
items = [],
figureEl,
linkEl,
size,
item;
for(var i = 0; i < numNodes; i++) {
figureEl = thumbElements[i]; // <figure> element
// include only element nodes
if(figureEl.nodeType !== 1) {
continue;
}
linkEl = figureEl.children[0]; // <a> element
size = linkEl.getAttribute('data-size').split('x');
// create slide object
item = {
src: linkEl.getAttribute('href'),
w: parseInt(size[0], 10),
h: parseInt(size[1], 10)
};
if(figureEl.children.length > 1) {
// <figcaption> content
item.title = figureEl.children[1].innerHTML;
}
if(linkEl.children.length > 0) {
// <img> thumbnail element, retrieving thumbnail url
item.msrc = linkEl.children[0].getAttribute('src');
}
item.el = figureEl; // save link to element for getThumbBoundsFn
items.push(item);
}
return items;
};
// find nearest parent element
var closest = function closest(el, fn) {
return el && ( fn(el) ? el : closest(el.parentNode, fn) );
};
// triggers when user clicks on thumbnail
var onThumbnailsClick = function(e) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var eTarget = e.target || e.srcElement;
// find root element of slide
var clickedListItem = closest(eTarget, function(el) {
return (el.tagName && el.tagName.toUpperCase() === 'FIGURE');
});
if(!clickedListItem) {
return;
}
// find index of clicked item by looping through all child nodes
// alternatively, you may define index via data- attribute
var clickedGallery = document.querySelectorAll('.my-gallery')[0], childNodes = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (var i = 0; i < numChildNodes; i++) {
if(childNodes[i].nodeType !== 1) {
continue;
}
if(childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
if(index >= 0) {
// open PhotoSwipe if valid index found
openPhotoSwipe( index, clickedGallery );
}
return false;
};
// parse picture index and gallery index from URL (#&pid=1&gid=2)
var photoswipeParseHash = function() {
var hash = window.location.hash.substring(1),
params = {};
if(hash.length < 5) {
return params;
}
var vars = hash.split('&');
for (var i = 0; i < vars.length; i++) {
if(!vars[i]) {
continue;
}
var pair = vars[i].split('=');
if(pair.length < 2) {
continue;
}
params[pair[0]] = pair[1];
}
if(params.gid) {
params.gid = parseInt(params.gid, 10);
}
return params;
};
var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
var pswpElement = document.querySelectorAll('.pswp')[0],
gallery,
options,
items;
items = parseThumbnailElements(galleryElement);
// define options (if needed)
options = {
// define gallery index (for URL)
galleryUID: galleryElement.getAttribute('data-pswp-uid'),
getThumbBoundsFn: function(index) {
// See Options -> getThumbBoundsFn section of documentation for more info
var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return {x:rect.left, y:rect.top + pageYScroll, w:rect.width};
}
};
// PhotoSwipe opened from URL
if(fromURL) {
if(options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for(var j = 0; j < items.length; j++) {
if(items[j].pid == index) {
options.index = j;
break;
}
}
} else {
// in URL indexes start from 1
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if( isNaN(options.index) ) {
return;
}
if(disableAnimation) {
options.showAnimationDuration = 0;
}
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
};
// loop through all gallery elements and bind events
var galleryElements = document.querySelectorAll( gallerySelector );
for(var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute('data-pswp-uid', i+1);
galleryElements[i].onclick = onThumbnailsClick;
}
// Parse URL and open gallery if it contains #&pid=3&gid=1
var hashData = photoswipeParseHash();
if(hashData.pid && hashData.gid) {
openPhotoSwipe( hashData.pid , galleryElements[ hashData.gid - 1 ], true, true );
}
};
// execute above function
initPhotoSwipeFromDOM('.my-gallery');`
@vishy93 I've put the JS and HTML code I used in a JSFiddle here to prevent a huge comment on this thread. Note how the figures are in separate div tags.
Hope this helps and the credit goes to @frederickpelchat for their answer.
@tombannister94 Sorry, I managed to fix it earlier. Just delayed initiation of the Lightbox until after document was ready. Btw, your jsfiddle gives a 404 pal. 👍
@vishy93 Nice fix! Yeah, I didn't add the required Photoswipe HTML; it was purely to paste my JS for you to see rather than creating a large comment here. Thank you though, and it's great you've fixed the issue. 👍
A little late for the party, but I wrote a small utility wrapper for photoswipe called Photoswippy which can handle this specific case. Look for the indexSelector
here :smile:
@kaisermann shall look over it shortly.
@vishy93 I've put the JS and HTML code I used in a JSFiddle here to prevent a huge comment on this thread. Note how the figures are in separate div tags.
Hope this helps and the credit goes to @frederickpelchat for their answer.
it worked for my issue: #1620
Best responsive image plugin for sure!
Basically, I started by trying out this plugin with the default example and ended up using a table to align everything.
Javascript code assumes that each figure element is directly inside a container div.
Wasnt that hard to fix the code.
Here is what I did:
Assign the same class to all figure elements so that we can easily find them:
<figure class="find-them-all" itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
Manually assign an index to each image by setting the data-index attribute:
<a href="/image/<?=$anImage->image?>" itemprop="contentUrl" data-size="<?=$size[0].'x'.$size[1]?>" data-index="<?=$count?>">
Small modifications to the JavaScript code to make it happens:
var parseThumbnailElements = function(el) { var thumbElements = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
var clickedGallery = document.querySelectorAll('.my-gallery')[0], childNodes = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')),
I hope that helps somebody :)
really appreciate that it really works thanks im digging it all day
@shevchenko21 thanks for the answer. I tried your solution but i keep getting error for the code inserts for the variables:
var parseThumbnailElements
var clickedGallery
if you still have the code somewhere, could you show me how you defined the whole variables? the way i defined was following:
var parseThumbnailElements = function (el) { var thumbElements = Array.prototype.slice.call(document.querySelectorAll('.find-them-all')), el.childNodes, numNodes = thumbElements.length, items = [], el, childElements, thumbnailEl, size, item;
and
var clickedGallery = clickedListItem.parentNode, document.querySelectorAll('.my-gallery')[0], childNodes = Array.prototype.slice.call(document.querySelectorAll('.find-them-all'));
The error I get is: ',' expected.javascript
If you have the whole JavaScript code, even better if you could share it.
Thanks!
Hi there,
I think it's not useful to tell you that your plugin is completely... outstanding :smiley:
I would like to know if I can use a gallery, I have used the js code provided in your doc, but my pictures are not in the same div, the code looks like :
Currently with this code, the pictures are well opened with the plugin but the navigation between them are not available.
In the waiting of your answer,
Keep up your awesome work man!