Fancybox - apply a function to several elements

2019-08-31 02:11发布

问题:

This source code below was posted by Cristiano G. Carvalho in answer to the question: calling fancybox gallery with other link made by another user.

<div class="details_gallery">
 <a href="#" class="manualfancybox">Manual Call Fancybox</a>
 <div class="details_gallery_min">
  <a rel="details" href="max/1.jpg" class="fancybox"><img src="min/1.jpg" alt="" /></a>
  <a rel="details" href="max/2.jpg" class="fancybox"><img src="min/2.jpg" alt="" /></a>
  <a rel="details" href="max/3.jpg" class="fancybox"><img src="min/3.jpg" alt="" /></a>
  <a rel="details" href="max/4.jpg" class="fancybox"><img src="min/4.jpg" alt="" /></a>
 </div>
</div>

<script>

$(document).ready(function(){
    $(".manualfancybox").click(function() {
        var photos  = new Array();

        $(".details_gallery_min a").each(function(){

            href = $(this).attr("href"); 
            title = $(this).attr("title"); 
            photos.push({'href': href, 'title': title})         

        });

        jQuery.fancybox(photos , 
            {   'transitionIn' : 'elastic', 
                'easingIn' : 'easeOutBack', 
                'transitionOut' : 'elastic', 
                'easingOut' : 'easeInBack', 
                'opacity' : false, 
                'titleShow' : true, 
                'titlePosition' : 'over',
                'type'              : 'image',          
                'titleFromAlt' : true 
            }
        );
    });
});

</script>

And it DOES work... if you have ONLY ONE gallery (.details_gallery_min in the example).

I've tried to change

$(".details_gallery_min a").each(function(){

to

$(".galleryone a, .gallerytwo a").each(function(){

but it only works for ".galleryone a", when I click on the link that calls "gallerytwo" it opens "galleryone". My HTML code is correct.

My question is:

What if I have multiple links opening different galleries and I want to use the same behaviors (transition, easing, etc.) to all galleries?

回答1:

Well, while Cristiano G. Carvalho's answer works, I think it is overdoing things. The array() + the .each() method will have a(n) (arguable) high cost in terms of memory and performance, much more if you have several images in your galleries.

I don't see any reason to iterate through every element and build the fancybox gallery (again) inside an array if a simple fancybox code and manual event handlers can tackle the issue. But that is entirely my personal opinion.

So for instance, if you have an html like this :

<h3>gallery one</h3>
<div id="gallery_one">
    <a rel="galleryone" class="fancybox" href="http://fancyapps.com/fancybox/demo/1_b.jpg"><img src="http://fancyapps.com/fancybox/demo/1_s.jpg" alt=""/></a>
    <a rel="galleryone" class="fancybox" href="http://fancyapps.com/fancybox/demo/2_b.jpg"><img src="http://fancyapps.com/fancybox/demo/2_s.jpg" alt=""/></a>
... etc.
</div>

<h3>gallery two</h3>
<div id="gallery_two">
    <a rel="gallerytwo" class="fancybox" href="http://fancyapps.com/fancybox/demo/3_b.jpg"><img src="http://fancyapps.com/fancybox/demo/3_s.jpg" alt=""/></a>
    <a rel="gallerytwo" class="fancybox" href="http://fancyapps.com/fancybox/demo/4_b.jpg"><img src="http://fancyapps.com/fancybox/demo/4_s.jpg" alt=""/></a>
...etc.
</div>

Rewriting my own answer to the same question, I would set any manual links I need like :

<a class="manualfancybox" data-gallery="gallery_one" href="#nogo">manual call to first gallery</a>
<a class="manualfancybox" data-gallery="gallery_two" href="#nogo">manual call to second gallery</a>

Notice that I added an HTML5 data-gallery attribute that indicates what gallery the link is targeting to (the data-gallery value matches the ID of the parent container of each gallery)

Then, add the fancybox code for all galleries

$(".fancybox").fancybox({
    // API options here
});

and bind the event handler to the manual fancybox calls like :

$(".manualfancybox").on("click", function(){
    var gallery = "#" + $(this).data("gallery");
    $(gallery).find(".fancybox").eq(0).click();
    return false;
});

Set the value of .eq() depending on what image the gallery should start from.

See JSFIDDLE

NOTE : .on() requires jQuery v1.7+