簡體   English   中英

SetInterval / Slider無法與Chrome配合使用

[英]SetInterval/Slider is not working with Chrome

我正在使用來自codrops的循環內容輪播,並進行了一些修改。

我正在嘗試使用setInterval調用使滑塊自動滾動。 在IE和Firefoxe中,它工作正常,但在Chrome中它只滑動一次,而不是更多。 任何人都可以檢查我的setInterval代碼有什么問題嗎?

這是我用於自動滾動的一段代碼:

var autoscroll = setInterval(function() {
    aux.navigate( 1, $el, $wrapper, settings, cache );
},5000);

我需要使用給定的變量調用aux.navigate,這是使滑塊永遠滾動的一種方法。

以下是我修改的Slider的完整代碼(自動滾動代碼片段接近結尾,在methodes部分的末尾):

(function($) {

var aux     = {

        // navigates left / right
        navigate    : function( dir, $el, $wrapper, opts, cache ) {

            var scroll      = opts.scroll,
                factor      = 1,
                idxClicked  = 0;

            if( cache.expanded ) {
                scroll      = 1; // scroll is always 1 in full mode
                factor      = 3; // the width of the expanded item will be 3 times bigger than 1 collapsed item 
                idxClicked  = cache.idxClicked; // the index of the clicked item
            }

            // clone the elements on the right / left and append / prepend them according to dir and scroll
            if( dir === 1 ) {
                $wrapper.find('div.ca-item:lt(' + scroll + ')').each(function(i) {
                    $(this).clone(true).css( 'left', ( cache.totalItems - idxClicked + i ) * cache.itemW * factor + 'px' ).appendTo( $wrapper );
                });
            }
            else {
                var $first  = $wrapper.children().eq(0);

                $wrapper.find('div.ca-item:gt(' + ( cache.totalItems  - 1 - scroll ) + ')').each(function(i) {
                    // insert before $first so they stay in the right order
                    $(this).clone(true).css( 'left', - ( scroll - i + idxClicked ) * cache.itemW * factor + 'px' ).insertBefore( $first );
                });
            }

            // animate the left of each item
            // the calculations are dependent on dir and on the cache.expanded value
            $wrapper.find('div.ca-item').each(function(i) {
                var $item   = $(this);
                $item.stop().animate({
                    left    :  ( dir === 1 ) ? '-=' + ( cache.itemW * factor * scroll ) + 'px' : '+=' + ( cache.itemW * factor * scroll ) + 'px'
                }, opts.sliderSpeed, opts.sliderEasing, function() {
                    if( ( dir === 1 && $item.position().left < - idxClicked * cache.itemW * factor ) || ( dir === -1 && $item.position().left > ( ( cache.totalItems - 1 - idxClicked ) * cache.itemW * factor ) ) ) {
                        // remove the item that was cloned
                        $item.remove();
                    }                       
                    cache.isAnimating   = false;
                });
            });

        },
        // opens an item (animation) -> opens all the others
        openItem    : function( $wrapper, $item, opts, cache ) {
            cache.idxClicked    = $item.index();
            // the item's position (1, 2, or 3) on the viewport (the visible items) 
            cache.winpos        = aux.getWinPos( $item.position().left, cache );


            $wrapper.find('div.ca-item').not( $item ).hide();

            $wrapper.find('div.ca-item-main').hide();

            //$item.find('div.ca-content-wrapper').stop().animate({ sera a solução para nao haver espaço branco ao fim do scroll em fullscreen??
            $item.find('div.ca-content-wrapper').css( 'left', cache.itemW + 'px' ).stop().animate({
                width   : cache.itemW * 3 + 'px',
                left    : '0px'
            }, opts.itemSpeed, opts.itemEasing)
            .end()
            .stop()
            .animate({
                left    : '0px'
            }, opts.itemSpeed, opts.itemEasing, function() {
                cache.isAnimating   = false;
                cache.expanded      = true;

                aux.openItems( $wrapper, $item, opts, cache );
            });

        },
        // opens all the items
        openItems   : function( $wrapper, $openedItem, opts, cache ) {
            var openedIdx   = $openedItem.index();

            $wrapper.find('div.ca-item').each(function(i) {
                var $item   = $(this),
                    idx     = $item.index();

                if( idx !== openedIdx ) {
                    $item.css( 'left', - ( openedIdx - idx ) * ( cache.itemW * 3 ) + 'px' ).show().find('div.ca-content-wrapper').css({
                        left    : '0px',
                        width   : cache.itemW * 3 + 'px'
                    });
                }
            });
        },
        // close all the items
        // the current one is animated
        closeItems  : function( $wrapper, $openedItem, opts, cache ) {
            var openedIdx   = $openedItem.index();

            $openedItem.find('div.ca-content-wrapper').stop().animate({
                width   : '0px'
            }, opts.itemSpeed, opts.itemEasing)
            .end()
            .stop()
            .animate({
                left    : cache.itemW * ( cache.winpos - 1 ) + 'px'
            }, opts.itemSpeed, opts.itemEasing, function() {
                cache.isAnimating   = false;
                cache.expanded      = false;
            });

            $wrapper.find('div.ca-item').each(function(i) {
                var $item   = $(this),
                    idx     = $item.index();

                $item.find('div.ca-item-main').show();

                if( idx !== openedIdx ) {
                    $item.find('div.ca-content-wrapper').css({
                        width   : '0px'
                    })
                    .end()
                    .css( 'left', ( ( cache.winpos - 1 ) - ( openedIdx - idx ) ) * cache.itemW + 'px' )
                    .show();
                }
            });
        },
        // gets the item's position (1, 2, or 3) on the viewport (the visible items)
        // val is the left of the item
        getWinPos   : function( val, cache ) {
            switch( val ) {
                case 0                  : return 1; break;
                case cache.itemW        : return 2; break;
                case cache.itemW * 2    : return 3; break;
            }
        }
    },
    methods = {
        init        : function( options ) {

            if( this.length ) {

                var settings = {
                    sliderSpeed     : 500,          // speed for the sliding animation
                    sliderEasing    : 'easeOutExpo',// easing for the sliding animation
                    itemSpeed       : 500,          // speed for the item animation (open / close)
                    itemEasing      : 'easeOutExpo',// easing for the item animation (open / close)
                    scroll          : 1             // number of items to scroll at a time
                };

                return this.each(function() {

                    // if options exist, lets merge them with our default settings
                    if ( options ) {
                        $.extend( settings, options );
                    }

                    var $el             = $(this),
                        $wrapper        = $el.find('div.ca-wrapper'),
                        $items          = $wrapper.children('div.ca-item'),
                        cache           = {};

                    // save the with of one item    
                    cache.itemW         = $items.width();
                    // save the number of total items
                    cache.totalItems    = $items.length;

                    // add navigation buttons
                    if( cache.totalItems > 3 )  
                        $el.prepend('<div class="ca-nav"><span class="ca-nav-prev">Previous</span><span class="ca-nav-next">Next</span></div>') 

                    // control the scroll value
                    if( settings.scroll < 1 )
                        settings.scroll = 1;
                    else if( settings.scroll > 3 )
                        settings.scroll = 3;    

                    var $navPrev        = $el.find('span.ca-nav-prev'),
                        $navNext        = $el.find('span.ca-nav-next');

                    // hide the items except the first 3
                    $wrapper.css( 'overflow', 'hidden' );

                    // the items will have position absolute 
                    // calculate the left of each item
                    $items.each(function(i) {
                        $(this).css({
                            position    : 'absolute',
                            left        : i * cache.itemW + 'px'
                        });
                    });

                    // click to open the item(s)
                    $el.find('a.ca-more').live('click.contentcarousel', function( event ) {
                        if( cache.isAnimating ) return false;
                        cache.isAnimating   = true;
                        var $item   = $(this).closest('div.ca-item');
                        aux.openItem( $wrapper, $item, settings, cache );
                        return false;
                    });

                    // click to close the item(s)
                    $el.find('a.ca-close').live('click.contentcarousel', function( event ) {
                        if( cache.isAnimating ) return false;
                        cache.isAnimating   = true;
                        var $item   = $(this).closest('div.ca-item');
                        aux.closeItems( $wrapper, $item, settings, cache );
                        return false;
                    });

                    // navigate left
                    $navPrev.bind('click.contentcarousel', function( event ) {
                        if( cache.isAnimating ) return false;
                        cache.isAnimating   = true;
                        aux.navigate( -1, $el, $wrapper, settings, cache );
                    });

                    // navigate right
                    $navNext.bind('click.contentcarousel', function( event ) {
                        if( cache.isAnimating ) return false;
                        cache.isAnimating   = true;
                        aux.navigate( 1, $el, $wrapper, settings, cache );
                    });

                    // adds events to the mouse
                    $el.bind('mousewheel.contentcarousel', function(e, delta) {
                        if(delta > 0) {
                            if( cache.isAnimating ) return false;
                            cache.isAnimating   = true;
                            aux.navigate( -1, $el, $wrapper, settings, cache );
                        }   
                        else {
                            if( cache.isAnimating ) return false;
                            cache.isAnimating   = true;
                            aux.navigate( 1, $el, $wrapper, settings, cache );
                        }   
                        return false;
                    });


                    var autoscroll = setInterval(function() {
                    aux.navigate( 1, $el, $wrapper, settings, cache );
                    },1000);

                });
            }
        }
    };

$.fn.contentcarousel = 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.contentcarousel' );
    }
};

})(jQuery);

我已經嘗試了很多代碼組合,搜索了很多,但無法使其在Chrome上運行,在其他瀏覽器中它運行正常。 非常感謝任何教學和幫助。

PS /編輯:

我將Slider添加到臨時服務器,你可以在這里找到它的完整代碼: http//ceh.ilch.uminho.pt/test/

我看不出Chrome出現問題的原因(這些日子不是常見的主題)但是你可以嘗試觸發點擊“下一步”按鈕,自動關注cache.isAnimating

var autoscroll = setInterval(function() {
    $navNext.trigger('click.contentcarousel');
}, 5000);

編輯

好的,經過一些嚴肅的整理代碼並轉換為使用jQuery 1.9.1(以前的jQuery 1.6.2),我最終得到了這個:

(function($) {
    var pluginName = 'contentcarousel';

    //Define event namespace strings
    var evt_ns = {
        click: 'click.' + pluginName,
        mousewheel: 'mousewheel.' + pluginName
    };
    var aux = {
        // navigates left / right
        navigate: function( dir, $el, $wrapper, opts, cache ) {
            if( cache.isAnimating ) return;
            cache.isAnimating = true;
            var scroll = ( cache.expanded ) ? 1 : opts.scroll,
                factor = ( cache.expanded ) ? 3 : 1,// expanded width will be 3x that of one collapsed item
                idxClicked = ( cache.expanded ) ? cache.idxClicked : 0;
            // clone the elements on the right / left and append / prepend them according to dir and scroll
            if( dir === 1 ) {
                $wrapper.find('div.ca-item:lt(' + scroll + ')').each(function(i) {
                    $(this).clone(true).css( 'left', ( cache.totalItems - idxClicked + i ) * cache.itemW * factor + 'px' ).appendTo( $wrapper );
                });
            }
            else {
                var $first = $wrapper.children().eq(0);
                $wrapper.find('div.ca-item:gt(' + ( cache.totalItems  - 1 - scroll ) + ')').each(   function(i) {
                    // insert before $first so they stay in the right order
                    $(this).clone(true).css( 'left', - ( scroll - i + idxClicked ) * cache.itemW * factor + 'px' ).insertBefore( $first );
                });
            }
            // animate the left of each item
            // the calculations are dependent on dir and on the cache.expanded value
            $wrapper.find('div.ca-item').each(function(i) {
                var $item = $(this);
                $item.stop().animate({
                    left : ( dir === 1 ) ? '-=' + ( cache.itemW * factor * scroll ) + 'px' : '+=' + ( cache.itemW * factor * scroll ) + 'px'
                }, opts.sliderSpeed, opts.sliderEasing, function() {
                    if( ( dir === 1 && $item.position().left < - idxClicked * cache.itemW * factor ) || ( dir === -1 && $item.position().left > ( ( cache.totalItems - 1 - idxClicked ) * cache.itemW * factor ) ) ) {
                        // remove the item that was cloned
                        $item.remove();
                    }
                    cache.isAnimating = false;
                });
            });
        },
        // opens an item (animation) -> opens all the others
        openItem: function( $wrapper, $item, opts, cache ) {
            if( cache.isAnimating ) return;
            cache.isAnimating = true;
            cache.idxClicked = $item.index();
            // the item's position (1, 2, or 3) on the viewport (the visible items) 
            cache.winpos = aux.getWinPos( $item.position().left, cache );
            $wrapper.find('div.ca-item').not( $item ).hide();
            $wrapper.find('div.ca-item-main').hide();
            //$item.find('div.ca-content-wrapper').stop().animate({ sera a solução para nao haver espaço branco ao fim do scroll em fullscreen??
            $item.find('div.ca-content-wrapper').css( 'left', cache.itemW + 'px' ).stop().animate({
                left : '0px',
                width : cache.itemW * 3 + 'px'
            }, opts.itemSpeed, opts.itemEasing).end().stop().animate({
                left : '0px'
            }, opts.itemSpeed, opts.itemEasing, function() {
                cache.isAnimating = false;
                cache.expanded = true;
                aux.openItems( $wrapper, $item, opts, cache );
            });
        },
        // opens all the items
        openItems: function( $wrapper, $openedItem, opts, cache ) {
            var openedIdx = $openedItem.index();
            $wrapper.find('div.ca-item').each(function(i) {
                var $item = $(this),
                    idx = $item.index();
                if( idx !== openedIdx ) {
                    $item.css( 'left', - ( openedIdx - idx ) * ( cache.itemW * 3 ) + 'px' ).show().find('div.ca-content-wrapper').css({
                        left : '0px',
                        width : cache.itemW * 3 + 'px'
                    });
                }
            });
        },
        // close all the items
        // the current one is animated
        closeItems: function( $wrapper, $openedItem, opts, cache ) {
            if( cache.isAnimating ) return;
            cache.isAnimating = true;
            var openedIdx = $openedItem.index();
            $openedItem.find('div.ca-content-wrapper').stop().animate({
                width: '0px'
            }, opts.itemSpeed, opts.itemEasing).end().stop().animate({
                left: cache.itemW * ( cache.winpos - 1 ) + 'px'
            }, opts.itemSpeed, opts.itemEasing, function() {
                cache.isAnimating = false;
                cache.expanded = false;
            });
            $wrapper.find('div.ca-item').each(function(i) {
                var $item = $(this),
                    idx = $item.index();
                $item.find('div.ca-item-main').show();
                if( idx !== openedIdx ) {
                    $item.find('div.ca-content-wrapper').css({
                        width: '0px'
                    }).end().css( 'left', ( ( cache.winpos - 1 ) - ( openedIdx - idx ) ) * cache.itemW + 'px' ).show();
                }
            });
        },
        // gets the item's position (1, 2, or 3) on the viewport (the visible items)
        // val is the left of the item
        getWinPos: function( val, cache ) {
            switch( val ) {
                case 0: return 1; break;
                case cache.itemW: return 2; break;
                case cache.itemW * 2: return 3; break;
            }
        },
        startAuto: function( dir, $el, $wrapper, settings, cache ) {
        aux.stopAuto( cache );
            aux.navigate( dir, $el, $wrapper, settings, cache );
            cache.autoscroll = setInterval(function() {
                aux.navigate( dir, $el, $wrapper, settings, cache );
            }, 1000);
        },
        stopAuto: function( cache ) {
            if(cache.autoscroll) {
                clearInterval(cache.autoscroll);
                cache.autoscroll = null;
                return true;
            }
            return false;
        }
    },
    methods = {
        init : function( options ) {
            if( this.length ) {
                var settings = {
                    autoStart: false,
                    sliderSpeed: 500, // speed for the sliding animation
                    sliderEasing: 'easeOutExpo',// easing for the sliding animation
                    itemSpeed: 500, // speed for the item animation (open / close)
                    itemEasing: 'easeOutExpo',// easing for the item animation (open / close)
                    scroll: 1 // number of items to scroll at a time
                };
                return this.each(function() {
                    // if options exist, lets merge them with our default settings
                    if ( options ) {
                        $.extend( settings, options );
                    }
                    // control the scroll value
                    settings.scroll = Math.max(Math.min(settings.scroll, 3), 1);
                    var $el = $(this),
                        $wrapper = $el.find('div.ca-wrapper'),
                        $items = $wrapper.children('div.ca-item'),
                        cache = {
                            autoscroll: null,
                            itemW: $items.width(),// save the width of one item
                            totalItems: $items.length// save the number of total items
                        };
                    // add navigation buttons
                    if( cache.totalItems > 3 )
                        $el.prepend('<div class="ca-nav"><span class="ca-nav-prev">Previous</span><span class="ca-nav-next">Next</span></div>');
                    var controls = {
                        navPrev: $el.find('span.ca-nav-prev'),
                        navNext: $el.find('span.ca-nav-next'),
                        more: $el.find('a.ca-more'),
                        close: $el.find('a.ca-close'),
                        auto: $el.find('a.ca-auto')
                    };

                    // hide the items except the first 3
                    $wrapper.css( 'overflow', 'hidden' );

                    // the items will have position absolute 
                    // calculate the left of each item
                    $items.each(function(i) {
                        $(this).css({
                            position: 'absolute',
                            left: i * cache.itemW + 'px'
                        });
                    });
                    // click to open the item(s)
                    controls.more.on(evt_ns.click, function( event ) {
                        aux.stopAuto( cache );
                        var $item = $(this).closest('div.ca-item');
                        aux.openItem( $wrapper, $item, settings, cache );
                        return false;
                    });
                    // click to close the item(s)
                    controls.close.on(evt_ns.click, function( event ) {
                        aux.stopAuto( cache );
                        var $item = $(this).closest('div.ca-item');
                        aux.closeItems( $wrapper, $item, settings, cache );
                        return false;
                    });
                    // navigate left
                    controls.navPrev.on(evt_ns.click, function( event ) {
                        if ( !aux.stopAuto( cache ) ) {
                            if (event.ctrlKey) aux.startAuto( -1, $el, $wrapper, settings, cache );
                            else aux.navigate( -1, $el, $wrapper, settings, cache );
                        }
                        return false;
                    });
                    // navigate right
                    controls.navNext.on(evt_ns.click, function( event ) {
                        if ( !aux.stopAuto( cache ) ) {
                            if (event.ctrlKey) aux.startAuto( 1, $el, $wrapper, settings, cache );
                            else aux.navigate( 1, $el, $wrapper, settings, cache );
                        }
                        return false;
                    });
                    // add event handler to the mousewheel
                    $el.on(evt_ns.mousewheel, function( event, delta ) {
                        if (!aux.stopAuto( cache )) {
                            aux.navigate( (delta > 0) ? -1 : 1, $el, $wrapper, settings, cache);
                        }
                        return false;
                    });
                    // add event handler to an optional "auto" button
                    controls.auto.on(evt_ns.click, function( event ) {
                        aux.startAuto(1, $el, $wrapper, settings, cache);
                        return false;
                    });
                    // autoStart
                    if(settings.autoStart) {
                        $(window).on('load', function() {
                            setTimeout(function() {
                                aux.startAuto(1, $el, $wrapper, settings, cache);
                            }, 1000);
                        });
                    }
                });
            }
        }
    };
    $.fn[pluginName] = 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.' + pluginName );
        }
    };
})(jQuery);

我不確定是什么修復了它,但可能是jQuery的后期版本。 許多事情在1.7時有所改善,然后在1.8和1.9時逐步提高。

除了解決Chrome問題之外,還有一些好東西可供選擇:

  • 要在頁面加載時啟動autoScroll,請使用選項autoStart初始化autoStart: true (默認為false )。

  • 可選地包括“自動”按鈕(如“更多”和“關閉”)以啟動autoScroll。

  • 單擊“上一步”,“下一步”,“更多”或“關閉”控件以停止autoScroll。

  • 按住Control鍵並單擊“上一步”或“下一步”控件以啟動autoScroll。

只有按住Control鍵並單擊“prev”autoScrolls。 所有其他autoScrolls都是正確的。

樣本初始化:

$(function() {
    $('#ca-container').contentcarousel({
        autoStart: true
    });
});

確保在部署之前測試所有內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM