0

With fancyBox 2, how do I avoid duplication of thumbnail helper images in a gallery on a page containing multiple links to multiple different images in that gallery?

Live example: http://publications.iodp.org/proceedings/349/101/349_101.html

See section "Introduction", first sentence, "Figures F1, F2" for sample links.

Assets: jQuery 1.8.3, Twitter Bootstrap 2.2.2, fancyBox 2.1.5

Sample link code:

<a class="fancybox-xtitle Link" rel="fancybox-xtitle" data-title-id="F1title" href="figures/01_F01.png">F1,</a> <a class="fancybox-xtitle Link" rel="fancybox-xtitle" data-title-id="F2title" href="figures/01_F02.png">F2</a>

Sample JavaScript:

$(".fancybox-xtitle")
.attr('rel', 'gallery')
.fancybox({
    openEffect : 'none',
    closeEffect : 'none',
    prevEffect : 'none',
    nextEffect : 'none',
    closeBtn : false,
    arrows : false,
    padding : [15, 15, 55, 15],
    minWidth : 300,
    maxWidth : 1200,
    helpers : {
        thumbs : {
            width : 50,
            height : 50
        },
        title : {
            type : 'inside',
            position : 'top'
        },
        buttons : {},
    },
    beforeLoad: function() {
        var el, id = $(this.element).data('title-id');
        if (id) {
            el = $('#' + id);            
            if (el.length) {
                this.title = el.html();
            }
        }
    }
});

I haven't seen this specific question answered anywhere, and I'm hoping the answer will be useful to anyone who wants to use fancyBox to create a gallery with multiple callouts on a page. I also checked the list of "Questions that may already have your answer" when authoring this question, and found no answer. Articles I have searched for solutions over the past three weeks: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16

Background information:

The page may have from 1 to 500+ figures (images plus captions).

There are three ways in which figures are referenced on the page:

  1. From text (e.g. "F1. First figure caption.") In the list of figures in the fixed navigation to the right—each figure is referenced once, rel="navfigures"; no thumbnail helper duplication problem.

  2. From an image in a grey box () in the text following the first mention of a figure in text—again each figure is referenced once, rel="thumb"; no thumbnail helper duplication problem.

  3. From text (e.g. "F1", "F14", etc.) in the text on the page, which may contain one or more links to any one of these images (e.g. Figure F1 may be called out in text from 1 to x times); thumbnail helper creates thumbnail for every referenced figure in the order they are called out.

The first two ways do not involve multiple references to any one figure and therefore do not cause duplication of thumbnails. The third way, however, does involve multiple references and therefore causes duplication. For example, a page containing text that calls out Figures F1, F2, F3, F3, F3, F1, F4, will result in a gallery where the thumbnail helper displays F1, F2, F3, F3, F3, F1, F4, instead of just F1, F2, F3, F4.

The figure captions are pulled from a hidden div containing the caption in HTML using a beforeLoad callback (per fancyBox documentation, Tips & Tricks, 2. Title - Use element instead of attribute).

Using the rel attribute to define a gallery works great as long as there is only one link to each image, as with the thumbnail figure images in text, and the list of figures in the side navigation. Using the rel attribute on links to figures in the main body of text results in extreme duplication of thumbnails.

Please note the following when answering: I have experience with HTML and CSS but not much with JavaScript and virtually none with jQuery; I am self-training as fast as possible.

Community
  • 1
  • 1
Patrick
  • 1
  • 3

2 Answers2

1

I've been having a look into this and I'm not sure there is any configuration based solution, but a programmatic approach I've found to work is to for each relevant click completely reapply the fancybox() function, after first looping through all the links, keeping a dictionary of each href and setting rel="gallery" only for the unique urls, making sure that the clicked item is one of them by adding it first.

$('.fancybox').click(function(e) {
    var uniques = {};    
    $(this).attr('rel', 'gallery');
    uniques[$(this).attr('href')] = true;
    $('.fancybox').not(this).each(function() {
        href = $(this).attr('href');
        if(!uniques[href]) {
            $(this).attr('rel', 'gallery');
            uniques[href] = true;
        } else {
            $(this).attr('rel', '');
        }
    });

    $('.fancybox').fancybox({
        helpers : {
            thumbs : {
                width : 50,
                height : 50
            }
        }
    });
});

Hope that helps. See https://jsfiddle.net/gL6578m3/ for a demo.

stovroz
  • 6,835
  • 2
  • 48
  • 59
  • Man, @stovroz, you just saved tons of my time. Your code didn't work for me but made me understand my problem and solve it. Thank you. – nrvnm Sep 05 '15 at 05:29
0

Here's more elegant solution that worked for me perfectly:

Initially I had many project blocks like below with images having different rel attributes in each block (gallery1, gallery2, etc) so that each block had its own gallery. But in reality all images were mixed or duplicated... May be because I also had hidden section for mobile version which contained all of these blocks too. All attempts to hide, delete, rearrange or anything else were useless. Thumbnails were duplicating and mixing anyway..

HTML structure:

<div class="project">
    <div class="img_container">
        <a href="img/a/01.jpg" class="fancybox-thumb" rel="gallery1">
            <img src="img/a/01.jpg"/>
        </a>
        <a href="img/a/02.jpg" class="fancybox-thumb" rel="gallery1">
            <img src="img/a/02.jpg"/>
        </a>
        <a href="img/a/03.jpg" class="fancybox-thumb" rel="gallery1">
            <img src="img/a/03.jpg"/>
        </a>
    </div>
</div>

<div class="project">
    <div class="img_container">
        <a href="img/b/01.jpg" class="fancybox-thumb" rel="gallery2">
            <img src="img/b/01.jpg"/>
        </a>
        <a href="img/b/02.jpg" class="fancybox-thumb" rel="gallery2">
            <img src="img/b/02.jpg"/>
        </a>
        <a href="img/b/03.jpg" class="fancybox-thumb" rel="gallery2">
            <img src="img/b/03.jpg"/>
        </a>
    </div>
</div>

Only 2 blocks here, imagine to have more than 15, like I did.

Here's the jQuery solution:

    var fan = $('.fancybox-thumb'); //caching
    fan.click(function() {
        fan.attr('rel', ''); //clear rel attribute of all images
        $(this).parents().children().attr('rel', 'gallery'); //set rel to current group of images

        fan.fancybox({
            //all those settings
            helpers : {
                thumbs  : {
                    width   : 195,
                    height  : 131
                }
            }
        });

    });

So, after all you can make rel='' for every image, it doesn't matter anymore. Grab all images with .fancybox class, clear rel attribute and add it to images you need.

PS: May be it has something to do with those 01.jpg file names that were the same for every project. I don't know.

Hope this is helpful.

nrvnm
  • 171
  • 2
  • 13