Search code examples
javascriptdom-eventspipefamo.us

Piping events from ScrollContainer


I'm trying to pipe mouse clicks from ScrollContainer encapsulated in a view, but somehow nothing's happening. I've just started playing with Famo.us so maybe I'm missing something obvious here. I can pipe directly from surfaces contained within ScrollContainer but I'm not sure if that's the way to do it. Any ideas ?

Link to runnable jsFiddle demo :

http://jsfiddle.net/nqxz596f/

And the code itself :

define('main', function (require, exports, module) {
    var Engine          = require('famous/core/Engine');
    var Surface         = require('famous/core/Surface');
    var Transform       = require('famous/core/Transform');
    var View            = require('famous/core/View');
    var Scrollview      = require('famous/views/ScrollContainer');

    var context = Engine.createContext();
    var mainview = new View({
        size: [500, 500]
    });
    var scrollview = new Scrollview({
        scrollview: {direction:0, size: [undefined, 300]}
    });
    var surfaces = [];

    scrollview.sequenceFrom(surfaces);

    for (var i = 0; i < 40; i++) {
        var surface = new Surface({
             content: "Surface: " + (i + 1),
             size: [undefined, 200],
             properties: {
                 backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
                 lineHeight: "200px",
                 textAlign: "center"
             }
        });

        surface.pipe(scrollview);
        surfaces.push(surface);
    }
    
    mainview._eventInput.on('click', function(){
        console.log('click');
    });
    
    scrollview.pipe(mainview);
    mainview.add(scrollview);

    context.add(mainview);
});

Solution

  • As of this writing, the ScrollContainer does not have it's own EventHandlers. It uses the event handlers from the ScrollView that it contains (scrollcontainer.scrollview). The ScrollContainer has a ContainerSurface that subscribes from the events of the scrollcontainer.scrollview and is the DOM element to hide the overflow of the scrollview.

    The below code in a new jsFiddle shows the correct way to setup the ContainerSurface. You do not need the mainview to pipe your events.

    You have a couple options:

    • Pipe the surface events to the scrollview event output (as below) and listen on the scrollview for the events
    • or Pipe the surface events to the container surface.pipe(scrollcontainer.container); and listen to the events from the container scrollcontainer.container.on('click', ...

    Corrected Code:

    define('main', function (require, exports, module) {
        var Engine = require('famous/core/Engine');
        var Surface = require('famous/core/Surface');
        var Transform = require('famous/core/Transform');
        var View = require('famous/core/View');
        var ScrollContainer = require('famous/views/ScrollContainer');
        var Scrollview = require('famous/views/Scrollview');
        var Utility = require('famous/utilities/Utility');
    
        var context = Engine.createContext();
    
        var scrollcontainer = new ScrollContainer({
    
            scrollview: {
                direction: Utility.Direction.Y
            }
        });
        scrollcontainer.container.setSize([500, 500]);
    
        var surfaces = [];
    
        for (var i = 0; i < 40; i++) {
            var surface = new Surface({
                content: "Surface: " + (i + 1),
                size: [undefined, 200],
                properties: {
                    backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
                    lineHeight: "200px",
                    textAlign: "center"
                }
            });
    
            surface.pipe(scrollcontainer.scrollview._eventOutput);
            surfaces.push(surface);
        }
    
        scrollcontainer.scrollview.on('click', function (e) {
            console.log('click ' + e.target.innerText);
        });
    
        scrollcontainer.sequenceFrom(surfaces);
    
        context.add(scrollcontainer);
    });
    

    Alternative Option:

        for (var i = 0; i < 40; i++) {
            var surface = new Surface({
                content: "Surface: " + (i + 1),
                size: [undefined, 200],
                properties: {
                    backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
                    lineHeight: "200px",
                    textAlign: "center"
                }
            });
    
            surface.pipe(scrollcontainer.container);
            surfaces.push(surface);
        }
    
        scrollcontainer.container.on('click', function (e) {
            console.log('click ' + e.target.innerText);
        });
    

    jsFiddle to show event pipe to a View

    for (var i = 0; i < 40; i++) {
        var surface = new Surface({
            content: "Surface: " + (i + 1),
            size: [undefined, 200],
            properties: {
                backgroundColor: "hsl(" + (i * 360 / 40) + ", 100%, 50%)",
                lineHeight: "200px",
                textAlign: "center"
            }
        });
    
        surface.pipe(scrollcontainer.container);
        surfaces.push(surface);
    }
    
    var mainview = new View({size: [500, 500]});
    
    mainview.on('click', function (e) {
        console.log('click ' + e.target.innerText);
    });
    
    scrollcontainer.sequenceFrom(surfaces);
    
    scrollcontainer.container.pipe(mainview._eventOutput);
    
    context.add(scrollcontainer).add(mainview);