I have made a jQuery plugin which acts as a slideshow. All of my problem is that it does fades out first, and then the next images fades in. Which is a little odd. I have thought all the day and am really beat about it. Can anyone helps me? Here is the info:
Below is a list of websites with current slideshow hosted:
http://behdis.org
www.ms-models.com
www.royal-fci.com
Now, PROBLEM is:
there are naturally a bunch of images for the slideshow to fade them in and out. Now, the slideshow makes the first image faded out and then makes the next image faded in. I want the slideshow to begin fading in the next image when the current image has already begun fading out. Just like hundreds of slideshows out there on many websites. No need to give link.
Here is the plugin script itself:
(function(){
/* function read_line (path_to_file, container, tag, url_prefix)
{
myObject = {}; //myObject[numberline] = "textEachLine";
$.get(, functipath_to_fileon(myContentFile) {
var lines = myContentFile.split("\r\n");
for(var i in lines)
{
myObject[i] = i;
container.append('<'+tag+'>'+"<img src='"+url_prefix+'/'+lines[i]+"'>"+'</img>'+'</'+tag+'>');
}
}, 'text');// end of anonymous function
} */
$.fn.mtSlideGallery = function(options){
var options = $.extend({
fullWidth : false, // this makes a full background slideshow
FadeIn : 2, // this is the duration of fading in
FadeOut : 2, // this is the duration of fading out
visibilityDuration : 2, // this is the duration of visible image
startSlide : 1, // this is the first slide when the page loads
height : '100%',
height_fixed : true,
enable_error : false,
enable_gallery : false,
slide_previous : '.slide-left-control', // this is the name of class for previous-picture-handle
slide_next : '.slide-right-control', // this is the name of class for next-picture-handle
print_output : false,
print_area : '.slideshow-label',
seo_campatible : false, // this allows the script to print the title of each slide out into a h1-h6 tag
seo_suggestion : 'h2' // this allows the user to specify which h1-h6 tag be used. default is h6
/*auto_generate_from_file : false, // if true, then it will generate the div tag based on a file given
auto_generate_url : false, // if true, then a url_prefix is added to each line of text
auto_generate_tag : 'div', // the tag inside which the image tags nest. default is div and it is recommended no to change
auto_generate_url_prefix : "" // this is the url added to each image address. Depends on auto_generate_url options*/
}, options)
// develope $fn protype
return this.each(function(){
if(options.print_output === true)
{
var text_for_output = $(this).children('div').eq(options.startSlide).children('img').attr('alt');
$(options.print_area).text(text_for_output);
}
if(options.fullWidth === true)
{
$("body").css({'padding' : '0', 'margin' : '0'});
$("body").css({'overflow' : 'hidden'});
$("html").css({'padding' : '0', 'margin' : '0'});
$(this).css({'width' : '100%', 'height' : options.height});
$(this).css({'margin' : '0', 'padding' : '0'});
}
if(options.height_fixed === true)
{
$(this).css({'overflow' : 'hidden'});
}
var slideWrapper = $(this);
var slidesGroup = slideWrapper.children('div');
slidesLength = slidesGroup.length;
if(options.enable_error == true)
{
if(options.startSlide > slidesLength)
{
alert("Please correct the \"slideStart\" option. The number has to be less than the total number of images.")
}
}
i = options.startSlide;
slidesGroup.not(":eq("+i+")").hide();
console.log(slidesLength);
////////////////////// Print To label if true
var print_label = function(i)
{
var label = slidesGroup.eq(i).children('img').attr('alt');
$(options.print_area).text(label);
}
;
///////////////////// End of printing label
//////////////// GALLERY SLIDESHOW IF ENABLED USES THIS SCRIPT
if(options.enable_gallery === true)
{
$(options.slide_previous).click(function(event){ // this is a click event for the previous picture in the queue
event.preventDefault();
event.stopPropagation();
slidesGroup.eq(i).hide();
if(i === slidesLength)
{
i=0;
}
i -= 1;
slidesGroup.eq(i).show();
if(options.print_output === true)
{
print_label(i);
}
});
$(options.slide_next).click(function(event){ // this is a click event for the next picture in the queue
event.preventDefault();
event.stopPropagation();
slidesGroup.eq(i).hide();
if(i === slidesLength)
{
i=0;
}
i += 1;
slidesGroup.eq(i).show();
if(options.print_output === true)
{
print_label(i);
}
});
}
////////////////////// END OF GALLERY-ENABLED SCRIPT
////////////////////////////////////////////////////////
var slideShow = function () {
slidesGroup.eq(i).fadeOut(options.FadeOut*1000, function(){
slidesGroup.eq(i).hide();
i += 1;
if(i === slidesLength)
{
i=0;
}
slidesGroup.eq(i).fadeIn(options.FadeIn*1000);
if(options.print_output === true)
{
print_label(i);
}
})
}
setInterval(slideShow, options.visibilityDuration*1000);
})
}
})(jQuery)
Now, the slideshow makes the first image faded out and then makes the
next image faded in. I want the slideshow to begin fading in the next
image when the current image has already begun fading out.
The issue here is that the call to fade in the next slide is part of an anonymous callback function that does not fire until the initial jQuery animation is complete. You'll want to rewrite your code such that the $.fadeOut() and $.fadeIn() functions occur simultaneously:
var transition = function() {
//Determine the index of the next slide to show, based on the current index
var next_index = (current_index < slidesLength - 1) ? current_index + 1 : 0;
//Fade out the 'old' slide while fading in the 'new' slide
slidesGroup.eq(current_index).fadeOut({
duration: options.FadeOut*1000,
start: function() {
slidesGroup.eq(next_index).fadeIn({
duration: options.FadeIn*1000
});
},
complete: function() {
//Update the value of current_index
current_index = next_index;
}
});
}
However, this function pretty much restricts you to forward-only transitions. You could include a function argument that specifies a transition direction (forward and backward) that will determine the 'next slide' index.
Working jsFiddle: http://jsfiddle.net/gh25s/
EDIT: To clarify, you'll want to replace this part of your code:
var slideShow = function () {
slidesGroup.eq(i).fadeOut(options.FadeOut*1000, function(){
slidesGroup.eq(i).hide();
i += 1;
if(i === slidesLength) {
i=0;
}
slidesGroup.eq(i).fadeIn(options.FadeIn*1000);
if(options.print_output === true) {
print_label(i);
}
});
};
with this:
var slideShow = function() {
//Determine the index of the next slide to show, based on the current index
var next_index = (i < slidesLength - 1) ? i + 1 : 0;
//Fade out the 'old' slide while fading in the 'new' slide
slidesGroup.eq(i).fadeOut({
duration: options.FadeOut*1000,
start: function() {
slidesGroup.eq(next_index).fadeIn({
duration: options.FadeIn*1000
});
},
complete: function() {
//Update the value of i
i = next_index;
}
});
}
Also, using the variable name i throughout your code is confusing. I would suggest giving it a more meaningful, descriptive name like current_index. Variable names like i are typically read as temporary, local variables that are being used for some kind of iteration.
Related
I commented a fadeOut for some of the sections but cannot get them to reappear after scrolling a second time and I don't know javascript well enough to find the right solution. How would I do that?
$(document.body).fadeIn(1000);
$(document).ready(function() {
'use strict';
// variables
var $isH1First = $('.first .is-animated h1'),
$ispFirst = $('.first .is-animated p'),
$isH1Second = $('.second .is-animated h1'),
$ispSecond = $('.second .is-animated p'),
$isH1Third = $('.third .is-animated h1'),
$ispThird = $('.third .is-animated p');
// initialize fullPage
$('#fullpage').fullpage({
// navigation: true,
scrollingSpeed: 1400,
resetSliders:true,
fitToSectionDelay: 1000,
afterLoad: function(index, nextIndex) {
if( nextIndex === 1 ) {
$isH1First.addClass('animated fadeInLeft').css('animation-delay', '.05s');
$ispFirst.addClass('animated fadeInLeft').css('animation-delay', '.45s');
}
},
onLeave: function(index, nextIndex) {
// first animation
if( nextIndex === 2) {
// $isH1First.addClass('animated fadeOutUp');
// $ispFirst.addClass('animated fadeOutUp');
$isH1Second.addClass('animated fadeInDown').css('animation-delay', '.45s');
$ispSecond.addClass('animated fadeInDown').css('animation-delay', '.85s');
}
// second animation
else if( nextIndex === 3 ) {
// $isH1Second.addClass('animated fadeOutUp');
// $ispSecond.addClass('animated fadeOutUp');
$isH1Third.addClass('animated bounceInDown').css('animation-delay', '.45s');
$ispThird.addClass('animated flipInX').css('animation-delay', '.85s');
}
}
});
});
I know this is rather late ,I use velocity.js to get nice animations and I wanted to only show the animations once and not every time the section loads.
If I understand you correctly then you are trying to achieve the opposite which was the default behavior for me.
A small example of my code :
if (index === 1) {
//slide 1 animation
if (!$jq(".refine").is(":visible")
{
$jq(".refine").velocity("fadeIn", {duration: 2000});
}
}
I'm trying to run a function when the last slide of the carousel has been reached. I've managed to use afterInit and afterMove callbacks to cycle the carousel items but I just need to be able to run a function when the cycle ends.
Hope you can help.
Plugin: http://owlgraphic.com/owlcarousel/#customizing
slideshow.owlCarousel({
navigation: false, // Show next and prev buttons
slideSpeed: 300,
paginationSpeed: 400,
singleItem: true,
autoPlay: false,
stopOnHover: false,
afterInit : cycle,
afterMove : moved,
});
function cycle(elem){
$elem = elem;
//start counting
start();
}
function start() {
//reset timer
percentTime = 0;
isPause = false;
//run interval every 0.01 second
tick = setInterval(interval, 10);
};
function interval() {
if(isPause === false){
percentTime += 1 / time;
//if percentTime is equal or greater than 100
if(percentTime >= 100){
//slide to next item
$elem.trigger('owl.next')
}
}
}
function moved(){
//clear interval
clearTimeout(tick);
//start again
start();
}
I can't find any onEnd handler.
But you can use afterMove event to check if the displayed element is the last by accesing the carousel instance properties currentItem and itemsCount.
Ref:
var owl = $(".owl-carousel").data('owlCarousel');
Code:
// carousel setup
$(".owl-carousel").owlCarousel({
navigation: false,
slideSpeed: 300,
paginationSpeed: 400,
singleItem: true,
autoHeight: true,
afterMove: moved,
});
function moved() {
var owl = $(".owl-carousel").data('owlCarousel');
if (owl.currentItem + 1 === owl.itemsAmount) {
alert('THE END');
}
}
Demo: http://jsfiddle.net/IrvinDominin/34bJ6/
The above works (I suppose) on Owl Carousel 1, but if you are using the new Owl 2 beta you will need:
$('.owl-carousel').on('change.owl.carousel', function(e) {
if (e.namespace && e.property.name === 'position'
&& e.relatedTarget.relative(e.property.value) === e.relatedTarget.items().length - 1) {
// put your stuff here ...
console.log('last slide')
}
});
I got the above answer here btw: https://github.com/OwlFonk/OwlCarousel2/issues/292#event-140932502
A better solution, in my opinion:
(the code above doesn't take into account responsive layouts with a variable amount of items being shown at a time)
mySlider.on('change.owl.carousel', function(e) {
// number of items on screen updates on responsive
var shown = e.page.size
// total number of slides
var total = e.relatedTarget.items().length - 1
// current slide index
var current = e.item.index
// how many slides to go?
var remain = total - (shown + current)
if( !remain ){
// last slide, fire a method - but dont forget to add checks that you only fire it or execute it once
}
});
mySlider.on('changed.owl.carousel', function(e) {
// am i the first slide? I do it this way so that we can check for first being true
var first = ( !e.item.index)
if( first ){
// first slide, fire a method - but dont forget to add checks that you only fire it or execute it once
}
});
For anyone using the beta in 2016 the easiest way is to use the 'translated' event like so:-
// I'm using Drupal so I already have a carousel going.
var owl = $('#owl-carousel-page2');
// After slide has moved fire some stuff
owl.on('translated.owl.carousel', function (event) {
console.log(event, "the event after move");
});
I've read a lot of ways of doing this but this seems to work the best fyi.
i ran into same problem so i searched but these answers were not working for me, so here is my solution, which will work with multiple item slides and single item slide as well.
$('.owl-carousel').on('changed.owl.carousel', function(e) {
if (e.page.index+1 == e.page.count) {
console.log('last');
}
if (e.item.index==0) {
console.log('start');
}
});
All the above solutions don't work on Owl Carousel 2.3.4
So I had to figure out a way to do that and I ended up with the following solution
$('.owl-carousel').on('changed.owl.carousel', function(e) {
var items = e.item.count; // Number of items
var item = e.item.index; // Position of the current item
var size = e.page.size; // Number of items per page
if (item === 0) {
console.log('Start')
}
if ((items - item) === size) {
console.log('Last')
}
});
I know this question is a bit old, but I came with a simpler solution that covers both situations: multiple(customItems) and singleItem, just use it like this:
$('.wrap_carousel_feeds').owlCarousel({
rewindNav: false,
responsiveRefreshRate: 50,
//singleItem: true, //works
itemsCustom: [
[2570, 15], [2390, 14], [2210, 13], [2030, 12], [1850, 11], [1670, 10], [1490, 9], [1310, 8], [1130, 7], [950, 6], [770, 5], [590, 4]
], //works too
afterMove: function(owl){
data = $(owl).data('owlCarousel');
isLast = data.currentItem + data.visibleItems.length == data.itemsAmount;
if(isLast){ //returns true when reaches the last
//do stuffs
}
}
});
Fiddle:
http://jsfiddle.net/rafaelmoni/1ty13y93/
I am using owl carousel 2 and found out these variables might be able to help:
$('.owl-carousel').on('change.owl.carousel', function(e) {
var carousel = e.currentTarget,
totalPageNumber = e.page.count, // count start from 1
currentPageNumber = e.page.index + 1; // index start from 0
if(currentPageNumber === totalPageNumber - 1){
console.log('last page reached!');
}
});
});
Slick carousel is a much better alternative to owl carousel. I would highly recommend that.
$carousel.on('change.owl.carousel', function (e) {
if (e.namespace && e.property.name === 'position' && e.item.index === e.item.count - 1) {
if (ko.isObservable(values.loaded)) {
values.loaded(false);
}
}
});
See below:
$(".owl-carousel").on('change.owl.carousel', function(e) {
var total = e.item.count, // # of total items
itemsPerPage = e.page.size, // # of items that appear per page
itemGoOut = e.item.index, // index of last item that appeared then went out (index start with 0)
itemRemain = total - (itemsPerPage + itemGoOut + 1);
if(itemRemain === 0){
console.log("No more Items");
}
});
I wrote a slideshow plugin, but for some reason maybe because I've been working on it all day, I can't figure out exactly how to get it to go back to state one, once it's reached the very last state when it's on auto mode.
I'm thinking it's an architectual issue at this point, because basically I'm attaching the amount to scroll left to (negatively) for each panel (a panel contains 4 images which is what is currently shown to the user). The first tab should get: 0, the second 680, the third, 1360, etc. This is just done by calculating the width of the 4 images plus the padding.
I have it on a setTimeout(function(){}) currently to automatically move it which works pretty well (unless you also click tabs, but that's another issue). I just want to make it so when it's at the last state (numTabs - 1), to animate and move its state back to the first one.
Code:
(function($) {
var methods = {
init: function(options) {
var settings = $.extend({
'speed': '1000',
'interval': '1000',
'auto': 'on'
}, options);
return this.each(function() {
var $wrapper = $(this);
var $sliderContainer = $wrapper.find('.js-slider-container');
$sliderContainer.hide().fadeIn();
var $tabs = $wrapper.find('.js-slider-tabs li a');
var numTabs = $tabs.size();
var innerWidth = $wrapper.find('.js-slider-container').width();
var $elements = $wrapper.find('.js-slider-container a');
var $firstElement = $elements.first();
var containerHeight = $firstElement.height();
$sliderContainer.height(containerHeight);
// Loop through each list element in `.js-slider-tabs` and add the
// distance to move for each "panel". A panel in this example is 4 images
$tabs.each(function(i) {
// Set amount to scroll for each tab
if (i === 1) {
$(this).attr('data-to-move', innerWidth + 20); // 20 is the padding between elements
} else {
$(this).attr('data-to-move', innerWidth * (i) + (i * 20));
}
});
// If they hovered on the panel, add paused to the data attribute
$('.js-slider-container').hover(function() {
$sliderContainer.attr('data-paused', true);
}, function() {
$sliderContainer.attr('data-paused', false);
});
// Start the auto slide
if (settings.auto === 'on') {
methods.auto($tabs, settings, $sliderContainer);
}
$tabs.click(function() {
var $tab = $(this);
var $panelNum = $(this).attr('data-slider-panel');
var $amountToMove = $(this).attr('data-to-move');
// Remove the active class of the `li` if it contains it
$tabs.each(function() {
var $tab = $(this);
if ($tab.parent().hasClass('active')) {
$tab.parent().removeClass('active');
}
});
// Add active state to current tab
$tab.parent().addClass('active');
// Animate to panel position
methods.animate($amountToMove, settings);
return false;
});
});
},
auto: function($tabs, settings, $sliderContainer) {
$tabs.each(function(i) {
var $amountToMove = $(this).attr('data-to-move');
setTimeout(function() {
methods.animate($amountToMove, settings, i, $sliderContainer);
}, i * settings.interval);
});
},
animate: function($amountToMove, settings, i, $sliderContainer) {
// Animate
$('.js-slider-tabs li').eq(i - 1).removeClass('active');
$('.js-slider-tabs li').eq(i).addClass('active');
$('#js-to-move').animate({
'left': -$amountToMove
}, settings.speed, 'linear', function() {});
}
};
$.fn.slider = 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 {
return false;
}
};
})(jQuery);
$(window).ready(function() {
$('.js-slider').slider({
'speed': '10000',
'interval': '10000',
'auto': 'on'
});
});
The auto and animate methods are where the magic happens. The parameters speed is how fast it's animated and interval is how often, currently set at 10 seconds.
Can anyone help me figure out how to get this to "infinitely loop", if you will?
Here is a JSFiddle
It would probably be better to let go of the .each() and setTimeout() combo and use just setInterval() instead. Using .each() naturally limits your loop to the length of your collection, so it's better to use a looping mechanism that's not, and that you can break at any point you choose.
Besides, you can readily identify the current visible element by just checking for .active, from what I can see.
You'd probably need something like this:
setInterval(function () {
// do this check here.
// it saves you a function call and having to pass in $sliderContainer
if ($sliderContainer.attr('data-paused') === 'true') { return; }
// you really need to just pass in the settings object.
// the current element you can identify (as mentioned),
// and $amountToMove is derivable from that.
methods.animate(settings);
}, i * settings.interval);
// ...
// cache your slider tabs outside of the function
// and just form a closure on that to speed up your manips
var slidertabs = $('.js-slider-tabs');
animate : function (settings) {
// identify the current tab
var current = slidertabs.find('li.active'),
// and then do some magic to determine the next element in the loop
next = current.next().length >= 0 ?
current.next() :
slidertabs.find('li:eq(0)')
;
current.removeClass('active');
next.addClass('active');
// do your stuff
};
The code is not optimized, but I hope you see where I'm getting at here.
I'm currently using the anythingSlider plugin, it works totally fine except when there is only one <li>.
The <li>s are generated from the database so sometimes there's only one.
However, the anythingSlider plugin still tries to slide through the <li>s, it works by sliding back to the first slide. Although this doesn't look great.
Does anybody know of a way of stopping it sliding if there's only one <li>?
-- EDIT --
Hi!
Can anybody else help with this? I've tried the solution by Greg and I've also tried:
if (banners<1) {
.anythingSlider({
startStopped: true,
buildNavigation: false
});
}
'banners' is my variable that I'm calling.
And this disables the anythingSlider function altogether.
Help please?!
-- EDIT 2 --
The original code is in the page of the html
<script type="text/javascript">
var banners=[];
banners[0]="http://image.ebuyer.com/customer/promos/UK/AcerAspire5536.jpg";
//banners[1]="http://image.ebuyer.com/customer/promos/2150/banner.jpg";
//banners[2]="http://image.ebuyer.com/customer/promos/UK/257653_FerrariOne_tb20091026.jpg";
//banners[3]="http://image.ebuyer.com/customer/promos/UK/247038_compaq_images/247038_compaq_incentive_banner20090814.jpg"; //added 03/09/2009
//banners[4]="http://image.ebuyer.com/customer/promos/UK/247858-samsung-tv-comp-tb20090817.jpg"; //added 19/08/2009
var bannerLink=[];
bannerLink[0]="http://www.ebuyer.com/product/173536";
//bannerLink[1]="/special/2150";
//bannerLink[2]="/product/172295";
//bannerLink[3]="/compaq-cash-incentive";
//bannerLink[4]="/special/2101";
var bannerAlt=[];
bannerAlt[0]="Acer Aspire 5536";
//bannerAlt[1]="The X5 range for Asus";
//bannerAlt[2]="Acer Ferrari One Laptop";
//bannerAlt[3]="Buy these three products together and claim £75 cashback";
//bannerAlt[4]="Win a Samsung 46in LCV TV";
</script>
It's then being actioned by this file: http://image.ebuyer.com/customer/promos/js/topbanners.js
// function to import css and javascript from external locations
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
// importing css and javascript
loadjscssfile("http://static.ebuyer.com/css/slider.css", "css") ////dynamically load and add this .css file
// setting the variables
var banner = document.getElementById('tehBanner');
var link = document.getElementById('tehLink');
// this function creates the tracking tags
function tracking (x) {
if (x.indexOf("?")>=0){x+='&tb='+(i+1);}else{x+='?tb='+(i+1);}
return x
}
// telling the javascript to display all available variables
for (var i in banners) {
banner.alt = bannerAlt[i];
link.href = tracking(bannerLink[i]);
banner.src = banners[i];
document.write('' + '<img src="' + banners[i] + '" id="slide-image" alt="' + bannerAlt[i] + '" />');
}
// remove the original banner
$ ('a#tehLink').parent().remove();
// hide banners to begin with
$('a.slide-link').hide();
/*
anythingSlider v1.1
By Chris Coyier: http://css-tricks.com
with major improvements by Doug Neiner: http://pixelgraphics.us/
based on work by Remy Sharp: http://jqueryfordesigners.com/
To use the navigationFormatter function, you must have a function that
accepts two paramaters, and returns a string of HTML text.
index = integer index (1 based);
panel = jQuery wrapped LI item this tab references
#return = Must return a string of HTML/Text
navigationFormatter: function(index, panel){
return index + " Panel"; // This would have each tab with the text 'X Panel' where X = index
}
*/
(function($){
$.anythingSlider = function(el, options){
// To avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this;
// Access to jQuery and DOM versions of element
base.$el = $(el);
base.el = el;
// Set up a few defaults
base.currentPage = 1;
base.timer = null;
base.playing = false;
// Add a reverse reference to the DOM object
base.$el.data("AnythingSlider", base);
base.init = function(){
base.options = $.extend({},$.anythingSlider.defaults, options);
// Cache existing DOM elements for later
base.$wrapper = base.$el.find('> div').css('overflow', 'hidden');
base.$slider = base.$wrapper.find('> ul');
base.$items = base.$slider.find('> li');
base.$single = base.$items.filter(':first');
// Build the navigation if needed
if(base.options.buildNavigation) base.buildNavigation();
// Get the details
base.singleWidth = base.$single.outerWidth();
base.pages = base.$items.length;
// Top and tail the list with 'visible' number of items, top has the last section, and tail has the first
// This supports the "infinite" scrolling
base.$items.filter(':first').before(base.$items.filter(':last').clone().addClass('cloned'));
base.$items.filter(':last' ).after(base.$items.filter(':first').clone().addClass('cloned'));
// We just added two items, time to re-cache the list
base.$items = base.$slider.find('> li'); // reselect
// Setup our forward/backward navigation
base.buildNextBackButtons();
// If autoPlay functionality is included, then initialize the settings
if(base.options.autoPlay) {
base.playing = !base.options.startStopped; // Sets the playing variable to false if startStopped is true
base.buildAutoPlay();
};
// If pauseOnHover then add hover effects
if(base.options.pauseOnHover) {
base.$el.hover(function(){
base.clearTimer();
}, function(){
base.startStop(base.playing);
});
}
// If a hash can not be used to trigger the plugin, then go to page 1
if((base.options.hashTags == true && !base.gotoHash()) || base.options.hashTags == false){
base.setCurrentPage(1);
};
};
base.gotoPage = function(page, autoplay){
// When autoplay isn't passed, we stop the timer
if(autoplay !== true) autoplay = false;
if(!autoplay) base.startStop(false);
if(typeof(page) == "undefined" || page == null) {
page = 1;
base.setCurrentPage(1);
};
// Just check for bounds
if(page > base.pages + 1) page = base.pages;
if(page < 0 ) page = 1;
var dir = page < base.currentPage ? -1 : 1,
n = Math.abs(base.currentPage - page),
left = base.singleWidth * dir * n;
base.$wrapper.filter(':not(:animated)').animate({
scrollLeft : '+=' + left
}, base.options.animationTime, base.options.easing, function () {
if (page == 0) {
base.$wrapper.scrollLeft(base.singleWidth * base.pages);
page = base.pages;
} else if (page > base.pages) {
base.$wrapper.scrollLeft(base.singleWidth);
// reset back to start position
page = 1;
};
base.setCurrentPage(page);
});
};
base.setCurrentPage = function(page, move){
// Set visual
if(base.options.buildNavigation){
base.$nav.find('.cur').removeClass('cur');
$(base.$navLinks[page - 1]).addClass('cur');
};
// Only change left if move does not equal false
if(move !== false) base.$wrapper.scrollLeft(base.singleWidth * page);
// Update local variable
base.currentPage = page;
};
base.goForward = function(autoplay){
if(autoplay !== true) autoplay = false;
base.gotoPage(base.currentPage + 1, autoplay);
};
base.goBack = function(){
base.gotoPage(base.currentPage - 1);
};
// This method tries to find a hash that matches panel-X
// If found, it tries to find a matching item
// If that is found as well, then that item starts visible
base.gotoHash = function(){
if(/^#?panel-\d+$/.test(window.location.hash)){
var index = parseInt(window.location.hash.substr(7));
var $item = base.$items.filter(':eq(' + index + ')');
if($item.length != 0){
base.setCurrentPage(index);
return true;
};
};
return false; // A item wasn't found;
};
// Creates the numbered navigation links
base.buildNavigation = function(){
base.$nav = $("<div id='thumbNav'></div>").appendTo(base.$el);
base.$items.each(function(i,el){
var index = i + 1;
var $a = $("<a href='#'></a>");
// If a formatter function is present, use it
if( typeof(base.options.navigationFormatter) == "function"){
$a.html(base.options.navigationFormatter(index, $(this)));
} else {
$a.text(index);
}
$a.click(function(e){
base.gotoPage(index);
if (base.options.hashTags)
base.setHash('panel-' + index);
e.preventDefault();
});
base.$nav.append($a);
});
base.$navLinks = base.$nav.find('> a');
};
// Creates the Forward/Backward buttons
base.buildNextBackButtons = function(){
var $forward = $('<a class="arrow forward">></a>'),
$back = $('<a class="arrow back"><</a>');
// Bind to the forward and back buttons
$back.click(function(e){
base.goBack();
e.preventDefault();
});
$forward.click(function(e){
base.goForward();
e.preventDefault();
});
// Append elements to page
base.$wrapper.after($back).after($forward);
};
// Creates the Start/Stop button
base.buildAutoPlay = function(){
base.$startStop = $("<a href='#' id='start-stop'></a>").html(base.playing ? base.options.stopText : base.options.startText);
base.$el.append(base.$startStop);
base.$startStop.click(function(e){
base.startStop(!base.playing);
e.preventDefault();
});
// Use the same setting, but trigger the start;
base.startStop(base.playing);
};
// Handles stopping and playing the slideshow
// Pass startStop(false) to stop and startStop(true) to play
base.startStop = function(playing){
if(playing !== true) playing = false; // Default if not supplied is false
// Update variable
base.playing = playing;
// Toggle playing and text
base.$startStop.toggleClass("playing", playing).html( playing ? base.options.stopText : base.options.startText );
if(playing){
base.clearTimer(); // Just in case this was triggered twice in a row
base.timer = window.setInterval(function(){
base.goForward(true);
}, base.options.delay);
} else {
base.clearTimer();
};
};
base.clearTimer = function(){
// Clear the timer only if it is set
if(base.timer) window.clearInterval(base.timer);
};
// Taken from AJAXY jquery.history Plugin
base.setHash = function ( hash ) {
// Write hash
if ( typeof window.location.hash !== 'undefined' ) {
if ( window.location.hash !== hash ) {
window.location.hash = hash;
};
} else if ( location.hash !== hash ) {
location.hash = hash;
};
// Done
return hash;
};
// <-- End AJAXY code
// Trigger the initialization
base.init();
};
$.anythingSlider.defaults = {
easing: "swing", // Anything other than "linear" or "swing" requires the easing plugin
autoPlay: true, // This turns off the entire FUNCTIONALY, not just if it starts running or not
startStopped: false, // If autoPlay is on, this can force it to start stopped
delay: 3000, // How long between slide transitions in AutoPlay mode
animationTime: 600, // How long the slide transition takes
hashTags: true, // Should links change the hashtag in the URL?
buildNavigation: true, // If true, builds and list of anchor links to link to each slide
pauseOnHover: true, // If true, and autoPlay is enabled, the show will pause on hover
startText: "Start", // Start text
stopText: "Stop", // Stop text
navigationFormatter: null // Details at the top of the file on this use (advanced use)
};
$.fn.anythingSlider = function(options){
if(typeof(options) == "object"){
return this.each(function(i){
(new $.anythingSlider(this, options));
// This plugin supports multiple instances, but only one can support hash-tag support
// This disables hash-tags on all items but the first one
options.hashTags = false;
});
} else if (typeof(options) == "number") {
return this.each(function(i){
var anySlide = $(this).data('AnythingSlider');
if(anySlide){
anySlide.gotoPage(options);
}
});
}
};
})(jQuery);
// this function wraps the elements in the neccessary tags to work with anything Slider
$ (document).ready(function() {
$('a.slide-link')
.wrap('<li class="slide-list-item"></li>');
$('li.slide-list-item')
.wrapAll('<ul id="slide-list"></ul>');
$('ul#slide-list')
.wrapAll('<div class="wrapper"></div>');
$('div.wrapper')
.wrapAll('<div class="anythingSlider internalSlider"></div>');
$('.anythingSlider')
.anythingSlider({
easing: "swing", // Anything other than "linear" or "swing" requires the easing plugin
autoPlay: true, // This turns off the entire FUNCTIONALY, not just if it starts running or not
startStopped: false, // If autoPlay is on, this can force it to start stopped
delay: 7000, // How long between slide transitions in AutoPlay mode
animationTime: 600, // How long the slide transition takes
hashTags: false, // Should links change the hashtag in the URL?
buildNavigation: true, // If true, builds and list of anchor links to link to each slide
pauseOnHover: true, // If true, and autoPlay is enabled, the show will pause on hover
startText: "Start", // Start text
stopText: "Stop", // Stop text
navigationFormatter: null // Details at the top of the file on this use (advanced use)
});
$('a.slide-link').show();
});
It's a bit of a hash job but works fine as long as there's more than one <li>
Try this:
// this function wraps the elements in the neccessary tags to work with anything Slider
$ (document).ready(function() {
$('a.slide-link')
.wrap('<li class="slide-list-item"></li>');
$('li.slide-list-item')
.wrapAll('<ul id="slide-list"></ul>');
$('ul#slide-list')
.wrapAll('<div class="wrapper"></div>');
$('div.wrapper')
.wrapAll('<div class="anythingSlider internalSlider"></div>');
if(banners.length > 1){
autoplayval= true;
} else {
autoplayval= false;
}
$('.anythingSlider')
.anythingSlider({
easing: "swing", // Anything other than "linear" or "swing" requires the easing plugin
autoPlay: autoplayval, // This turns off the entire FUNCTIONALY, not just if it starts running or not
startStopped: false, // If autoPlay is on, this can force it to start stopped
delay: 7000, // How long between slide transitions in AutoPlay mode
animationTime: 600, // How long the slide transition takes
hashTags: false, // Should links change the hashtag in the URL?
buildNavigation: true, // If true, builds and list of anchor links to link to each slide
pauseOnHover: true, // If true, and autoPlay is enabled, the show will pause on hover
startText: "Start", // Start text
stopText: "Stop", // Stop text
navigationFormatter: null // Details at the top of the file on this use (advanced use)
});
$('a.slide-link').show();
});
Changing this
$('.anythingSlider').anythingSlider({...});
to this
$('.anythingSlider:has(li:nth-child(2)').anythingSlider({...});
should do it
This assumes you don't have nested lists.
I had this problem and could only resolve this with a new version of the plugin: v1.5.3
URL: https://github.com/ProLoser/AnythingSlider/downloads
Once you've got the latest version, only change one line:
base.setCurrentPage(startPanel, false); // added to trigger events for FX code
When I have only one <li> the anythingControls element's style is display=none.
This will only activate the slider if more than 1 <LI> elements are present:
jQuery("#sliderDiv:has(>li:eq(1))").anythingSlider({...})
it assumes your HTML structure is like this:
<div id="sliderDiv">
<li>Offer 1</li>
<li>Offer 2</li>
</div>
You'll need something like
if($([ULELEMENT]).children('li').length > 1){
//Your code
}
Something along those lines. If you post your code, I can give it a try.
I've implemented the AnythingSlider (http://css-tricks.com/anythingslider-jquery-plugin/) using image and video content (videos use the longtail flv player - licensed version 5).
Problem: When the user plays the video, the slideshow doesn't know this has happened, so the slideshow keeps cycling while the video runs. So you have the slideshow running - and user can hear the audio but the video has cycled off.
UPDATE - here is a link to see what's going on: http://silverberry.org/beta/slider-longtail/
I'm trying to figure out an event-listener that will look and see when the LONGTAIL player is in PLAYING state and signals to the AnythingSlider that it needs to STOP.
Here's what I've got so far ... the video player event listeners are working (right now I have alerts popping up so that I can be sure the events are being heard). An alert pops up with the player is initialized .. and alert pops up when we press the PLAY button on the video ... and an alert pops up when the video STOPS playing. But ... I've yet to work out the proper syntax for signaling to the anythingslider to STOP!
I thought it would be this:
$VUslider.startStop(false);
Below is the code I have so far ... beginning with the code that initializes the slider.
function formatText(index, panel) {
return index + "";
}
$(function () {
$('.VUslider').VUslider({
autoPlay: true,
delay: 7000,
startStopped: false,
animationTime: 200,
hashTags: true,
buildNavigation: false,
pauseOnHover: true,
navigationFormatter: formatText
});
});
var player = null;
function playerReadyCallback(obj) {
player = document.getElementsByName(obj.id)[0];
alert('the videoplayer '+obj['id']+' has been instantiated');
player.addModelListener('STATE', 'stateMonitor');
}
function stateMonitor(obj) {
currentState = obj['newstate'];
if(currentState == 'PLAYING') {
alert ('the videoplayer '+obj['id']+' is playing now!');
$VUslider.startStop(false); // Trigger slideshow stop
}
if(obj.newstate == 'COMPLETED') {
alert ('the videoplayer '+obj['id']+' has stopped playing now!');
$VUslider.startStop(true); // Trigger slideshow start
}
}
FOR REFERENCE ... HERE IS THE ANYTHING SLIDER CODE:
(function($){
$.VUslider = function(el, options){
// To avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this;
// Access to jQuery and DOM versions of element
base.$el = $(el);
base.el = el;
// Set up a few defaults
base.currentPage = 1;
base.timer = null;
base.playing = false;
// Add a reverse reference to the DOM object
base.$el.data("AnythingSlider", base);
base.init = function(){
base.options = $.extend({},$.VUslider.defaults, options);
// Cache existing DOM elements for later
base.$wrapper = base.$el.find('> div').css('overflow', 'hidden');
base.$slider = base.$wrapper.find('> ul');
base.$items = base.$slider.find('> li');
base.$single = base.$items.filter(':first');
// Build the navigation if needed
if(base.options.buildNavigation) base.buildNavigation();
// Get the details
base.singleWidth = base.$single.outerWidth();
base.pages = base.$items.length;
// Top and tail the list with 'visible' number of items, top has the last section, and tail has the first
// This supports the "infinite" scrolling
base.$items.filter(':first').before(base.$items.filter(':last').clone().addClass('cloned'));
base.$items.filter(':last' ).after(base.$items.filter(':first').clone().addClass('cloned'));
// We just added two items, time to re-cache the list
base.$items = base.$slider.find('> li'); // reselect
// Setup our forward/backward navigation
base.buildNextBackButtons();
// If autoPlay functionality is included, then initialize the settings
if(base.options.autoPlay) {
base.playing = !base.options.startStopped; // Sets the playing variable to false if startStopped is true
base.buildAutoPlay();
};
// If pauseOnHover then add hover effects
if(base.options.pauseOnHover) {
base.$el.hover(function(){
base.clearTimer();
}, function(){
base.startStop(base.playing);
});
}
// If a hash can not be used to trigger the plugin, then go to page 1
if((base.options.hashTags == true && !base.gotoHash()) || base.options.hashTags == false){
base.setCurrentPage(1);
};
};
base.gotoPage = function(page, autoplay){
// When autoplay isn't passed, we stop the timer
if(autoplay !== true) autoplay = false;
if(!autoplay) base.startStop(false);
if(typeof(page) == "undefined" || page == null) {
page = 1;
base.setCurrentPage(1);
};
// Just check for bounds
if(page > base.pages + 1) page = base.pages;
if(page < 0 ) page = 1;
var dir = page < base.currentPage ? -1 : 1,
n = Math.abs(base.currentPage - page),
left = base.singleWidth * dir * n;
base.$wrapper.filter(':not(:animated)').animate({
scrollLeft : '+=' + left
}, base.options.animationTime, base.options.easing, function () {
if (page == 0) {
base.$wrapper.scrollLeft(base.singleWidth * base.pages);
page = base.pages;
} else if (page > base.pages) {
base.$wrapper.scrollLeft(base.singleWidth);
// reset back to start position
page = 1;
};
base.setCurrentPage(page);
});
};
base.setCurrentPage = function(page, move){
// Set visual
if(base.options.buildNavigation){
base.$nav.find('.cur').removeClass('cur');
$(base.$navLinks[page - 1]).addClass('cur');
};
// Only change left if move does not equal false
if(move !== false) base.$wrapper.scrollLeft(base.singleWidth * page);
// Update local variable
base.currentPage = page;
};
base.goForward = function(autoplay){
if(autoplay !== true) autoplay = false;
base.gotoPage(base.currentPage + 1, autoplay);
};
base.goBack = function(){
base.gotoPage(base.currentPage - 1);
};
// This method tries to find a hash that matches panel-X
// If found, it tries to find a matching item
// If that is found as well, then that item starts visible
base.gotoHash = function(){
if(/^#?panel-\d+$/.test(window.location.hash)){
var index = parseInt(window.location.hash.substr(7));
var $item = base.$items.filter(':eq(' + index + ')');
if($item.length != 0){
base.setCurrentPage(index);
return true;
};
};
return false; // A item wasn't found;
};
// Creates the numbered navigation links
base.buildNavigation = function(){
base.$nav = $("<div id='thumbNav'></div>").appendTo(base.$el);
base.$items.each(function(i,el){
var index = i + 1;
var $a = $("<a href='#'></a>");
// If a formatter function is present, use it
if( typeof(base.options.navigationFormatter) == "function"){
$a.html(base.options.navigationFormatter(index, $(this)));
} else {
$a.text(index);
}
$a.click(function(e){
base.gotoPage(index);
if (base.options.hashTags)
base.setHash('panel-' + index);
e.preventDefault();
});
base.$nav.append($a);
});
base.$navLinks = base.$nav.find('> a');
};
// Creates the Forward/Backward buttons
base.buildNextBackButtons = function(){
var $forward = $('<a class="arrow forward">></a>'),
$back = $('<a class="arrow back"><</a>');
// Bind to the forward and back buttons
$back.click(function(e){
base.goBack();
e.preventDefault();
});
$forward.click(function(e){
base.goForward();
e.preventDefault();
});
// Append elements to page
base.$wrapper.after($back).after($forward);
};
// Creates the Start/Stop button
base.buildAutoPlay = function(){
base.$startStop = $("<a href='#' id='start-stop'></a>").html(base.playing ? base.options.stopText : base.options.startText);
base.$el.append(base.$startStop);
base.$startStop.click(function(e){
base.startStop(!base.playing);
e.preventDefault();
});
// Use the same setting, but trigger the start;
base.startStop(base.playing);
};
// Handles stopping and playing the slideshow
// Pass startStop(false) to stop and startStop(true) to play
base.startStop = function(playing){
if(playing !== true) playing = false; // Default if not supplied is false
// Update variable
base.playing = playing;
// Toggle playing and text
if(base.options.autoPlay) base.$startStop.toggleClass("playing", playing).html( playing ? base.options.stopText : base.options.startText );
if(playing){
base.clearTimer(); // Just in case this was triggered twice in a row
base.timer = window.setInterval(function(){
base.goForward(true);
}, base.options.delay);
} else {
base.clearTimer();
};
};
base.clearTimer = function(){
// Clear the timer only if it is set
if(base.timer) window.clearInterval(base.timer);
};
// Taken from AJAXY jquery.history Plugin
base.setHash = function ( hash ) {
// Write hash
if ( typeof window.location.hash !== 'undefined' ) {
if ( window.location.hash !== hash ) {
window.location.hash = hash;
};
} else if ( location.hash !== hash ) {
location.hash = hash;
};
// Done
return hash;
};
// <-- End AJAXY code
// Trigger the initialization
base.init();
};
$.VUslider.defaults = {
easing: "swing", // Anything other than "linear" or "swing" requires the easing plugin
autoPlay: true, // This turns off the entire FUNCTIONALY, not just if it starts running or not
startStopped: false, // If autoPlay is on, this can force it to start stopped
delay: 3000, // How long between slide transitions in AutoPlay mode
animationTime: 600, // How long the slide transition takes
hashTags: true, // Should links change the hashtag in the URL?
buildNavigation: true, // If true, builds and list of anchor links to link to each slide
pauseOnHover: true, // If true, and autoPlay is enabled, the show will pause on hover
startText: "Start", // Start text
stopText: "Stop", // Stop text
navigationFormatter: null // Details at the top of the file on this use (advanced use)
};
$.fn.VUslider = function(options){
if(typeof(options) == "object"){
return this.each(function(i){
(new $.VUslider(this, options));
// This plugin supports multiple instances, but only one can support hash-tag support
// This disables hash-tags on all items but the first one
options.hashTags = false;
});
} else if (typeof(options) == "number") {
return this.each(function(i){
var anySlide = $(this).data('AnythingSlider');
if(anySlide){
anySlide.gotoPage(options);
}
});
}
};
})(jQuery);
Are you setting $VUslider to equal $('.VUslider').VUslider({ . . }); ?
In your example code you are not.
You should be doing something like this:
$VUslider = $('.VUslider').VUslider({
autoPlay: true,
delay: 7000,
startStopped: false,
animationTime: 200,
hashTags: true,
buildNavigation: false,
pauseOnHover: true,
navigationFormatter: formatText
});
This is somewhat of a stab in the dark, so I'll try to explain my reasoning a bit.
After you've created the VUslider bits as you're already doing, try doing this to start/stop the slider:
$('.VUslider').VUslider.startStop(false);
// this will toggle between starting and stopping but doesn't give control
// to call start or stop specifically.
$('#start-stop').click();
When you call $('.VUslider').VUslider({...}), it doesn't return anything, so there's no handle to VUslider at that point ($.each(..) doesn't return anything). This will hopefully get you a reference to the script and to the startStop function.
HTH