Question

I'm using vTicker which is working perfectly, but after items cycle through, they lose their css properties that are based on their pseudo-classes. The idea is to have the first and last child be of the same opacity, the second and second-to-last, and so-on-so-forth with the middle item being at 100% opacity.

I've looked into adding classes to control this as well, such as:

<ul>
    <li class="item-1">Text</li>
    <li class="item-2">Text</li>
</ul>

But once item-1 cycles through, it just goes to the bottom of the list while keeping the class name. I need the class name "item-1" to always stay with the first item in the list even after vTicker reorders it.

How would I go about that? Here's the code for vTicker:

/*! vTicker 1.14
 http://richhollis.github.com/vticker/ | http://richhollis.github.com/vticker/license/ | based on Jubgits vTicker http://www.jugbit.com/jquery-vticker-vertical-news-ticker/ */
(function(d){var m={speed:700,pause:4E3,showItems:1,mousePause:!0,height:0,animate:!0,margin:0,padding:0,startPaused:!1},c={moveUp:function(a,b){c.animate(a,b,"up")},moveDown:function(a,b){c.animate(a,b,"down")},animate:function(a,b,e){var c=a.itemHeight,f=a.options,g=a.element.children("ul"),k="up"===e?"li:first":"li:last",l=g.children(k).clone(!0);0<f.height&&(c=g.children("li:first").height());c+=f.margin+2*f.padding;"down"===e&&g.css("top","-"+c+"px").prepend(l);if(b&&b.animate){if(a.animating)return;
a.animating=!0;g.animate("up"===e?{top:"-="+c+"px"}:{top:0},f.speed,function(){d(g).children(k).remove();d(g).css("top","0px");a.animating=!1})}else g.children(k).remove(),g.css("top","0px");"up"===e&&l.appendTo(g)},nextUsePause:function(){var a=d(this).data("state"),b=a.options;a.isPaused||2>a.itemCount||f.next.call(this,{animate:b.animate})},startInterval:function(){var a=d(this).data("state"),b=this;a.intervalId=setInterval(function(){c.nextUsePause.call(b)},a.options.pause)},stopInterval:function(){var a=
d(this).data("state");a&&(a.intervalId&&clearInterval(a.intervalId),a.intervalId=void 0)},restartInterval:function(){c.stopInterval.call(this);c.startInterval.call(this)}},f={init:function(a){f.stop.call(this);var b=jQuery.extend({},m);a=d.extend(b,a);var b=d(this),e={itemCount:b.children("ul").children("li").length,itemHeight:0,itemMargin:0,element:b,animating:!1,options:a,isPaused:a.startPaused?!0:!1,pausedByCode:!1};d(this).data("state",e);b.css({overflow:"hidden",position:"relative"}).children("ul").css({position:"absolute",
margin:0,padding:0}).children("li").css({margin:a.margin,padding:a.padding});isNaN(a.height)||0===a.height?(b.children("ul").children("li").each(function(){var a=d(this);a.height()>e.itemHeight&&(e.itemHeight=a.height())}),b.children("ul").children("li").each(function(){d(this).height(e.itemHeight)}),b.height((e.itemHeight+(a.margin+2*a.padding))*a.showItems+a.margin)):b.height(a.height);var h=this;a.startPaused||c.startInterval.call(h);a.mousePause&&b.bind("mouseenter",function(){!0!==e.isPaused&&
(e.pausedByCode=!0,c.stopInterval.call(h),f.pause.call(h,!0))}).bind("mouseleave",function(){if(!0!==e.isPaused||e.pausedByCode)e.pausedByCode=!1,f.pause.call(h,!1),c.startInterval.call(h)})},pause:function(a){var b=d(this).data("state");if(b){if(2>b.itemCount)return!1;(b.isPaused=a)?d(this).addClass("paused"):d(this).removeClass("paused")}},next:function(a){var b=d(this).data("state");if(b){if(b.animating||2>b.itemCount)return!1;c.restartInterval.call(this);c.moveUp(b,a)}},prev:function(a){var b=
d(this).data("state");if(b){if(b.animating||2>b.itemCount)return!1;c.restartInterval.call(this);c.moveDown(b,a)}},stop:function(){d(this).data("state")&&c.stopInterval.call(this)}};d.fn.vTicker=function(a){if(f[a])return f[a].apply(this,Array.prototype.slice.call(arguments,1));if("object"!==typeof a&&a)d.error("Method "+a+" does not exist on jQuery.vTicker");else return f.init.apply(this,arguments)}})(jQuery);
Was it helpful?

Solution

I'm the author of vTicker.

I see the same behaviour in Webkit and if this is a webkit bug it probably won't get fixed any time soon!

My suggestion is to add some events to vTicker (before and after ticker animates) and then set the desired effects using jQuery.

Have a look at this:

http://jsfiddle.net/v6Znq/2/

/*
  Vertical News Ticker 1.15 (pre-release)

  Original by: Tadas Juozapaitis ( kasp3rito [eta] gmail (dot) com )
               http://www.jugbit.com/jquery-vticker-vertical-news-ticker/

  Forked/Modified by: Richard Hollis @richhollis - richhollis.co.uk
*/

(function($){

  var defaults = {
    speed: 700,
    pause: 4000,
    showItems: 1,
    mousePause: true,
    height: 0,
    animate: true,
    margin: 0,
    padding: 0,
    startPaused: false
  };

  var internal = { 

    moveUp: function(state, attribs) {    
      internal.animate(state, attribs, 'up');
    },

    moveDown: function(state, attribs){
      internal.animate(state, attribs, 'down');
    },

    animate: function(state, attribs, dir) {
      var height = state.itemHeight;
      var options = state.options;
      var el = state.element;
      var obj = el.children('ul');
      var selector = (dir === 'up') ? 'li:first' : 'li:last';

      state.element.trigger("vticker.beforeTick");

      var clone = obj.children(selector).clone(true);

      if(options.height > 0) height = obj.children('li:first').height();
      height += (options.margin) + (options.padding*2); // adjust for margins & padding

      if(dir==='down') obj.css('top', '-' + height + 'px').prepend(clone);

      if(attribs && attribs.animate) {
        if(state.animating) return;
        state.animating = true;
        var opts = (dir === 'up') ? {top: '-=' + height + 'px'} : {top: 0};
        obj.animate(opts, options.speed, function() {
            $(obj).children(selector).remove();
            $(obj).css('top', '0px');
            state.animating = false;
            state.element.trigger("vticker.ticked");
          });
      } else {
        obj.children(selector).remove();
        obj.css('top', '0px');
        state.element.trigger("vticker.ticked");
      }
      if(dir==='up') clone.appendTo(obj);
    },

    nextUsePause: function() {
      var state = $(this).data('state');
      var options = state.options;
      if(state.isPaused || state.itemCount < 2) return;
      methods.next.call( this, {animate:options.animate} );
    },

    startInterval: function() {
      var state = $(this).data('state');
      var options = state.options;
      var initThis = this;
      state.intervalId = setInterval(function(){ 
        internal.nextUsePause.call( initThis );
      }, options.pause);
    },

    stopInterval: function() {
      var state = $(this).data('state');
      if(!state) return;
      if(state.intervalId) clearInterval(state.intervalId);
      state.intervalId = undefined;
    },

    restartInterval: function() {
      internal.stopInterval.call(this);
      internal.startInterval.call(this);
    }
  };

  var methods = {

    init: function(options) {
      // if init called second time then stop first, then re-init
      methods.stop.call(this);
      // init
      var defaultsClone = jQuery.extend({}, defaults);
      var options = $.extend(defaultsClone, options);
      var el = $(this);
      var state = { 
        itemCount: el.children('ul').children('li').length,
        itemHeight: 0,
        itemMargin: 0,
        element: el,
        animating: false,
        options: options,
        isPaused: (options.startPaused) ? true : false,
        pausedByCode: false
      };
      $(this).data('state', state);

      el.css({overflow: 'hidden', position: 'relative'})
        .children('ul').css({position: 'absolute', margin: 0, padding: 0})
        .children('li').css({margin: options.margin, padding: options.padding});

      if(isNaN(options.height) || options.height === 0)
      {
        el.children('ul').children('li').each(function(){
          var current = $(this);
          if(current.height() > state.itemHeight)
            state.itemHeight = current.height();
        });
        // set the same height on all child elements
        el.children('ul').children('li').each(function(){
          var current = $(this);
          current.height(state.itemHeight);
        });
        // set element to total height
        var box = (options.margin) + (options.padding * 2);
        el.height(((state.itemHeight + box) * options.showItems) + options.margin);
      }
      else
      {
        // set the preferred height
        el.height(options.height);
      }

      var initThis = this;
      if(!options.startPaused) {
        internal.startInterval.call( initThis );
      }

      if(options.mousePause)
      {
        el.bind("mouseenter", function () {
          //if the automatic scroll is paused, don't change that.
          if (state.isPaused === true) return; 
          state.pausedByCode = true; 
          // stop interval
          internal.stopInterval.call( initThis );
          methods.pause.call( initThis, true );
        }).bind("mouseleave", function () {
          //if the automatic scroll is paused, don't change that.
          if (state.isPaused === true && !state.pausedByCode) return;
          state.pausedByCode = false; 
          methods.pause.call(initThis, false);
          // restart interval
          internal.startInterval.call( initThis );
        });
      }
    },

    pause: function(pauseState) {
      var state = $(this).data('state');
      if(!state) return undefined;
      if(state.itemCount < 2) return false;
      state.isPaused = pauseState;
      if(pauseState) $(this).addClass('paused');
      else $(this).removeClass('paused');
    },

    next: function(attribs) { 
      var state = $(this).data('state');
      if(!state) return undefined;
      if(state.animating || state.itemCount < 2) return false;
      internal.restartInterval.call( this );
      internal.moveUp(state, attribs); 
    },

    prev: function(attribs) {
      var state = $(this).data('state');
      if(!state) return undefined;
      if(state.animating || state.itemCount < 2) return false;
      internal.restartInterval.call( this );
      internal.moveDown(state, attribs); 
    },

    stop: function() {
      var state = $(this).data('state');
      if(!state) return undefined;
      internal.stopInterval.call( this );
    },

    remove: function() {
      var state = $(this).data('state');
      if(!state) return undefined;
      internal.stopInterval.call( this );
      var el = state.element;
      el.unbind();
      el.remove();
    }
  };

  $.fn.vTicker = function( method ) {
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.vTicker' );
    }    
  };
})(jQuery);

jQuery(function() {
    function setInitialOpacities() {
        var ul = jQuery('#home-tick ul');
        ul.children('li:nth-child(1)').css("opacity", .15);
        ul.children('li:nth-child(2)').css("opacity", .15);
        ul.children('li:nth-child(3)').css("opacity", .23);
        ul.children('li:nth-child(4)').css("opacity", 1);
        ul.children('li:nth-child(5)').css("opacity", .23);
        ul.children('li:nth-child(6)').css("opacity", .15);
        ul.children('li:nth-child(7)').css("opacity", .15);       
    }

    jQuery('#home-tick').vTicker({showItems: 7});
    setInitialOpacities();

    jQuery('#home-tick').on('vticker.beforeTick', function() {
        var ul = jQuery('#home-tick ul');
        var interval = 500;
        ul.children('li:nth-child(1)').animate({opacity: .15}, interval);
        ul.children('li:nth-child(2)').animate({opacity: .15}, interval);
        ul.children('li:nth-child(3)').animate({opacity: .23}, interval);
        ul.children('li:nth-child(4)').animate({opacity: .23}, interval);
        ul.children('li:nth-child(5)').animate({opacity: 1}, interval);
        ul.children('li:nth-child(6)').animate({opacity: .23}, interval);
        ul.children('li:nth-child(7)').animate({opacity: .15}, interval);
        ul.children('li:nth-child(8)').css("opacity", .15);       
    });
    jQuery('#home-tick').on('vticker.ticked', function() {
    });                               
});

If this gives you what you need then please mark as answer and I will update vTicker release accordingly.

Richard

OTHER TIPS

Try adding :

.intro-main-title ul li:last-child { opacity: .15 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top