views:

1009

answers:

1

Hello guys,

I'm working with a Slideshow, and I'd like to give to the items in it a smooth pop-up bubble, to give some more info about them on mouseover.

The thing is, when I use the nice system that I found here (inspired by a post in jQuery for Designers), combined with jCarousel Lite, it seems to be a conflict.

I got both versions working OK as separate things, the problem appears when I mix them, and I don't actually know where I should check : I tweaked the CSS in every possible way, maybe there can be the solution and I didn't see it ? And if I must re-do the .js files ... then I would be quite lost.

What I got by now :

Slide and bubble, separated, working

Slide and bubble incorporated, not working

Thanks for any quick input,

jCarousel Lite :

(function($) {                                          // Compliant with jquery.noConflict()
$.fn.jCarouselLite = function(o) {
    o = $.extend({
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,

        speed: 200,
        easing: null,

        vertical: false,
        circular: true,
        visible: 3,
        start: 0,
        scroll: 1,

        beforeStart: null,
        afterEnd: null
    }, o || {});

    return this.each(function() {                           // Returns the element collection. Chainable.

        var running = false, animCss=o.vertical?"top":"left", sizeCss=o.vertical?"height":"width";
        var div = $(this), ul = $("ul", div), tLi = $("li", ul), tl = tLi.size(), v = o.visible;

        if(o.circular) {
            ul.prepend(tLi.slice(tl-v-1+1).clone())
              .append(tLi.slice(0,v).clone());
            o.start += v;
        }

        var li = $("li", ul), itemLength = li.size(), curr = o.start;
        div.css("visibility", "visible");

        li.css({overflow: "hidden", float: o.vertical ? "none" : "left"});
        ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
        div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"});

        var liSize = o.vertical ? height(li) : width(li);   // Full li size(incl margin)-Used for animation
        var ulSize = liSize * itemLength;                   // size of full ul(total length, not just for the visible items)
        var divSize = liSize * v;                           // size of entire div(total length for just the visible items)

        li.css({width: li.width(), height: li.height()});
        ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

        div.css(sizeCss, divSize+"px");                     // Width of the DIV. length of visible images

        if(o.btnPrev)
            $(o.btnPrev).click(function() {
                return go(curr-o.scroll);
            });

        if(o.btnNext)
            $(o.btnNext).click(function() {
                return go(curr+o.scroll);
            });

        if(o.btnGo)
            $.each(o.btnGo, function(i, val) {
                $(val).click(function() {
                    return go(o.circular ? o.visible+i : i);
                });
            });

        if(o.mouseWheel && div.mousewheel)
            div.mousewheel(function(e, d) {
                return d>0 ? go(curr-o.scroll) : go(curr+o.scroll);
            });

        if(o.auto)
            setInterval(function() {
                go(curr+o.scroll);
            }, o.auto+o.speed);

        function vis() {
            return li.slice(curr).slice(0,v);
        };

        function go(to) {
            if(!running) {

                if(o.beforeStart)
                    o.beforeStart.call(this, vis());

                if(o.circular) {            // If circular we are in first or last, then goto the other end
                    if(to<=o.start-v-1) {           // If first, then goto last
                        ul.css(animCss, -((itemLength-(v*2))*liSize)+"px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
                        curr = to==o.start-v-1 ? itemLength-(v*2)-1 : itemLength-(v*2)-o.scroll;
                    } else if(to>=itemLength-v+1) { // If last, then goto first
                        ul.css(animCss, -( (v) * liSize ) + "px" );
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
                        curr = to==itemLength-v+1 ? v+1 : v+o.scroll;
                    } else curr = to;
                } else {                    // If non-circular and to points to first or last, we just return.
                    if(to<0 || to>itemLength-v) return;
                    else curr = to;
                }                           // If neither overrides it, the curr will still be "to" and we can proceed.

                running = true;

                ul.animate(
                    animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
                    function() {
                        if(o.afterEnd)
                            o.afterEnd.call(this, vis());
                        running = false;
                    }
                );
                // Disable buttons when the carousel reaches the last/first, and enable when not
                if(!o.circular) {
                    $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
                    $( (curr-o.scroll<0 && o.btnPrev)
                        ||
                       (curr+o.scroll > itemLength-v && o.btnNext)
                        ||
                       []
                     ).addClass("disabled");
                }

            }
            return false;
        };
    });
};

function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
};
function width(el) {
    return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
};
function height(el) {
    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
};

})(jQuery);

And the Coda Bubble Plugin :

jQuery.fn.codaBubble = function(opts){
 var bubble = this;
 opts = jQuery.extend({
  distances : [20],
  leftShifts : [30],
    bubbleTimes : [400],
    hideDelays : [0],
    bubbleWidths : [200],
    bubbleImagesPath : "",
    msieFix : true,
    msiePop : true
 },opts||{});
        function bubbleHtmlWrapper(bubbleHtml) {
       return '<table class="popup" style="opacity: 0; top: -120px; left: -33px; display: none;"><tr><td class="corner topleft"/><td class="top"/><td class="corner topright"/></tr><tr><td class="left"/><td class="bubble_content">' +  bubbleHtml  + '</td><td class="right"/></tr><tr><td class="corner bottomleft"/><td class="bottom"><img style="display:block;" width="30" height="29" alt="" /></td><td class="corner bottomright"/></tr></table>';
    }
 return jQuery(bubble).each(function (i) {
    var bubbleHtml = jQuery('.bubble_html', this).html();      jQuery('.bubble_html', this).hide().after(bubbleHtmlWrapper(bubbleHtml));     jQuery('.popup td.bottom img', this).attr('src', opts.bubbleImagesPath  + '/bubble-tail2.png');
    if (opts.msieFix)
    {
      if ($.browser.msie)
      {
       jQuery('.popup td.topleft').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-1.gif)');
       jQuery('.popup td.top').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-2.gif)');
       jQuery('.popup td.topright').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-3.gif)');
       jQuery('.popup td.left').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-4.gif)');
       jQuery('.popup td.right').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-5.gif)');
       jQuery('.popup td.bottomleft').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-6.gif)');
       jQuery('.popup td.bottom').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-7.gif)');        jQuery('.popup td.bottomright').css('background-image', 'url(' + opts.bubbleImagesPath  + '/bubble-8.gif)');        jQuery('.popup td.bottom img').attr('src', opts.bubbleImagesPath  + '/bubble-tail2.gif');
      }
    }
        var distance = opts.distances[i];
    var time = opts.bubbleTimes[i];
    var hideDelay = opts.hideDelays[i];
    var hideDelayTimer = null;
    var beingShown = false;
    var shown = false;
    var trigger = jQuery('.trigger', this);
    var popup = jQuery('.popup', this).css('opacity', 0);
         jQuery([trigger.get(0), popup.get(0)]).mouseover(function () {
      jQuery(popup).css("width", opts.bubbleWidths[i] + "px");
      var triggerWidth = jQuery(trigger.get(0)).css('width');
             if (hideDelayTimer) clearTimeout(hideDelayTimer);
      if (beingShown || shown) {
        return;
      } else {
        beingShown = true;
         popup.css({
          top: -100,
          left: opts.leftShifts[i],
          display: 'block'
        })
        .animate({
          top: '-=' + distance + 'px',
          opacity: 1
        }, time, 'swing', function() {
          beingShown = false;
          shown = true;
        });
      }
    }).mouseout(function () {
      if (hideDelayTimer) clearTimeout(hideDelayTimer);
             hideDelayTimer = setTimeout(function () {
        hideDelayTimer = null;
        popup.animate({
          top: '-=' + distance + 'px',
          opacity: 0
        }, time, 'swing', function () {
          shown = false;
          popup.css('display', 'none');
        });
      }, hideDelay);
    });
    if (!opts.msiePop && $.browser.msie)
   {      jQuery(popup).remove();
   }
  });}
+1  A: 

Your problem with the two implementations is that the carousel uses overflow hidden on both the DIV and the LI's wrapping each image. When you hover over an image, your tooltip code is firing properly but you cannot actually see the tooltip being displayed because it's hidden above the LI element.

For a fix, you would have to have the tooltip event append the tooltip directly to the BODY tag and utilize a couple jquery techniques to find the of the LI that fired the event to reposition the tooltip.

Another possibility is to ensure that all images displayed have a fixed thumbnail size and you can do away with the overflow: hidden on all elements. You would then need to add the following to the parent DIV that previously had overflow: hidden

overflow-x: hidden;

This is because you really only care to hide the left and right sides of the carousel, not the top and bottom. This would allow the tooltip to properly display as it displays in the positive Y axis of the LI.

EDIT

You'll want to modify these lines in the jCarousel JS:

li.css({overflow: "hidden", float: o.vertical ? "none" : "left"});
div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"});

And make sure you have a CSS style to increase the z-index of the tooltip to at least 3.

cballou
cballou, awesome ! thanks. I'm still trying to figure it out, I'll try to post back a (hopefully) happy end.
Peanuts