2

Fancybox 2.

I would like to add all "Button helper" buttons to the title. So that the title was aligned to the left edge and the buttons to the right edge.

Please, can anyone tell me, how can I do it?

jquery.fancybox.css:

    /*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */
.fancybox-wrap,
.fancybox-skin,
.fancybox-outer,
.fancybox-inner,
.fancybox-image,
.fancybox-tmp
{
    padding: 0;
    margin: 0;
    border: 0;
    outline: none;
    vertical-align: top;
}

.fancybox-wrap {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 8020;
}

.fancybox-skin {
        bottom: 15px;
    position: relative;
    background: DarkGreen;
    color: #444;
    text-shadow: none;
}

.fancybox-opened {
    z-index: 8030;
}

.fancybox-outer, .fancybox-inner {
    position: relative;
}

.fancybox-inner {
    overflow: hidden;
}

.fancybox-image, .fancybox-iframe {
    display: block;
    width: 100%;
    height: 100%;
}

.fancybox-image {
    max-width: 100%;
    max-height: 100%;
}

.fancybox-tmp {
    position: absolute;
    top: -99999px;
    left: -99999px;
    visibility: hidden;
    max-width: 99999px;
    max-height: 99999px;
    overflow: visible !important;
}

.fancybox-overlay {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    z-index: 8010;
}

.fancybox-title {
    visibility: hidden;
    font: 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;
    position: relative;
    text-shadow: none;
    z-index: 8050;
}

.fancybox-opened .fancybox-title {
    visibility: visible;
}

.fancybox-title-inside-wrap {
        position: relative;
    padding-bottom: 5px;
    font-weight: bold;
    color: white;
    text-align: left;
}

jquery.fancybox-buttons.css:

#fancybox-buttons {
        display: none;
    position: fixed;
    right: 10px;
    width: 100%;
    z-index: 8050;
}

#fancybox-buttons ul {
    display: block;
    width: 133px;
    height: 25px;
    margin: 0 auto;
    padding-right: 5px;
    list-style: none;
}

#fancybox-buttons ul li {
    float: left;
    margin: 0;
    padding: 0;
}

#fancybox-buttons a {
    display: block;
    width: 27px;
    height: 25px;
    text-indent: -9999px;
    background-color: DarkGreen;  
    background-image: url('http://2.bp.blogspot.com/-5CNF6M2iOPM/UfVFckJ9jiI/AAAAAAAABjY/WT53trk2XUE/s1600/fancybox_buttons.png');
    background-repeat: no-repeat;
    outline: none;
}

#fancybox-buttons a:hover {
    background-image: url('http://4.bp.blogspot.com/-M6nS5WXq-lI/UfVFcvlh7MI/AAAAAAAABjU/fMbwIP_esaQ/s1600/fancybox_buttons2.png');
    background-color: ForestGreen;  
}

#fancybox-buttons a.btnPrev {
    background-position: -1px -3px;
}

#fancybox-buttons a.btnNext {
    background-position: -31px -3px;
}

#fancybox-buttons a.btnPlay {
    background-position: -1px -33px;
}

#fancybox-buttons a.btnPlayOn {
    background-position: -31px -33px;
}

#fancybox-buttons a.btnToggle {
    background-position: -1px -63px;
}

#fancybox-buttons a.btnToggleOn {
    background-position: -31px -63px;
}

#fancybox-buttons a.btnClose {
    height: 25px;
    width: 25px;
        background-position: -63px -3px;
        background-color: DarkRed;
    background-image: url('http://4.bp.blogspot.com/-M6nS5WXq-lI/UfVFcvlh7MI/AAAAAAAABjU/fMbwIP_esaQ/s1600/fancybox_buttons2.png');
}

#fancybox-buttons a.btnClose:hover  {
    background-color: Red;
}

#fancybox-buttons a.btnDisabled {
        background-color: DarkGreen;
    background-image: url('http://2.bp.blogspot.com/-5CNF6M2iOPM/UfVFckJ9jiI/AAAAAAAABjY/WT53trk2XUE/s1600/fancybox_buttons.png');
       cursor: default;
}
Walter Stolz
  • 51
  • 1
  • 9

3 Answers3

4

This is one of the weirdest things I have done with fancybox, but just for fun.

First, if you want to add the buttons helper to the title, then you have to make sure that every link has the title attribute (some may not)... so you can start with this :

$(document).ready(function () {
    $(".fancybox").each(function () {
        // make sure every element has the tile attribute
        if (!$(this).attr("title")) {
            $(this).attr("title", " "); //no-break space
        }
    })
}); // ready

This will add an empty (no-break space) title to any link that doesn't have any.

On the other hand, moving the Buttons helper to the title may have some issues so the best option is to clone it and then append the clone to the title.

Let's set some CSS properties to the clone so it will be positioned where we want it inside the title :

/* hide the actual buttons helper */
#fancybox-buttons {
    display: none
}
/* position the clone : notice the class "clone" */
#fancybox-buttons.clone {
    position: absolute;
    top: 5px;
    right: 0;
}
/* also position the child ul */
#fancybox-buttons.clone ul {
    right: 0;
    margin: 0;
    position: absolute;
}

Then, we will use the afterShow callback in our fancybox custom script to :

  • clone the buttons helper
  • add the class clone to the cloned element
  • append it to the fancybox title
  • show it (fade it in)

NOTICE that we will set the title position inside to make the things workable. Also notice that since the buttons helper is added after the fancybox is loaded, we will need to wait for it before we can clone it; this is where setTimeout comes in handy :

$(document).ready(function () {
    $(".fancybox").each(function () {
        // make sure every element has the tile attribute
        if (!$(this).attr("title")) {
            $(this).attr("title", " "); //no-break space
        }
    }).fancybox({
        modal: true,
        helpers: {
            title: {
                type: 'inside'
            },
            buttons: {}
        },
        afterShow: function () {
            // wait for the buttons helper
            var buttons = setTimeout(function () {
                $("#fancybox-buttons")
                    .clone(true, true) // clone with data and events
                    .attr("class", "clone") // set class "clone" (and remove class "top")
                    .appendTo(".fancybox-title") // append it to the title
                    .fadeIn(); // show it nicely
            }, 100); //setTimeout
        } // afterShow
    }); // fancybox
}); // ready

See it working : JSFIDDLE

  • Use at your own risk ;)

EDIT :

In the previous demo, when any of the buttons is clicked, the icon doesn't change to the corresponding functionality as pointed out by the OP. We would need some extra callbacks to add the icon "toggling" functionality to our cloned buttons :

onPlayStart: function () {
    $("#fancybox-buttons.clone").find(".btnPlay").attr('title', 'Pause slideshow').addClass('btnPlayOn');
},
onPlayEnd: function () {
    $("#fancybox-buttons.clone").find(".btnPlay").attr('title', 'Start slideshow').removeClass('btnPlayOn');
},
onUpdate: function () {
    $("#fancybox-buttons.clone").find(".btnToggle").toggleClass('btnToggleOn');
}

See new forked JSFIDDLE

EDIT #2 :

To fix the onUpdate button toggling issue while scrolling (as per the OP's comment) when the overlay locked is set to false - overlay : {locked:false} - we have to replace this code :

onUpdate: function () {
    $("#fancybox-buttons.clone").find(".btnToggle").toggleClass('btnToggleOn');
}

by this :

onUpdate: function () {
    var toggle;
    toggle = $("#fancybox-buttons.clone").find(".btnToggle").removeClass('btnDisabled btnToggleOn');
    if (this.canShrink) {
       toggle.addClass('btnToggleOn');
    } else if (!this.canExpand) {
       toggle.addClass('btnDisabled');
    }
}

See new JSFIDDLE

JFK
  • 40,963
  • 31
  • 133
  • 306
  • Thanks for idea. I changed your script a little bit. My version : [http://jsfiddle.net/5QbeL/show/](http://jsfiddle.net/5QbeL/show/) But in your and in my script the "play/pause" button and "size toggle" button backgrounds (icons) don't change after I click any of them. 1) Try to pause the slideshow by pressing the pause button and the button will still show the pause button. 2) Try to expand or shrink the image by pressing the corresponding button and the button will not change its background (icon). – Walter Stolz Jul 27 '13 at 14:31
  • I would like to specify about "onUpdate" callback method function work. If the overlay locked parameter is not indicated (default value), then toggle size button do not changes the background (icon) at scrolling. It's good. If that parameter is set in false value, then toggle size button changes an icon at scrolling. Example: [http://jsfiddle.net/ajk89/show/](http://jsfiddle.net/ajk89/show/) How to disable this? – Walter Stolz Jul 27 '13 at 20:57
  • Thank you. Now everything works as necessary. If you are interested why I asked this question, then I would like to make viewing of photos in Windows style. I placed my finished version to the starting message of this topic. – Walter Stolz Jul 28 '13 at 17:17
0

A little late I know but I'm going to chime my own two cents worth here.

The assumption that one needs to tap into the button-helpers to implement custom buttons for declared functions is incorrect and causes more problems than is worth it... you don't even need the button-helpers activated.

The solution is to make use of functions already mapped to keys and to append said functions to your own buttons as required. My code for launching Fancybox 2.1.5 thus looks like this:

$(function() {  
    $('.fancybox').fancybox({
             scrolling      : 'yes',
             openEffect  : 'elastic',
             closeEffect : 'fade',
             openSpeed   : 600,
             closeSpeed   : 200,
             prevEffect : 'fade',
             nextEffect : 'fade',
             closeBtn  : true,
             arrows    : false,
             nextClick : false,
             helpers : {
              title : {
               type : 'inside'
              },
            //buttons : {},
              thumbs : {
               width : 75,
               height : 75
              }
             },
        afterShow: function() {
            expander = $('<a class="expander" title="Toggle size" href="javascript:;"></a>').appendTo('.fancybox-inner');
            toggle = $('.expander').on('click.fb', $.fancybox.toggle ).removeClass('hidden btnToggleOn');
            if (this.canShrink) {
                toggle.addClass('btnToggleOn');
            } else if (!this.canExpand) {
                toggle.addClass('hidden');
            }
            $('.fancybox-skin').swipe({
                  threshold : 40,

                  swipeLeft: function(event, direction) {
                        $.fancybox.next( direction );
                  },
                  swipeRight: function(event, direction) {
                        $.fancybox.prev( direction );
                  }
            });
        }

    });
}(jQuery));

Note that I've included the toggle variable states under 'afterShow' as opposed to 'onUpdate'.. this is a deliberate method as I found applying under afterLoad resulted in unwanted delays between the button loading and it actually becoming a live element.

EDIT I've since discovered housing the variable states for 'toggle' in afterShow creates issues in relation to the addition of classes on update. Have change the following below:

        afterShow: function() {
        /*twttr.widgets.load();*/
        expander = $('<a class="expander" title="Toggle size" href="javascript:;"></a>').appendTo('.fancybox-inner').on('click.fb', $.fancybox.toggle );
        $('.fancybox-skin')
            $('.fancybox-skin').swipe({
                threshold : 100,
                swipe:function(event, direction) {}
            });
            $('.fancybox-skin')
                .on('swipeLeft', function(){
                  $.fancybox.next();
                })
                .on('swipeRight', function(){
                  $.fancybox.prev();
            });
        },
    onUpdate: function() {
        var toggle;
        toggle = $('.expander').removeClass('hidden ToggleOn');
        if (this.canShrink) {
            toggle.addClass('ToggleOn');
        } else if (!this.canExpand) {
            toggle.addClass('hidden');
        }
    }
ElricE
  • 11
  • 2
  • I did my own version, different than JFK offered. I added buttons to title manually. But I am interested to see your version. Can you show JSFIDDLE working example? – Walter Stolz Aug 30 '13 at 04:48
0

My own version, without delays ans blinking.
Example: JSFIDDLE

JavaScript:

$(document).ready(function () {
  $(".fancybox").fancybox({
    openEffect: "elastic",
    openSpeed: 100,
    closeEffect: "elastic",
    closeSpeed: 100,
    prevEffect: "none",
    prevSpeed: 100,
    nextEffect: "none",
    nextSpeed: 100,
    minWidth: "130px",
    padding: 5,
    closeBtn: false,
    helpers: {
        title: {
            type: "inside",
            position: "top"
        },
        overlay: {
            locked: false
        }
    },
    afterLoad: function () {
        if (this.group.length > 1) {
            this.title = '<div id="fancybox-buttons"><ul><li><a class="btnPrev" onClick="javascript:$.fancybox.prev();"></a></li><li><a class="btnPlay" onClick="javascript:$.fancybox.play();"></a></li><li><a class="btnNext" onClick="javascript:$.fancybox.next();"></a></li><li><a class="btnToggle" onClick="javascript:$.fancybox.toggle();"></a></li><li><a class="btnClose" onClick="javascript:$.fancybox.close();"></a></li></ul></div> Рисунок ' + (this.index + 1) + " из " + this.group.length + (this.title ? " - " + this.title : "")
        }
        if (this.group.length < 2) {
            $.extend(this, {
                loop: false
            });
            this.title = '<div id="fancybox-buttons"><ul><li><a class="btnPrev btnDisabled"></a></li><li><a class="btnPlay btnDisabled"></a></li><li><a class="btnNext btnDisabled"></a></li><li><a class="btnToggle" onClick="javascript:$.fancybox.toggle();"></a></li><li><a class="btnClose" onClick="javascript:$.fancybox.close();"></a></li></ul></div> Рисунок ' + (this.index + 1) + " из " + this.group.length + (this.title ? " - " + this.title : "")
        }
    },
    afterShow: function () {
        $(".fancybox-wrap").easydrag();
        var e;
        e = $("#fancybox-buttons").find(".btnPlay").removeClass("btnPlayOn");
        if ($.fancybox.player.isActive) {
            e.addClass("btnPlayOn")
        }
        var t;
        t = $("#fancybox-buttons").find(".btnToggle").removeClass("btnDisabled btnToggleOn");
        if (this.canShrink) {
            t.addClass("btnToggleOn")
        } else if (!this.canExpand) {
            t.addClass("btnDisabled")
        }
    },
    onPlayStart: function () {
        $("#fancybox-buttons").find(".btnPlay").addClass("btnPlayOn")
    },
    onPlayEnd: function () {
        $("#fancybox-buttons").find(".btnPlay").removeClass("btnPlayOn")
    },
    onUpdate: function () {
        var e;
        e = $("#fancybox-buttons").find(".btnToggle").removeClass("btnDisabled btnToggleOn");
        if (this.canShrink) {
            e.addClass("btnToggleOn")
        } else if (!this.canExpand) {
            e.addClass("btnDisabled")
        }
    }
  })
});

CSS:

#fancybox-buttons{position:absolute;width:100%;z-index:8050}
#fancybox-buttons ul{display:block;float:right;height:25px;list-style:none;margin:0 auto;width:155px; margin-top: -10px;}
#fancybox-buttons ul li{float:left;margin:0;padding:0}
#fancybox-buttons a{cursor:pointer;background-repeat:no-repeat;display:block;height:25px;outline:none;text-indent:-9999px;width:27px}
Walter Stolz
  • 51
  • 1
  • 9