How to add the buttons from Button helper to the t

2019-05-18 21:54发布

问题:

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;
}

回答1:

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



回答2:

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');
        }
    }


回答3:

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}