Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8 />
  <title>JS Bin</title>
  <!-- Test dependencies -->
  <link rel="stylesheet" href="http://imagine-it.org/cdn/mocha.css" />
  <script src="http://imagine-it.org/cdn/mocha.js"></script>
  <script src="http://imagine-it.org/cdn/chai.js"></script>
  <script src="http://imagine-it.org/cdn/sinon.js"></script>
  
  <!-- Marquee dependencies -->
  <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
  <script src="http://www.coursera.org/static/js/lib/lucid.js">
   
  </script>
</head>
<body>
  
   <div id="mocha"></div>
  
  
</body>
</html>
 
/** Marquee
Why does this library exist?
==============================
We found ourself constantly having to implement scrolling text, and since <marquee> was deprecated from the HTML spec by the haters, we kept writing it in JavaScript. So, we've developed this library that we can use anywhere that we do scrolling text. (We may extend this to also emulate <blink> functionality, as that's come up a few times recently as well).
How do you use this library?
==============================
The typical usage is to create a simple DIV with your text:
<div id="marquee"></div>
Then call Marquee on it, with any desired customization options:
var marquee = new Marquee($('#marquee'), {distance: 1});
You can also specify options in the HTML:
<div id="marquee" data-marquee-direction="backwards"></div>
You can even construct it in HTML. If the HTML is loaded after the JS, however, you'll have to call Marquee.start:
<div id="marquee" data-marquee data-marquee-direction="backwards"></div>
Marquee.start();
*/ 
(function(wndw) {
  var MarqueeModule = function($, LucidJS) {
    
    var _private = {
      defaults: {
        'direction': 'forwards',  // 'forwards' or 'backwards',
        'distance' : 10 // any integer
      },
      getOrMakeMarquee: function(elem, options) {
        var marquee = $(elem).data('marquee.object');
        if (marquee && marquee.constructor == Marquee.prototype.constructor) {
          if (options) _private.customizeMarquee.call(marquee, options);
          return marquee;
        } else {
          marquee = new Marquee($(elem), options);
          $(elem).data('marquee.object', marquee);
          return marquee;
        }
      },
      customizeMarquee: function(options) {
        var dataDefaults = {};
        for (var optKey in _private.defaults) {
          dataDefaults[optKey] = this.$elem.attr('data-marquee-' + optKey);
        }
        this.options = $.extend({}, _private.defaults, dataDefaults, options);
        this.direction = this.options.direction;
      },
      moveItMoveIt: function() {
        var currentLeft = parseInt(this.$elem.css('left'), 10);
        if (currentLeft > $(window).width()) {
          this.direction = 'backwards';
          this.emitter.trigger('reverse');
        } else if (currentLeft < 0) {
          this.direction = 'forwards';
          this.emitter.trigger('reverse');
        }
        if (this.direction == 'forwards') {
          newLeft = (currentLeft + parseInt(this.options.distance, 10));
        } else {
          newLeft = (currentLeft - parseInt(this.options.distance, 10));
        }
        this.$elem.css('left', newLeft + 'px');
      }
    };
    
    
    var Marquee = function(elem, options) {
      this.$elem = $(elem);
      
      this.$elem.css('position', 'relative');
      this.$elem.css('left', '0px');
      
      this.emitter = LucidJS.emitter(this);
      
      _private.customizeMarquee.call(this, options);
      
      var self = this;
      this.moveTimer = window.setInterval(function() {_private.moveItMoveIt.call(self);}, 50);
    };
    
    Marquee.prototype.stop = function() {
      window.clearInterval(this.moveTimer);
    };
    
    var _public = function(el, options) {
      return _private.getOrMakeMarquee(el, options);
    };
    _public.start = function(elem) {
      var $elem = $(elem);
      if ($elem.data('marquee-initialized')) {
        return;
      } else {
        $elem.data('marquee-initialized', 1);
      }
      console.log(elem.innerHTML);
      $elem.find('[data-marquee]').each(function(elem) {
        console.log('found one');
        _public(elem);
      });
    };
    
    //_public.start(document.body);
    
    return _public;
  };
  
  
  if (typeof define === "function" && define.amd) {
    define(["jquery", "lucid"], function($, LucidJS) {
      return MarqueeModule($, LucidJS);
    });
  } else if (typeof window !== "undefined" && typeof ender === "undefined") {
    wndw.Marquee = MarqueeModule(wndw.$, wndw.LucidJS);
  }
  
})(window);
// Tests
mocha.setup('bdd');
describe('Marquee', function() {
  var $marqueeDiv;
  
  beforeEach(function() {
    // do some setup code
    $marqueeDiv = $('<div>');
    $marqueeDiv.html("Scroll me baby one more time");
    $('body').append($marqueeDiv);
  });
  afterEach(function() {
    $marqueeDiv.remove();   
  });
  
  it('sets the defaults correctly', function() {
    var marquee = new Marquee($marqueeDiv);
    chai.expect(marquee.options.distance).to.be.equal(10);
    chai.expect(marquee.options.direction).to.be.equal('forwards');
  });
  
  it('customizes with distance option', function() {
    var marquee = new Marquee($marqueeDiv, {distance: 1});
    chai.expect(marquee.options.distance).to.be.equal(1);
  });
  
  it('customizes with direction option', function() {
    var marquee = new Marquee($marqueeDiv, {direction: 'backwards'});
    chai.expect(marquee.options.direction).to.be.equal('backwards');
    chai.expect(marquee.direction).to.be.equal('backwards');
  });
  
  it('re-sets options when re-constructed', function() {
    var marquee = new Marquee($marqueeDiv, {distance: 1});
    chai.expect(marquee.options.distance).to.be.equal(1);
    marquee = new Marquee($marqueeDiv, {distance: 2});
    chai.expect(marquee.options.distance).to.be.equal(2);
  });
  
  it('can be customized in HTML', function() {
    $marqueeDiv.attr('data-marquee-direction', 'backwards');
    $marqueeDiv.attr('data-marquee-distance', '5');
    var marquee = new Marquee($marqueeDiv);
    chai.expect(marquee.options.distance).to.be.equal('5');
    chai.expect(marquee.options.direction).to.be.equal('backwards');
  });
  
  it('can be customized in HTML', function() {
    $marqueeDiv.attr('data-marquee-direction', 'backwards');
    $marqueeDiv.attr('data-marquee-distance', '5');
    var marquee = new Marquee($marqueeDiv);
    chai.expect(marquee.options.distance).to.be.equal('5');
    chai.expect(marquee.options.direction).to.be.equal('backwards');
  });
  
  
  it('triggers the reverse event', function(done) {
    var marquee = new Marquee($marqueeDiv, {distance: $(window).width()-10});
    marquee.on('reverse', function() {
      done();
    });
  });
  
});
mocha.run();
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers