繁体   English   中英

JavaScript轮播的多个实例

[英]Multiple instances of a JavaScript carousel

因此,我编写了以下代码,使用Hammer.jsjQuery在JavaScript中构建轮播:

var hCarousel = {

    container: false,
    panes: false,
    pane_width: 0,
    pane_count: 0,
    current_pane: 0,

    build: function( element ) {

        hCarousel.container = $(element).find('.hcarousel-inner-container');

        hCarousel.panes = $(hCarousel.container).find('> .section');

        hCarousel.pane_width = 0;
        hCarousel.pane_count = hCarousel.panes.length;

        hCarousel.current_pane = 0;

        hCarousel.setPaneDimensions( element );

        $(window).on('load resize orientationchange', function() {

            hCarousel.setPaneDimensions( element );

        });

        $(element).hammer({ drag_lock_to_axis: true })
                    .on('release dragleft dragright swipeleft swiperight', hCarousel.handleHammer);

    },

    setPaneDimensions: function( element ){

        hCarousel.pane_width = $(element).width();

        hCarousel.panes.each(function() {
            $(this).width(hCarousel.pane_width);
        });

        hCarousel.container.width(hCarousel.pane_width*hCarousel.pane_count);

    },

    next: function() {

        return hCarousel.showPane(hCarousel.current_pane+1, true);

    },

    prev: function() {

        return hCarousel.showPane(hCarousel.current_pane-1, true);

    },

    showPane: function( index ) {

        // between the bounds
        index = Math.max(0, Math.min(index, hCarousel.pane_count-1));
        hCarousel.current_pane = index;

        var offset = -((100/hCarousel.pane_count)*hCarousel.current_pane);

        hCarousel.setContainerOffset(offset, true);

    },

    setContainerOffset: function( percent, animate ) {

        hCarousel.container.removeClass("animate");

        if(animate) {
            hCarousel.container.addClass("animate");
        }

        if(Modernizr.csstransforms3d) {
            hCarousel.container.css("transform", "translate3d("+ percent +"%,0,0) scale3d(1,1,1)");
        }
        else if(Modernizr.csstransforms) {
            hCarousel.container.css("transform", "translate("+ percent +"%,0)");
        }
        else {
            var px = ((hCarousel.pane_width*hCarousel.pane_count) / 100) * percent;
            hCarousel.container.css("left", px+"px");
        }

    },

    handleHammer: function( ev ) {

        ev.gesture.preventDefault();

        switch(ev.type) {

            case 'dragright':
            case 'dragleft':
                // stick to the finger
                var pane_offset = -(100/hCarousel.pane_count)*hCarousel.current_pane;
                var drag_offset = ((100/hCarousel.pane_width)*ev.gesture.deltaX) / hCarousel.pane_count;

                // slow down at the first and last pane
                if((hCarousel.current_pane == 0 && ev.gesture.direction == Hammer.DIRECTION_RIGHT) ||
                    (hCarousel.current_pane == hCarousel.pane_count-1 && ev.gesture.direction == Hammer.DIRECTION_LEFT)) {
                    drag_offset *= .4;
                }

                hCarousel.setContainerOffset(drag_offset + pane_offset);

                break;

            case 'swipeleft':
                hCarousel.next();
                ev.gesture.stopDetect();
                break;

            case 'swiperight':
                hCarousel.prev();
                ev.gesture.stopDetect();
                break;

            case 'release':
                // more then 50% moved, navigate
                if(Math.abs(ev.gesture.deltaX) > hCarousel.pane_width/2) {
                    if(ev.gesture.direction == 'right') {
                        hCarousel.prev();
                    } else {
                        hCarousel.next();
                    }
                }
                else {
                    hCarousel.showPane(hCarousel.current_pane, true);
                }
                break;
        }

    }

}

我这样称呼:

var hSections;

$(document).ready(function(){

    hSections = hCarousel.build('.hcarousel-container');

});

哪个工作正常。 但是我想这样做,以便我可以在页面上有多个轮播,这些轮播可以再次使用...但是容器的整体宽度是错误的,因为它结合了两个轮播的宽度。

我如何运行这样的多个实例,但是代码知道它与之交互的WHICH实例,所以事情不会混淆,等等。

我会尝试将其转换为可以像类一样使用的函数。 然后,您可以为轮播创建单独的对象。

因此,您将获得以下内容:

function HCarousel (element) {
    this.element=element;
    this.container= false;
    this.panes= false;
    this.pane_width= 0;
    this.pane_count= 0;
    this.current_pane= 0;
}

然后像这样在类上添加每个方法。

HCarousel.prototype.build = function() {
    this.container = $(element).find('.hcarousel-inner-container');
    this.panes = $(hCarousel.container).find('> .section');
    this.pane_width = 0;
    this.pane_count = hCarousel.panes.length;
    this.current_pane = 0;
    this.setPaneDimensions( element );
    $(window).on('load resize orientationchange', function() {
        this.setPaneDimensions( element );
    });
    $(this.element).hammer({ drag_lock_to_axis: true }).on('release dragleft dragright swipeleft swiperight', hCarousel.handleHammer);
};

等。这应该给你基本的想法。 将需要一些重写,但是您可以创建带有以下内容的轮播:

var carousel1 = new HCarousel('.hcarousel-container');

希望您能走上正确的道路。

类实际上在JS中并不存在,但这是一种使用函数模拟一个类的方法。 这是一篇有关在JS中使用类的好文章http://www.phpied.com/3-ways-to-define-a-javascript-class/

问题是您的设计实际上并不适合于多个实例,因为对象文字具有轮播的属性,而且具有构建方法。

如果我是从头开始的,那么我会更喜欢OOP设计,带有一个可实例化的轮播类,或者将其作为jQuery插件使用。 话虽如此,改编您现有的代码并不是没有可能。

function hCarousel(selector){
  function hCarouselInstance(element){
    var hCarousel = {

        // insert whole hCarousel object code
        container: false,
        panes: false,
        build : function( element ){
        ...

    };

    this.hCarousel = hCarousel;
    hCarousel.build(element);
  }

  var instances = [];
  $(selector).each(function(){
    instances.push(new hCarouselInstance(this));
  });

  return instances;
}

用法

例如,具有hcarousel-container类的所有元素都将成为独立的轮播。

$(document).ready(function(){
    var instances = hCarousel('.hcarousel-container');
});

说明:

hCarousel函数称为传递选择器,该选择器可以匹配多个元素。 如果需要,也可以多次调用它。

内部的hCarouselInstance将像类一样使用,并使用new关键字实例化。 调用hCarousel时,它将迭代匹配的元素并创建hCarouselInstance的新实例。 现在,hCarouselInstance是一个自包含函数,用于容纳您的原始hCarousel对象,在创建该对象后,它将调用hCarousel.build()

instances返回值是一个包含每个实例对象的数组。 您可以从此处访问hCarousel属性和方法,例如:

instances[0].hCarousel.panes;

jQuery插件

以下是对jQuery插件的转换,该插件可用于多个轮播。

(function ( $ ) {
    $.fn.hCarousel = function( ) {
        return this.each(function( ) {

            var hCarousel = {
                // insert whole hCarousel object code here - same as in the question
            };

            hCarousel.build(this);

        });
    };
}( jQuery ));

插件用法:

$('.hcarousel-container').hCarousel();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM