I'm using the plugin smoothstate.js on my website. For some reason, every now and again when I navigate through the pages using the back and forward buttons, the back button stops working.
The URL changes but the content remains the same?
I've checked the console for errors this is displaying:
TypeError: Cannot read property 'state' of undefined
Does anyone know why this is happening? Like I said, the majority of the time it works okay but all of sudden it doesn't.
The code I'm using is like so:
$(function(){
'use strict';
var options = {
prefetch: true,
debug:true,
cacheLength: 0,
repeatDelay: 500,
onStart: {
duration: 0, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onProgress: {
// How long this animation takes
duration: 0,
// A function that dictates the animations that take place
render: function ($container) {
$container.addClass('is-loading');
$('#progressBar').append('<div id="bar"></div>');
var progress = '100%';
$('#bar').animate({
width: progress
}, 400);
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
$container.removeClass('is-loading is-exiting');
// Inject the new content
$container.html($newContent);
},
},
onAfter: function() {
navbarAnimate();
closeMenu();
ImageSliders();
initPhotoSwipeFromDOM('.gallery');
ImageOverlay();
window.parsePinBtns();
backToTop();
}
},
smoothState = $('#main').smoothState(options).data('smoothState');
});
I also ran into this issue which happens when the back and forward buttons are clicked too fast without the page fully loading. A hacky solution for me was to reload the page if page.cache[page.href] is undefined.
/** Handles the popstate event, like when the user hits 'back' */
onPopState = function(e) {
if(e.state !== null || typeof e.state !== undefined) {
var url = window.location.href;
var $page = $('#' + e.state.id);
var page = $page.data('smoothState');
if (typeof(page.cache[page.href]) !== 'undefined') {
var diffUrl = (page.href !== url && !utility.isHash(url, page.href));
var diffState = (e.state !== page.cache[page.href].state);
if(diffUrl || diffState) {
if (diffState) {
page.clear(page.href);
}
page.load(url, false);
}
}
else {
//reload the page if page.cache[page.href] is undefined
location.reload();
}
}
},
Related
Im using django-el-pagination to do lazy loading of entries.
When I click on an entry and then use the browser back button, all of the lazy loading is gone, I tried to add window.history.pushState() but then I only get the current page i.e.?page=4 when I use the browser back button, and all of the entries on top is not loaded.
Is there any way to implement a correct history so that the user is back at the same place when they use the browser back button?
$.endlessPaginate({
paginateOnScroll: true,
paginateOnScrollMargin: 400,
paginateOnScrollChunkSize: 2,
onCompleted: function(context, fragment) {
window.history.pushState(null, null, context.url);
}
});
Edit 1
Here is the JavaScript for the .endlessPaginate function:
'use strict';
(function ($) {
// Fix JS String.trim() function is unavailable in IE<9 #45
if (typeof(String.prototype.trim) === "undefined") {
String.prototype.trim = function() {
return String(this).replace(/^\s+|\s+$/g, '');
};
}
$.fn.endlessPaginate = function(options) {
var defaults = {
// Twitter-style pagination container selector.
containerSelector: '.endless_container',
// Twitter-style pagination loading selector.
loadingSelector: '.endless_loading',
// Twitter-style pagination link selector.
moreSelector: 'a.endless_more',
// Digg-style pagination page template selector.
pageSelector: '.endless_page_template',
// Digg-style pagination link selector.
pagesSelector: 'a.endless_page_link',
// Callback called when the user clicks to get another page.
onClick: function() {},
// Callback called when the new page is correctly displayed.
onCompleted: function() {},
// Set this to true to use the paginate-on-scroll feature.
paginateOnScroll: false,
// If paginate-on-scroll is on, this margin will be used.
paginateOnScrollMargin : 1,
// If paginate-on-scroll is on, it is possible to define chunks.
paginateOnScrollChunkSize: 0
},
settings = $.extend(defaults, options);
var getContext = function(link) {
return {
key: link.attr('rel').split(' ')[0],
url: link.attr('href')
};
};
return this.each(function() {
var element = $(this),
loadedPages = 1;
// Twitter-style pagination.
element.on('click', settings.moreSelector, function() {
var link = $(this),
html_link = link.get(0),
container = link.closest(settings.containerSelector),
loading = container.find(settings.loadingSelector);
// Avoid multiple Ajax calls.
if (loading.is(':visible')) {
return false;
}
link.hide();
loading.show();
var context = getContext(link);
// Fire onClick callback.
if (settings.onClick.apply(html_link, [context]) !== false) {
var data = 'querystring_key=' + context.key;
// Send the Ajax request.
$.get(context.url, data, function(fragment) {
container.before(fragment);
container.remove();
// Increase the number of loaded pages.
loadedPages += 1;
// Fire onCompleted callback.
settings.onCompleted.apply(
html_link, [context, fragment.trim()]);
});
}
return false;
});
// On scroll pagination.
if (settings.paginateOnScroll) {
var win = $(window),
doc = $(document);
doc.scroll(function(){
if (doc.height() - win.height() -
win.scrollTop() <= settings.paginateOnScrollMargin) {
// Do not paginate on scroll if chunks are used and
// the current chunk is complete.
var chunckSize = settings.paginateOnScrollChunkSize;
if (!chunckSize || loadedPages % chunckSize) {
element.find(settings.moreSelector).click();
} else {
element.find(settings.moreSelector).addClass('endless_chunk_complete');
}
}
});
}
// Digg-style pagination.
element.on('click', settings.pagesSelector, function() {
var link = $(this),
html_link = link.get(0),
context = getContext(link);
// Fire onClick callback.
if (settings.onClick.apply(html_link, [context]) !== false) {
var page_template = link.closest(settings.pageSelector),
data = 'querystring_key=' + context.key;
// Send the Ajax request.
page_template.load(context.url, data, function(fragment) {
// Fire onCompleted callback.
settings.onCompleted.apply(
html_link, [context, fragment.trim()]);
});
}
return false;
});
});
};
$.endlessPaginate = function(options) {
return $('body').endlessPaginate(options);
};
})(jQuery);
short answer: no. The whole point of 'endless pagination' is to not reload a (new) page, therefore there is no history.
I'm having an issue with a gallery script I wrote. Basically, there's a set of thumbnails and a large image with arrows. When you click on a thumbnail, the current image fades out, and when the new image loads, it fades in. The issue I'm having is that if you click on a thumbnail or arrow a bunch of times during the transition (as if changing the currently displayed image), the entire process starts to get delayed. The more you click, they more you see the delay.
So say I click five times in the middle of the fade transition. After the current transition finishes, if I click on another thumbnail/arrow the scripts effect doesn't start immediately like it's supposed to, it lags for a few seconds and then starts.
Here's my script:
$(".jTscroller a").click(function(event) {
event.preventDefault();
var last = $("#photo").attr("src");
var target = $(this).attr("href");
if (last != target) {
$("#photo").stop(false,false).fadeTo("fast", 0, function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").fadeTo("fast", 1);
});
});
};
});
$("#photo-area .arrow.left").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof prev != "undefined") {
if (prev != current) {
$("#photo").stop(false,false).fadeTo("fast", 0, function() {
$("#photo").attr("src",prev);
$("#photo").load(function() {
$("#photo").fadeTo("fast");
});
});
};
};
});
$("#photo-area .arrow.right").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof next != "undefined") {
if (next != current) {
$("#photo").stop(false,false).fadeTo("fast", 0, function() {
$("#photo").attr("src",next);
$("#photo").load(function() {
$("#photo").fadeTo("fast", 1);
});
});
};
};
});
JS Fiddle: http://jsfiddle.net/G5VAf/7/
My theory for the fix is to add a Boolean variable that gets changed when the animation completes, but the 50 times I've tried it hasn't worked. Hopefully someone more skilled than me can figure it out.
Oh, and I know I should shrink it down to one smaller script, I'm just trying to get this working before going any farther down that road...
Update: Tried implementing the queue thing mentioned below, and now it won't fade in at all.
$("#photo").animate({
opacity: 0
}, {queue: false, duration: 500}, function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").animate({
opacity: 1
});
});
});
Update 2: figured it out. Final script:
$(document).ready(function() {
$(".jTscroller a").click(function(event) {
event.preventDefault();
var last = $("#photo").attr("src");
var target = $(this).attr("href");
if (last != target) {
$("#photo").stop(false,true).animate({
opacity: 0
}, {queue: false, duration: 500, complete: function() {
$("#photo").attr("src",target);
$("#photo").load(function() {
$("#photo").stop(false,false).animate({
opacity: 1
}, {queue: false, duration: 500});
});
}});
};
});
$("#photo-area .arrow.left").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof prev != "undefined") {
if (prev != current) {
$("#photo").stop(false,true).animate({
opacity: 0
}, {queue: false, duration: 500, complete: function() {
$("#photo").attr("src",prev);
$("#photo").load(function() {
$("#photo").stop(false,false).animate({
opacity: 1
}, {queue: false, duration: 500});
});
}});
};
};
});
$("#photo-area .arrow.right").click(function(event) {
event.preventDefault();
var current = $("#photo-area #photo").attr("src");
var prev = $(".jTscroller a[href=\""+current+"\"]").prev("a").attr("href");
var next = $(".jTscroller a[href=\""+current+"\"]").next("a").attr("href");
if (typeof next != "undefined") {
if (next != current) {
$("#photo").stop(false,true).animate({
opacity: 0
}, {queue: false, duration: 500, complete: function() {
$("#photo").attr("src",next);
$("#photo").load(function() {
$("#photo").stop(false,false).animate({
opacity: 1
}, {queue: false, duration: 500});
});
}});
};
};
});
});
Sounds like you are having problems with the animate queue. The jQuery functions you are using are just shorthand for the .animate() function.
.animate( properties, options )
queue: A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately. As of jQuery 1.7, the queue option can also accept a string, in which case the animation is added to the queue represented by that string.
Basically each click is then getting added to the animate queue hence the delay. You can try the .animate() function and set queue to false and see if that helps.
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 have a simple throbber, that is automatically shown when an ajax request lasts longer than 3 seconds. This throbber consists mainly of an animated GIF-Image.
Now, I want to use the same throbber also for regular links, meaning that when I click a link and it takes the server more than 3 seconds to respond, the throbber is shown.
Unfortunately, it seems that firefox is unable to play the animation, while it is "reloading" the webpage. The javascript is called and fades the throbber correctly in, but is it not spinning.
How can I make firefox play the GIF-Animation while it is loading?
This is the function:
// Throbber manager
function Throbber() { }
Throbber.prototype = {
image : null,
requests : 0,
requestOpened : function(event) {
if (this.requests == 0) {
this.image.src = 'throbber.gif';
}
this.requests++;
},
requestLoaded : function(event) {
this.requests--;
if (this.requests == 0) {
this.image.src = 'throbber_stopped.gif';
}
},
clicked : function() {
request_manager.abortAll();
},
// Called on window load
attach : function() {
this.image = document.getElementById('throbber');
if (this.image && request_manager) {
request_manager.addEventListener('open', [this, this.requestOpened]);
request_manager.addEventListener('load', [this, this.requestLoaded]);
request_manager.addEventListener('abort', [this, this.requestLoaded]);
this.image.onclick = function() { Throbber.prototype.clicked.apply(throbber, arguments); };
}
}
}
var throbber = new Throbber();
window.addEventListener('load', function() { Throbber.prototype.attach.apply(throbber, arguments); }, false);
function SimpleDemo() { }
SimpleDemo.prototype = {
// The AjaxRequest object
request : null,
// Setup and send the request
run : function() {
this.request = request_manager.createAjaxRequest();
this.request.get = {
one : 1,
two : 2
};
this.request.addEventListener('load', [this, this.ran]);
this.request.open('GET', 'xml.php');
var req = requests[this.request.id];
return setTimeout(function() { req.send(); }, 5000);
},
// Triggered when the response returns
ran : function(event) {
alert(event.request.xhr.responseText);
}
}
If you use jQuery:
$("#throbber").show();
/* Your AJAX calls */
$("#throbber").hide();
Check to see when the DOM is ready before calling all your Ajax stuff.
using Prototype:
document.observe("dom:loaded", function() {
//your code
});
using jQuery:
$(document).ready(function() {
//your code
});
Or Refer this: http://plugins.jquery.com/project/throbber
I just tried my old code and found out that this issue does not exist anymore in Firefox 10.0.2
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