fancybox 2: put thumbnails within a parent div

2019-04-10 21:57发布

问题:

Ok so I've recently added 'fancyBox' to my site and its great. However I want to place the tumbnails (whose functionality is part of the thumbnails helper, thus in a separate .js file) just under the gallery images.

I first tried to change the divs containing the images (and I assumed thumbnails) however the two are sibling divs with no parent div other than body. I then set about trying to figure out what is actually 'printing' the elements onto the page and I've found a whole bunch of uses of 'wrap'.

For Example:

tpl: {
            wrap     : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
            image    : '<img class="fancybox-image" src="{href}" alt="" />',
            iframe   : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',
            error    : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
            closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
            next     : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
            prev     : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
        },

So first off; whats the tpl : {},? What is that? Is it an array? A function? I can't find any documentation talking about something that fits that syntax, which just span me right out.

Secondly I assume that's not the lines where the actual html is being 'printed', just the area that's defining what should be printed and the values within it are called when the html is actually printed. ...? So wouldn't that mean that I could print this (from the thumbnail js file):

this.wrap = $('<div id="fancybox-thumbs"></div>').addClass(opts.position).appendTo('body');
        this.list = $('<ul>' + list + '</ul>').appendTo(this.wrap);

on the line where the actual html for the images is printed? Bearing in mind they're part of two separate files.

Basically all I need is to have a parent div for both the gallery and the thumbnails. This way I can position the thumbnails according to the size of the gallery. I'm using drupal as well, so pretty much any hard coding of html documents is out, unless its a template obviously.

I tried to figure this out on my onesie however due to my lack of experience and the fact that the main file is 2020 lines long, its highly unlikely I'll be successful. Rather I'll find myself repetitively hitting walls I don't have a clue about, then proceed to lose my mind.

回答1:

There are not too much documentation about the tpl API option so I will share with you my findings.


1). whats the tpl : {},? : tpl stands for template, and it's a collection of data entries (json name/value pair format) that returns metadata inside the fancybox function.

obj : {
    property-name: value // Boolean (true/false), integer (50, 260.3) or string ("string" ... note the quotes)
}

You can use tpl to add your own selectors to fancybox if you want to add different css styles like :

$(".fancybox").fancybox({
    tpl: {
        wrap: '<div class="fancybox-wrap mywrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'
    },
});

Notice I added the class mywrap so you can use its selector to add custom css styles (or manipulate it through jQuery) like :

/* add a 5px red border around fancybox */
.mywrap {
    border: solid 5px #880000 !important;
}

See JSFIDDLE


2). Basically all I need is to have a parent div for both the gallery and the thumbnails. This has to be seen from different angles.

When you open fancybox two main containers are added (by selector) :

2.a). .fancybox-overlay

  • it's the semi-transparent overlay on top of your page AND behind fancybox
  • it's always appended to the body

2.b). .fancybox-wrap

  • it's the fancybox box with all its children (navigation and close buttons, content, etc.)
  • it's appended to .fancybox-overlay IF the locked option is set to true (default value) like :

    $(".fancybox").fancybox({
        helpers : {
            overlay: {
                locked: true
            }
        }
    });
    
  • OR it's appended to body IF the locked option is set to false :

    $(".fancybox").fancybox({
        helpers : {
            overlay: {
                locked: false
            }
        }
    });
    

    NOTE: .fancybox-wrap will be a sibling of .fancybox-overlay in this case.

  • it's appended to any designated custom container when using the option parent AND the locked option is set to false

    so having this html:

    <body>
        <div id="mainWrapper"></div>
    </body>
    

    ... and

    $(".fancybox").fancybox({
        parent: "#mainWrapper", // parent div
        helpers : {
            overlay: {
                locked: false
            }
        }
    });
    

    ....fancybox-wrap will be appended as a child element of #mainWrapper so you can apply your own custom css styles like :

    #mainWrapper .fancybox-wrap {
        left: 0 !important;
    }
    

    See JSFIDDLE


3). When you use the thumbnails helper (and linked the proper js and css files), another container is added by fancybox :

3.a). #fancybox-thumbs

  • it's always appended to the body
  • it's a sibling of the .fancybox-overlay element

If you require a parent div for the #fancybox-thumbs container, you could wrap #fancybox-thumbs with its new custom parent div on the fly using a fancybox callback like :

$(".fancybox").fancybox({
    helpers: {
        thumbs: {}
    },
    afterShow: function () {
        if ($(".mythumbswrap").length == 0) {
            setTimeout(function () {
                $("body").find("#fancybox-thumbs").css({
                    // custom css (optional)
                    position: "relative"
                }).wrap("<div class='mythumbswrap' />");
            }, 100);
        }
    },
    afterClose: function () {
        $(".mythumbswrap").remove();
    }
});

Notice that we first checked if .mythumbswrap already existed, which can be true if I am browsing a gallery. If not, we'll add it BUT we will need to wait for #fancybox-thumbs to be appended to the body since it doesn't happen until fancybox is completely added to the DOM.

We used setTimeout to set the delay.

Also notice that we removed the parent container .mythumbswrap after closing fancybox, otherwise it will remain in the DOM and not added as a wrapper of #fancybox-thumbs next time we open fancybox.

Since now .mythumbswrap is the parent element of #fancybox-thumbs we can apply any custom styles like :

.mythumbswrap {
  background: none repeat scroll 0 0 #FFFFFF !important;
  bottom: 0;
  display: block;
  height: 60px;
  width: 100%;
  z-index: 10000;
  position: fixed;
  bottom: 0;
}

See JSFIDDLE