gpt4 book ai didi

javascript - SetInterval/Slider 不适用于 Chrome

转载 作者:可可西里 更新时间:2023-11-01 14:52:48 28 4
gpt4 key购买 nike

我正在使用来自 codrops 的循环内容轮播,并进行了一些修改。

我正在尝试使用 setInterval 调用使 slider 自动滚动。在 IE 和 Firefoxe 中,它工作正常,但在 Chrome 中,它只滑动一次,再也不会滑动了。任何人都可以检查我的 setInterval 代码有什么问题吗?

这是我用于自动滚动的代码片段:

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

我需要用给定的变量调用 aux.navigate,这是使 slider 永远滚动的一种方法。

这是经过我修改后的 Slider 的完整代码(自动滚动代码接近尾声,在方法部分的末尾):

(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 上运行,在其他浏览器中运行良好。非常感谢您对此的任何教导和帮助。

附言/编辑:

我将 Slider 添加到临时服务器,您可以在此处使用完整代码在线找到它:http://ceh.ilch.uminho.pt/test/

最佳答案

我看不出 Chrome 应该有问题的具体原因(除了它现在是一个常见的主题)但是你可以尝试触发点击“下一步”按钮,自动查看 缓存。是动画:

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 问题外,还有一些好东西供您使用:

  • 要在页面加载时启动自动滚动,请使用选项 autoStart: true 进行初始化(默认为 false)。

  • 可选择包含“自动”按钮(如“更多”和“关闭”)以启动自动滚动。

  • 单击“上一个”、“下一个”、“更多”或“关闭”控件以停止自动滚动。

  • 按住 Control 键并单击“上一个”或“下一个”控件以开始自动滚动。

仅按住 control 并单击“prev”向左自动滚动。所有其他 autoScrolls 都正确。

示例初始化:

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

确保在部署之前测试所有内容。

关于javascript - SetInterval/Slider 不适用于 Chrome,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15819429/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com