Image Carousel Codepen Images not loading - javascript
I have been trying to implement this codepen [https://codepen.io/LokeshNagarajan/pen/apRmZe?editors=1111] on my website but like in the codepen the images do not load even if I assign an https src and i believe the issue stems from the javascript but not sure exactly what to do to fix it.
(function ($) {
'use strict';
$.fn.waterwheelCarousel = function (startingOptions) {
// Adds support for intializing multiple carousels from the same selector group
if (this.length > 1) {
this.each(function () {
$(this).waterwheelCarousel(startingOptions);
});
return this; // allow chaining
}
var carousel = this;
var options = {};
var data = {};
function initializeCarouselData() {
data = {
itemsContainer: $(carousel),
totalItems: $(carousel).children().length,
containerWidth: $(carousel).width(),
containerHeight: $(carousel).height(),
currentCenterItem: null,
previousCenterItem: null,
items: [],
calculations: [],
carouselRotationsLeft: 0,
currentlyMoving: false,
itemsAnimating: 0,
currentSpeed: options.speed,
intervalTimer: null,
currentDirection: 'forward',
leftItemsCount: 0,
rightItemsCount: 0,
performingSetup: true
};
data.itemsContainer.children().removeClass(options.activeClassName);
}
/**
* This function will set the autoplay for the carousel to
* automatically rotate it given the time in the options
* Can clear the autoplay by passing in true
*/
function autoPlay(stop) {
// clear timer
clearTimeout(data.autoPlayTimer);
// as long as no stop command, and autoplay isn't zeroed...
if (!stop && options.autoPlay !== 0) {
// set timer...
data.autoPlayTimer = setTimeout(function () {
// to move the carousl in either direction...
if (options.autoPlay > 0) {
moveOnce('forward');
} else {
moveOnce('backward');
}
}, Math.abs(options.autoPlay));
}
}
/**
* This function will preload all the images in the carousel before
* calling the passed in callback function. This is only used so we can
* properly determine the width and height of the items. This is not needed
* if a user instead manually specifies that information.
*/
function preload(callback) {
var $imageElements = data.itemsContainer.find('img'),
totalImages = $imageElements.length,
loadedImages = 0;
if (options.preloadImages === false || $imageElements.length === 0) {
callback();
return;
}
$imageElements.each(function () {
$(this).bind('load', function () {
// Add to number of images loaded and see if they are all done yet
loadedImages += 1;
if (loadedImages === totalImages) {
// All done, perform callback
callback();
return;
}
});
// May need to manually reset the src to get the load event to fire
// http://stackoverflow.com/questions/7137737/ie9-problems-with-jquery-load-event-not-firing
$(this).attr('src', $(this).attr('src'));
// If browser has cached the images, it may not call trigger a load. Detect this and do it ourselves
if (this.complete) {
$(this).trigger('load');
}
});
}
/**
* Makes a record of the original width and height of all the items in the carousel.
* If we re-intialize the carousel, these values can be used to re-establish their
* original dimensions.
*/
function setOriginalItemDimensions() {
data.itemsContainer.children().each(function () {
if ($(this).data('original_width') == undefined || options.forcedImageWidth > 0) {
$(this).data('original_width', $(this).width());
}
if ($(this).data('original_height') == undefined || options.forcedImageHeight > 0) {
$(this).data('original_height', $(this).height());
}
});
}
/**
* Users can pass in a specific width and height that should be applied to every image.
* While this option can be used in conjunction with the image preloader, the intended
* use case is for when the preloader is turned off and the images don't have defined
* dimensions in CSS. The carousel needs dimensions one way or another to work properly.
*/
function forceImageDimensionsIfEnabled() {
if (options.forcedImageWidth && options.forcedImageHeight) {
data.itemsContainer.children().each(function () {
$(this).width(options.forcedImageWidth);
$(this).height(options.forcedImageHeight);
});
}
}
/**
* For each "visible" item slot (# of flanking items plus the middle),
* we pre-calculate all of the properties that the item should possess while
* occupying that slot. This saves us some time during the actual animation.
*/
function preCalculatePositionProperties() {
// The 0 index is the center item in the carousel
var $firstItem = data.itemsContainer.children().eq(0);
data.calculations[0] = {
distance: 0,
offset: 0,
opacity: 1
}
// Then, for each number of flanking items (plus one more, see below), we
// perform the calcations based on our user options
var horizonOffset = options.horizonOffset;
var separation = options.separation;
for (var i = 1; i <= options.flankingItems + 2; i++) {
if (i > 1) {
horizonOffset *= options.horizonOffsetMultiplier;
separation *= options.separationMultiplier;
}
data.calculations[i] = {
distance: data.calculations[i - 1].distance + separation,
offset: data.calculations[i - 1].offset + horizonOffset,
opacity: data.calculations[i - 1].opacity * options.opacityMultiplier
}
}
// We performed 1 extra set of calculations above so that the items that
// are moving out of sight (based on # of flanking items) gracefully animate there
// However, we need them to animate to hidden, so we set the opacity to 0 for
// that last item
if (options.edgeFadeEnabled) {
data.calculations[options.flankingItems + 1].opacity = 0;
} else {
data.calculations[options.flankingItems + 1] = {
distance: 0,
offset: 0,
opacity: 0
}
}
}
/**
* Here we prep the carousel and its items, like setting default CSS
* attributes. All items start in the middle position by default
* and will "fan out" from there during the first animation
*/
function setupCarousel() {
// Fill in a data array with jQuery objects of all the images
data.items = data.itemsContainer.children();
for (var i = 0; i < data.totalItems; i++) {
data.items[i] = $(data.items[i]);
}
// May need to set the horizon if it was set to auto
if (options.horizon === 0) {
if (options.orientation === 'horizontal') {
options.horizon = data.containerHeight / 2;
} else {
options.horizon = data.containerWidth / 2;
}
}
// Default all the items to the center position
data.itemsContainer
.css('position', 'relative')
.children()
.each(function () {
// Figure out where the top and left positions for center should be
var centerPosLeft, centerPosTop;
if (options.orientation === 'horizontal') {
centerPosLeft = (data.containerWidth / 2) - ($(this).data('original_width') / 2);
centerPosTop = options.horizon - ($(this).data('original_height') / 2);
} else {
centerPosLeft = options.horizon - ($(this).data('original_width') / 2);
centerPosTop = (data.containerHeight / 2) - ($(this).data('original_height') / 2);
}
$(this)
// Apply positioning and layering to the images
.css({
'left': centerPosLeft,
'top': centerPosTop,
'visibility': 'visible',
'position': 'absolute',
'z-index': 0,
'opacity': 0
})
// Give each image a data object so it remembers specific data about
// it's original form
.data({
top: centerPosTop,
left: centerPosLeft,
oldPosition: 0,
currentPosition: 0,
depth: 0,
opacity: 0
})
// The image has been setup... Now we can show it
.show();
});
}
/**
* All the items to the left and right of the center item need to be
* animated to their starting positions. This function will
* figure out what items go where and will animate them there
*/
function setupStarterRotation() {
options.startingItem = (options.startingItem === 0) ? Math.round(data.totalItems / 2) : options.startingItem;
data.rightItemsCount = Math.ceil((data.totalItems - 1) / 2);
data.leftItemsCount = Math.floor((data.totalItems - 1) / 2);
// We are in effect rotating the carousel, so we need to set that
data.carouselRotationsLeft = 1;
// Center item
moveItem(data.items[options.startingItem - 1], 0);
data.items[options.startingItem - 1].css('opacity', 1);
// All the items to the right of center
var itemIndex = options.startingItem - 1;
for (var pos = 1; pos <= data.rightItemsCount; pos++) {
(itemIndex < data.totalItems - 1) ? itemIndex += 1 : itemIndex = 0;
data.items[itemIndex].css('opacity', 1);
moveItem(data.items[itemIndex], pos);
}
// All items to left of center
var itemIndex = options.startingItem - 1;
for (var pos = -1; pos >= data.leftItemsCount * -1; pos--) {
(itemIndex > 0) ? itemIndex -= 1 : itemIndex = data.totalItems - 1;
data.items[itemIndex].css('opacity', 1);
moveItem(data.items[itemIndex], pos);
}
}
/**
* Given the item and position, this function will calculate the new data
* for the item. One the calculations are done, it will store that data in
* the items data object
*/
function performCalculations($item, newPosition) {
var newDistanceFromCenter = Math.abs(newPosition);
// Distance to the center
if (newDistanceFromCenter < options.flankingItems + 1) {
var calculations = data.calculations[newDistanceFromCenter];
} else {
var calculations = data.calculations[options.flankingItems + 1];
}
var distanceFactor = Math.pow(options.sizeMultiplier, newDistanceFromCenter)
var newWidth = distanceFactor * $item.data('original_width');
var newHeight = distanceFactor * $item.data('original_height');
var widthDifference = Math.abs($item.width() - newWidth);
var heightDifference = Math.abs($item.height() - newHeight);
var newOffset = calculations.offset
var newDistance = calculations.distance;
if (newPosition < 0) {
newDistance *= -1;
}
if (options.orientation == 'horizontal') {
var center = data.containerWidth / 2;
var newLeft = center + newDistance - (newWidth / 2);
var newTop = options.horizon - newOffset - (newHeight / 2);
} else {
var center = data.containerHeight / 2;
var newLeft = options.horizon - newOffset - (newWidth / 2);
var newTop = center + newDistance - (newHeight / 2);
}
newTop -= heightDifference / 2;
newLeft -= widthDifference / 2;
var newOpacity;
if (newPosition === 0) {
newOpacity = 1;
} else {
newOpacity = calculations.opacity;
}
// Depth will be reverse distance from center
var newDepth = options.flankingItems + 2 - newDistanceFromCenter;
$item.data('width', newWidth);
$item.data('height', newHeight);
$item.data('top', newTop);
$item.data('left', newLeft);
$item.data('oldPosition', $item.data('currentPosition'));
$item.data('depth', newDepth);
$item.data('opacity', newOpacity);
$item.data('distanceFactor', distanceFactor);
}
function moveItem($item, newPosition) {
// Only want to physically move the item if it is within the boundaries
// or in the first position just outside either boundary
if (Math.abs(newPosition) <= options.flankingItems + 1) {
performCalculations($item, newPosition);
data.itemsAnimating++;
$item
.css('z-index', $item.data().depth)
// Animate the items to their new position values
.animate({
'left': $item.data().left,
'top': $item.data().top,
'opacity': $item.data().opacity
}, data.currentSpeed, options.animationEasing, function () {
// Animation for the item has completed, call method
itemAnimationComplete($item, newPosition);
});
TweenMax.to($item, data.currentSpeed / 1000, {
scaleX: $item.data('distanceFactor'),
scaleY: $item.data('distanceFactor'),
ease: options.animationEasing
});
} else {
$item.data('currentPosition', newPosition)
// Move the item to the 'hidden' position if hasn't been moved yet
// This is for the intitial setup
if ($item.data('oldPosition') === 0) {
$item
.css({
'left': $item.data().left,
'top': $item.data().top,
'opacity': $item.data().opacity,
'z-index': $item.data().depth
});
TweenMax.to($item, 0, {
scaleX: $item.data('distanceFactor'),
scaleY: $item.data('distanceFactor')
});
}
}
}
/**
* This function is called once an item has finished animating to its
* given position. Several different statements are executed here, such as
* dealing with the animation queue
*/
function itemAnimationComplete($item, newPosition) {
data.itemsAnimating--;
$item.data('currentPosition', newPosition);
// Keep track of what items came and left the center position,
// so we can fire callbacks when all the rotations are completed
if (newPosition === 0) {
data.currentCenterItem = $item;
}
// all items have finished their rotation, lets clean up
if (data.itemsAnimating === 0) {
data.carouselRotationsLeft -= 1;
data.currentlyMoving = false;
// If there are still rotations left in the queue, rotate the carousel again
// we pass in zero because we don't want to add any additional rotations
if (data.carouselRotationsLeft > 0) {
rotateCarousel(0);
// Otherwise there are no more rotations and...
} else {
// Reset the speed of the carousel to original
data.currentSpeed = options.speed;
data.currentCenterItem.addClass(options.activeClassName);
if (data.performingSetup === false) {
options.movedToCenter(data.currentCenterItem);
options.movedFromCenter(data.previousCenterItem);
}
data.performingSetup = false;
// reset & initate the autoPlay
autoPlay();
}
}
}
/**
* Function called to rotate the carousel the given number of rotations
* in the given direciton. Will check to make sure the carousel should
* be able to move, and then adjust speed and move items
*/
function rotateCarousel(rotations) {
// Check to see that a rotation is allowed
if (data.currentlyMoving === false) {
// Remove active class from the center item while we rotate
data.currentCenterItem.removeClass(options.activeClassName);
data.currentlyMoving = true;
data.itemsAnimating = 0;
data.carouselRotationsLeft += rotations;
if (options.quickerForFurther === true) {
// Figure out how fast the carousel should rotate
if (rotations > 1) {
data.currentSpeed = options.speed / rotations;
}
// Assure the speed is above the minimum to avoid weird results
data.currentSpeed = (data.currentSpeed < 100) ? 100 : data.currentSpeed;
}
// Iterate thru each item and move it
for (var i = 0; i < data.totalItems; i++) {
var $item = $(data.items[i]);
var currentPosition = $item.data('currentPosition');
var newPosition;
if (data.currentDirection == 'forward') {
newPosition = currentPosition - 1;
} else {
newPosition = currentPosition + 1;
}
// We keep both sides as even as possible to allow circular rotation to work.
// We will "wrap" the item arround to the other side by negating its current position
var flankingAllowance = (newPosition > 0) ? data.rightItemsCount : data.leftItemsCount;
if (Math.abs(newPosition) > flankingAllowance) {
newPosition = currentPosition * -1;
// If there's an uneven number of "flanking" items, we need to compenstate for that
// when we have an item switch sides. The right side will always have 1 more in that case
if (data.totalItems % 2 == 0) {
newPosition += 1;
}
}
moveItem($item, newPosition);
}
}
}
/**
* The event handler when an image within the carousel is clicked
* This function will rotate the carousel the correct number of rotations
* to get the clicked item to the center, or will fire the custom event
* the user passed in if the center item is clicked
*/
$(this).children().bind("click", function () {
var itemPosition = $(this).data().currentPosition;
if (options.imageNav == false) {
return;
}
// Don't allow hidden items to be clicked
if (Math.abs(itemPosition) >= options.flankingItems + 1) {
return;
}
// Do nothing if the carousel is already moving
if (data.currentlyMoving) {
return;
}
data.previousCenterItem = data.currentCenterItem;
// Remove autoplay
autoPlay(true);
options.autoPlay = 0;
var rotations = Math.abs(itemPosition);
if (itemPosition == 0) {
options.clickedCenter($(this));
} else {
// Fire the 'moving' callbacks
options.movingFromCenter(data.currentCenterItem);
options.movingToCenter($(this));
if (itemPosition < 0) {
data.currentDirection = 'backward';
rotateCarousel(rotations);
} else if (itemPosition > 0) {
data.currentDirection = 'forward';
rotateCarousel(rotations);
}
}
});
function nextItemFromCenter() {
var $next = data.currentCenterItem.next();
if ($next.length <= 0) {
$next = data.currentCenterItem.parent().children().first();
}
return $next;
}
function prevItemFromCenter() {
var $prev = data.currentCenterItem.prev();
if ($prev.length <= 0) {
$prev = data.currentCenterItem.parent().children().last();
}
return $prev;
}
/**
* Intiate a move of the carousel in either direction. Takes care of firing
* the 'moving' callbacks
*/
function moveOnce(direction) {
if (data.currentlyMoving === false) {
data.previousCenterItem = data.currentCenterItem;
options.movingFromCenter(data.currentCenterItem);
if (direction == 'backward') {
options.movingToCenter(prevItemFromCenter());
data.currentDirection = 'backward';
} else if (direction == 'forward') {
options.movingToCenter(nextItemFromCenter());
data.currentDirection = 'forward';
}
}
rotateCarousel(1);
}
/**
* Navigation with arrow keys
*/
$(document).keydown(function (e) {
if (options.keyboardNav) {
// arrow left or up
if ((e.which === 37 && options.orientation == 'horizontal') || (e.which === 38 && options.orientation == 'vertical')) {
autoPlay(true);
options.autoPlay = 0;
moveOnce('backward');
// arrow right or down
} else if ((e.which === 39 && options.orientation == 'horizontal') || (e.which === 40 && options.orientation == 'vertical')) {
autoPlay(true);
options.autoPlay = 0;
moveOnce('forward');
}
// should we override the normal functionality for the arrow keys?
if (options.keyboardNavOverride && (
(options.orientation == 'horizontal' && (e.which === 37 || e.which === 39)) ||
(options.orientation == 'vertical' && (e.which === 38 || e.which === 40))
)) {
e.preventDefault();
return false;
}
}
});
/**
* Public API methods
*/
this.reload = function (newOptions) {
if (typeof newOptions === "object") {
var combineDefaultWith = newOptions;
} else {
var combineDefaultWith = {};
}
options = $.extend({}, $.fn.waterwheelCarousel.defaults, newOptions);
initializeCarouselData();
data.itemsContainer.children().hide();
forceImageDimensionsIfEnabled();
preload(function () {
setOriginalItemDimensions();
preCalculatePositionProperties();
setupCarousel();
setupStarterRotation();
});
}
this.next = function () {
autoPlay(true);
options.autoPlay = 0;
moveOnce('forward');
}
this.prev = function () {
autoPlay(true);
options.autoPlay = 0;
moveOnce('backward');
}
this.reload(startingOptions);
return this;
};
$.fn.waterwheelCarousel.defaults = {
// number tweeks to change apperance
startingItem: 1, // item to place in the center of the carousel. Set to 0 for auto
separation: 175, // distance between items in carousel
separationMultiplier: 0.6, // multipled by separation distance to increase/decrease distance for each additional item
horizonOffset: 0, // offset each item from the "horizon" by this amount (causes arching)
horizonOffsetMultiplier: 1, // multipled by horizon offset to increase/decrease offset for each additional item
sizeMultiplier: 0.7, // determines how drastically the size of each item changes
opacityMultiplier: 0.8, // determines how drastically the opacity of each item changes
horizon: 0, // how "far in" the horizontal/vertical horizon should be set from the container wall. 0 for auto
flankingItems: 3, // the number of items visible on either side of the center
// animation
speed: 300, // speed in milliseconds it will take to rotate from one to the next
animationEasing: 'linear', // the easing effect to use when animating
quickerForFurther: true, // set to true to make animations faster when clicking an item that is far away from the center
edgeFadeEnabled: false, // when true, items fade off into nothingness when reaching the edge. false to have them move behind the center image
// misc
linkHandling: 2, // 1 to disable all (used for facebox), 2 to disable all but center (to link images out)
autoPlay: 0, // indicate the speed in milliseconds to wait before autorotating. 0 to turn off. Can be negative
orientation: 'horizontal', // indicate if the carousel should be 'horizontal' or 'vertical'
activeClassName: 'carousel-center', // the name of the class given to the current item in the center
keyboardNav: false, // set to true to move the carousel with the arrow keys
keyboardNavOverride: true, // set to true to override the normal functionality of the arrow keys (prevents scrolling)
imageNav: true, // clicking a non-center image will rotate that image to the center
// preloader
preloadImages: true, // disable/enable the image preloader.
forcedImageWidth: 0, // specify width of all images; otherwise the carousel tries to calculate it
forcedImageHeight: 0, // specify height of all images; otherwise the carousel tries to calculate it
// callback functions
movingToCenter: $.noop, // fired when an item is about to move to the center position
movedToCenter: $.noop, // fired when an item has finished moving to the center
clickedCenter: $.noop, // fired when the center item has been clicked
movingFromCenter: $.noop, // fired when an item is about to leave the center position
movedFromCenter: $.noop // fired when an item has finished moving from the center
};
})(jQuery);
/*--water_wheel_carousel--*/
var carousel = $("#carousel").waterwheelCarousel({
flankingItems: 2,
separation:200,
sizeMultiplier:0.8,
separationMultiplier:0.9,
speed:250,
});
$("#carousel").swipe( {
swipeStatus:function(event, phase, direction, distance)
{
if (phase=="end"){
if(direction == "right") {
carousel.prev();
}
else if(direction =="left") {
carousel.next();
}else { return false;}
}
},
triggerOnTouchEnd:false,
threshold:100
});
$('#prev').on('click', function (){
carousel.prev();
return false;
});
$('#next').on('click', function (){
carousel.next();
return false;
});
/*--water_wheel carousel_script_end--*/
Kindly help me fix the javascript so as to apply the solution to my code. Thanks
Your images are loading, but there are DIVs with a white background on top of them that are visually blocking the images. If you remove the background-color CSS declaration on those DIVs, then your images will show up. Just update this:
#carousel .caption {
position: absolute;
background-color:#FFF;
top: 0px;
left: 0px;
height:100%;
width:100%;
}
to this:
#carousel .caption {
position: absolute;
top: 0px;
left: 0px;
height:100%;
width:100%;
}
Related
Button for smooth scrolling
I am doing a button for smooth scrolling to the bottom of the page. The button is working, but without the smooth animation. Does someone have an idea, what I am doing wrong? The same kind of code for button to top is working fine. I need to do this without CSS "smooth". document.getElementById("buttondown").onclick = function() { scrollTo(5555550, 2000); } // Element or Position to move + Time in ms (milliseconds) function scrollTo(element, duration) { var rootelement = document.documentElement; if (rootelement.scrollTop === 0) { var up = rootelement.scrollTop; ++rootelement.scrollTop; rootelement = up + 1 === rootelement.scrollTop-- ? rootelement : document.body; } scrollToC(rootelement, rootelement.scrollTop, element, duration); } // Element to move, element or px from, element or px to, time in ms to animate function scrollToC(element, from, to, duration) { if (duration <= 0) return; if (typeof from === "object") from = from.offsetTop; if (typeof to === "object") to = to.offsetTop; scrollToX(element, from, to, 0, 1 / duration, 20, easeOutCuaic); } function scrollToX(element, xFrom, xTo, t01, speed, step, motion) { if (t01 < 0 || t01 > 1 || speed <= 0) { element.scrollTop = xTo; return; } element.scrollTop = xFrom - (xFrom - xTo) * motion(t01); t01 += speed * step; debugger; setTimeout(function() { scrollToX(element, xFrom, xTo, t01, speed, step, motion); }, step); } function easeOutCuaic(t) { t--; return t * t * t + 1; }
You can add smooth behaviour to the function: document.getElementById("buttondown").onclick = function() { window.scrollTo({ top: 100, left: 100, behavior: 'smooth' }); }
Slider navigation dots not getting highlighted
My slider is partly made of dots indicating which slide is active. So when a slide gets activated, its associated dot should become blue. But I could not get the last (third) dot to be highlighted when its slide is comes in. Can anybody help me sort things out? Thank you. My code so far: var prevDot = 0; function init() { var elem = document.getElementById('mySwipe'); window.mySwipe = Swipe(elem, { // startSlide: 4, // auto: 3000, // continuous: true, // disableScroll: true, // stopPropagation: true, // callback: function(index, element) {}, transitionEnd: function(index, element) { $(".swipeDot").find("li").eq(prevDot).removeClass("dot_select"); prevDot = (index == 0 || index == 2) ? 0 : 1; $(".swipeDot").find("li").eq(prevDot).addClass("dot_select"); console.log(index); } }); //$(".swipe-wrap").find("div").eq(2).find("span").css({backgroundImage:"url('../images/p006_img_2.png')"}) $("#prevBtn").click(function() { window.mySwipe.prev(); }); $("#nextBtn").click(function() { window.mySwipe.next(); }); $(".swipeDot li").each(function(index) { $(this).attr("slideIndex", index); }); $(".swipeDot li").click(function() { var slideIndex = $(this).attr("slideIndex"); window.mySwipe.slide(slideIndex); }); } $(document).ready(init); function Swipe(container, options) { console.log(container); "use strict"; // utilities var noop = function() {}; // simple no operation function var offloadFn = function(fn) { setTimeout(fn || noop, 0) }; // offload a functions execution // check browser capabilities var browser = { addEventListener: !!window.addEventListener, touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch, transitions: (function(temp) { var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition']; for (var i in props) if (temp.style[props[i]] !== undefined) return true; return false; })(document.createElement('swipe')) }; // quit if no root element if (!container) return; var element = container.children[0]; var slides, slidePos, width, length; options = options || {}; var index = parseInt(options.startSlide, 10) || 0; var speed = options.speed || 300; options.continuous = options.continuous !== undefined ? options.continuous : true; function setup() { // cache slides slides = element.children; length = slides.length; // set continuous to false if only one slide if (slides.length < 2) options.continuous = false; //special case if two slides if (browser.transitions && options.continuous && slides.length < 3) { element.appendChild(slides[0].cloneNode(true)); element.appendChild(element.children[1].cloneNode(true)); slides = element.children; } // create an array to store current positions of each slide slidePos = new Array(slides.length); // determine width of each slide width = container.offsetWidth; element.style.width = (slides.length * width) + 'px'; // stack elements var pos = slides.length; while (pos--) { var slide = slides[pos]; slide.style.width = width + 'px'; slide.setAttribute('data-index', pos); if (browser.transitions) { slide.style.left = (pos * -width) + 'px'; move(pos, index > pos ? -width : (index < pos ? width : 0), 0); } } // reposition elements before and after index if (options.continuous && browser.transitions) { move(circle(index - 1), -width, 0); move(circle(index + 1), width, 0); } if (!browser.transitions) element.style.left = (index * -width) + 'px'; container.style.visibility = 'visible'; } function prev() { if (options.continuous) slide(index - 1); else if (index) slide(index - 1); } function next() { if (options.continuous) slide(index + 1); else if (index < slides.length - 1) slide(index + 1); } function circle(index) { // a simple positive modulo using slides.length return (slides.length + (index % slides.length)) % slides.length; } function slide(to, slideSpeed) { // do nothing if already on requested slide if (index == to) return; if (browser.transitions) { var direction = Math.abs(index - to) / (index - to); // 1: backward, -1: forward // get the actual position of the slide if (options.continuous) { var natural_direction = direction; direction = -slidePos[circle(to)] / width; // if going forward but to < index, use to = slides.length + to // if going backward but to > index, use to = -slides.length + to if (direction !== natural_direction) to = -direction * slides.length + to; } var diff = Math.abs(index - to) - 1; // move all the slides between index and to in the right direction while (diff--) move(circle((to > index ? to : index) - diff - 1), width * direction, 0); to = circle(to); move(index, width * direction, slideSpeed || speed); move(to, 0, slideSpeed || speed); if (options.continuous) move(circle(to - direction), -(width * direction), 0); // we need to get the next in place } else { to = circle(to); animate(index * -width, to * -width, slideSpeed || speed); //no fallback for a circular continuous if the browser does not accept transitions } index = to; offloadFn(options.callback && options.callback(index, slides[index])); } function move(index, dist, speed) { translate(index, dist, speed); slidePos[index] = dist; } function translate(index, dist, speed) { var slide = slides[index]; var style = slide && slide.style; if (!style) return; style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = speed + 'ms'; style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)'; style.msTransform = style.MozTransform = style.OTransform = 'translateX(' + dist + 'px)'; } function animate(from, to, speed) { // if not an animation, just reposition if (!speed) { element.style.left = to + 'px'; return; } var start = +new Date; var timer = setInterval(function() { var timeElap = +new Date - start; if (timeElap > speed) { element.style.left = to + 'px'; if (delay) begin(); options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); clearInterval(timer); return; } element.style.left = (((to - from) * (Math.floor((timeElap / speed) * 100) / 100)) + from) + 'px'; }, 4); } // setup auto slideshow var delay = options.auto || 0; var interval; function begin() { interval = setTimeout(next, delay); } function stop() { delay = 0; clearTimeout(interval); } // setup initial vars var start = {}; var delta = {}; var isScrolling; // setup event capturing var events = { handleEvent: function(event) { switch (event.type) { case 'touchstart': this.start(event); break; case 'touchmove': this.move(event); break; case 'touchend': offloadFn(this.end(event)); break; case 'webkitTransitionEnd': case 'msTransitionEnd': case 'oTransitionEnd': case 'otransitionend': case 'transitionend': offloadFn(this.transitionEnd(event)); break; case 'resize': offloadFn(setup); break; } if (options.stopPropagation) event.stopPropagation(); }, start: function(event) { var touches = event.touches[0]; // measure start values start = { // get initial touch coords x: touches.pageX, y: touches.pageY, // store time to determine touch duration time: +new Date }; // used for testing first move event isScrolling = undefined; // reset delta and end measurements delta = {}; // attach touchmove and touchend listeners element.addEventListener('touchmove', this, false); element.addEventListener('touchend', this, false); }, move: function(event) { // ensure swiping with one touch and not pinching if (event.touches.length > 1 || event.scale && event.scale !== 1) return if (options.disableScroll) event.preventDefault(); var touches = event.touches[0]; // measure change in x and y delta = { x: touches.pageX - start.x, y: touches.pageY - start.y } // determine if scrolling test has run - one time test if (typeof isScrolling == 'undefined') { isScrolling = !!(isScrolling || Math.abs(delta.x) < Math.abs(delta.y)); } // if user is not trying to scroll vertically if (!isScrolling) { // prevent native scrolling event.preventDefault(); // stop slideshow stop(); // increase resistance if first or last slide if (options.continuous) { // we don't add resistance at the end translate(circle(index - 1), delta.x + slidePos[circle(index - 1)], 0); translate(index, delta.x + slidePos[index], 0); translate(circle(index + 1), delta.x + slidePos[circle(index + 1)], 0); } else { delta.x = delta.x / ((!index && delta.x > 0 // if first slide and sliding left || index == slides.length - 1 // or if last slide and sliding right && delta.x < 0 // and if sliding at all ) ? (Math.abs(delta.x) / width + 1) // determine resistance level : 1); // no resistance if false // translate 1:1 translate(index - 1, delta.x + slidePos[index - 1], 0); translate(index, delta.x + slidePos[index], 0); translate(index + 1, delta.x + slidePos[index + 1], 0); } } }, end: function(event) { // measure duration var duration = +new Date - start.time; // determine if slide attempt triggers next/prev slide var isValidSlide = Number(duration) < 250 // if slide duration is less than 250ms && Math.abs(delta.x) > 20 // and if slide amt is greater than 20px || Math.abs(delta.x) > width / 2; // or if slide amt is greater than half the width // determine if slide attempt is past start and end var isPastBounds = !index && delta.x > 0 // if first slide and slide amt is greater than 0 || index == slides.length - 1 && delta.x < 0; // or if last slide and slide amt is less than 0 if (options.continuous) isPastBounds = false; // determine direction of swipe (true:right, false:left) var direction = delta.x < 0; // if not scrolling vertically if (!isScrolling) { if (isValidSlide && !isPastBounds) { if (direction) { if (options.continuous) { // we need to get the next in this direction in place move(circle(index - 1), -width, 0); move(circle(index + 2), width, 0); } else { move(index - 1, -width, 0); } move(index, slidePos[index] - width, speed); move(circle(index + 1), slidePos[circle(index + 1)] - width, speed); index = circle(index + 1); } else { if (options.continuous) { // we need to get the next in this direction in place move(circle(index + 1), width, 0); move(circle(index - 2), -width, 0); } else { move(index + 1, width, 0); } move(index, slidePos[index] + width, speed); move(circle(index - 1), slidePos[circle(index - 1)] + width, speed); index = circle(index - 1); } options.callback && options.callback(index, slides[index]); } else { if (options.continuous) { move(circle(index - 1), -width, speed); move(index, 0, speed); move(circle(index + 1), width, speed); } else { move(index - 1, -width, speed); move(index, 0, speed); move(index + 1, width, speed); } } } // kill touchmove and touchend event listeners until touchstart called again element.removeEventListener('touchmove', events, false) element.removeEventListener('touchend', events, false) }, transitionEnd: function(event) { if (parseInt(event.target.getAttribute('data-index'), 10) == index) { if (delay) begin(); options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); } } } // trigger setup setup(); // start auto slideshow if applicable if (delay) begin(); // add event listeners if (browser.addEventListener) { // set touchstart event on element if (browser.touch) element.addEventListener('touchstart', events, false); if (browser.transitions) { element.addEventListener('webkitTransitionEnd', events, false); element.addEventListener('msTransitionEnd', events, false); element.addEventListener('oTransitionEnd', events, false); element.addEventListener('otransitionend', events, false); element.addEventListener('transitionend', events, false); } // set resize event on window window.addEventListener('resize', events, false); } else { window.onresize = function() { setup() }; // to play nice with old IE } // expose the Swipe API return { setup: function() { setup(); }, slide: function(to, speed) { // cancel slideshow stop(); slide(to, speed); }, prev: function() { // cancel slideshow stop(); prev(); }, next: function() { // cancel slideshow stop(); next(); }, stop: function() { // cancel slideshow stop(); }, getPos: function() { // return current index position return index; }, getNumSlides: function() { // return total number of slides return length; }, kill: function() { // cancel slideshow stop(); // reset element element.style.width = ''; element.style.left = ''; // reset slides var pos = slides.length; while (pos--) { var slide = slides[pos]; slide.style.width = ''; slide.style.left = ''; if (browser.transitions) translate(pos, 0, 0); } // removed event listeners if (browser.addEventListener) { // remove current event listeners element.removeEventListener('touchstart', events, false); element.removeEventListener('webkitTransitionEnd', events, false); element.removeEventListener('msTransitionEnd', events, false); element.removeEventListener('oTransitionEnd', events, false); element.removeEventListener('otransitionend', events, false); element.removeEventListener('transitionend', events, false); window.removeEventListener('resize', events, false); } else { window.onresize = null; } } } } if (window.jQuery || window.Zepto) { (function($) { $.fn.Swipe = function(params) { return this.each(function() { $(this).data('Swipe', new Swipe($(this)[0], params)); }); } })(window.jQuery || window.Zepto) } ul, li{display: inline-block; list-style:none} li, .swipeBtn{cursor: pointer} li+li{margin-left:10px} li::before {content:'●'; color:grey} .dot_select::before{color: blue} #mySwipe{overflow: hidden} <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="swipeBtn hotspot hspot cElement" id="prevBtn">❰</div> <div id='mySwipe' style='width:600px;margin:0 auto' class='swipe hotspot hspot cElement'> <div class='swipe-wrap'> <div><span id="slide1">---- SLIDE1 ----</span></div> <div><span id="slide2">---- SLIDE2 ----</span></div> <div><span id="slide3">---- SLIDE3 ----</span></div> </div> </div> <div class="swipeBtn hotspot hspot cElement" id="nextBtn">❱</div> <ul class="swipeDot"> <li class="dot_select"></li> <li ></li> <li></li> </ul>
Added the next lines prevDot=index; $(".swipeDot").find("li").eq(index).addClass("dot_select"); This will save the value of the active dot. The second line is yours but i just change the eq(prevdot) to eq(index) Fior the problem stated in the comments. I debbuged the code and found the error on line 174 of the js. U had if (direction !== natural_direction) to= -direction * slides.length + to; This line changed the value of to before it ended the operation and returned rubbish. So i just changed the to var for newTo and works fine. This is a debbuge of a long script. There might be a better solution but this is the one i got. Hope this is what you were looking for. Happy to explain or help in a better solution if needed. var prevDot = 0; function init() { var elem = document.getElementById('mySwipe'); window.mySwipe = Swipe(elem, { // startSlide: 4, // auto: 3000, // continuous: true, // disableScroll: true, // stopPropagation: true, // callback: function(index, element) {}, transitionEnd: function(index, element) { $(".swipeDot").find("li").eq(prevDot).removeClass("dot_select"); prevDot = (index == 0 || index == 2) ? 0 : 1; prevDot=index; $(".swipeDot").find("li").eq(index).addClass("dot_select"); console.log(index); } }); //$(".swipe-wrap").find("div").eq(2).find("span").css({backgroundImage:"url('../images/p006_img_2.png')"}) $("#prevBtn").click(function() { window.mySwipe.prev(); }); $("#nextBtn").click(function() { window.mySwipe.next(); }); $(".swipeDot li").each(function(index) { $(this).attr("slideIndex", index); }); $(".swipeDot li").click(function() { var slideIndex = $(this).attr("slideIndex"); window.mySwipe.slide(slideIndex); }); } $(document).ready(init); function Swipe(container, options) { console.log(container); "use strict"; // utilities var noop = function() {}; // simple no operation function var offloadFn = function(fn) { setTimeout(fn || noop, 0) }; // offload a functions execution // check browser capabilities var browser = { addEventListener: !!window.addEventListener, touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch, transitions: (function(temp) { var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition']; for (var i in props) if (temp.style[props[i]] !== undefined) return true; return false; })(document.createElement('swipe')) }; // quit if no root element if (!container) return; var element = container.children[0]; var slides, slidePos, width, length; options = options || {}; var index = parseInt(options.startSlide, 10) || 0; var speed = options.speed || 300; options.continuous = options.continuous !== undefined ? options.continuous : true; function setup() { // cache slides slides = element.children; length = slides.length; // set continuous to false if only one slide if (slides.length < 2) options.continuous = false; //special case if two slides if (browser.transitions && options.continuous && slides.length < 3) { element.appendChild(slides[0].cloneNode(true)); element.appendChild(element.children[1].cloneNode(true)); slides = element.children; } // create an array to store current positions of each slide slidePos = new Array(slides.length); // determine width of each slide width = container.offsetWidth; element.style.width = (slides.length * width) + 'px'; // stack elements var pos = slides.length; while (pos--) { var slide = slides[pos]; slide.style.width = width + 'px'; slide.setAttribute('data-index', pos); if (browser.transitions) { slide.style.left = (pos * -width) + 'px'; move(pos, index > pos ? -width : (index < pos ? width : 0), 0); } } // reposition elements before and after index if (options.continuous && browser.transitions) { move(circle(index - 1), -width, 0); move(circle(index + 1), width, 0); } if (!browser.transitions) element.style.left = (index * -width) + 'px'; container.style.visibility = 'visible'; } function prev() { if (options.continuous) slide(index - 1); else if (index) slide(index - 1); } function next() { if (options.continuous) slide(index + 1); else if (index < slides.length - 1) slide(index + 1); } function circle(index) { // a simple positive modulo using slides.length return (slides.length + (index % slides.length)) % slides.length; } function slide(to, slideSpeed) { // do nothing if already on requested slide if (index == to) return; if (browser.transitions) { var direction = Math.abs(index - to) / (index - to); // 1: backward, -1: forward // get the actual position of the slide if (options.continuous) { var natural_direction = direction; direction = -slidePos[circle(to)] / width; // if going forward but to < index, use to = slides.length + to // if going backward but to > index, use to = -slides.length + to if (direction !== natural_direction) newTo = -direction * slides.length + to; } var diff = Math.abs(index - to) - 1; // move all the slides between index and to in the right direction while (diff--) move(circle((to > index ? to : index) - diff - 1), width * direction, 0); to = circle(to); move(index, width * direction, slideSpeed || speed); move(to, 0, slideSpeed || speed); if (options.continuous) move(circle(to - direction), -(width * direction), 0); // we need to get the next in place } else { to = circle(to); animate(index * -width, to * -width, slideSpeed || speed); //no fallback for a circular continuous if the browser does not accept transitions } index = to; offloadFn(options.callback && options.callback(index, slides[index])); } function move(index, dist, speed) { translate(index, dist, speed); slidePos[index] = dist; } function translate(index, dist, speed) { var slide = slides[index]; var style = slide && slide.style; if (!style) return; style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = speed + 'ms'; style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)'; style.msTransform = style.MozTransform = style.OTransform = 'translateX(' + dist + 'px)'; } function animate(from, to, speed) { // if not an animation, just reposition if (!speed) { element.style.left = to + 'px'; return; } var start = +new Date; var timer = setInterval(function() { var timeElap = +new Date - start; if (timeElap > speed) { element.style.left = to + 'px'; if (delay) begin(); options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); clearInterval(timer); return; } element.style.left = (((to - from) * (Math.floor((timeElap / speed) * 100) / 100)) + from) + 'px'; }, 4); } // setup auto slideshow var delay = options.auto || 0; var interval; function begin() { interval = setTimeout(next, delay); } function stop() { delay = 0; clearTimeout(interval); } // setup initial vars var start = {}; var delta = {}; var isScrolling; // setup event capturing var events = { handleEvent: function(event) { switch (event.type) { case 'touchstart': this.start(event); break; case 'touchmove': this.move(event); break; case 'touchend': offloadFn(this.end(event)); break; case 'webkitTransitionEnd': case 'msTransitionEnd': case 'oTransitionEnd': case 'otransitionend': case 'transitionend': offloadFn(this.transitionEnd(event)); break; case 'resize': offloadFn(setup); break; } if (options.stopPropagation) event.stopPropagation(); }, start: function(event) { var touches = event.touches[0]; // measure start values start = { // get initial touch coords x: touches.pageX, y: touches.pageY, // store time to determine touch duration time: +new Date }; // used for testing first move event isScrolling = undefined; // reset delta and end measurements delta = {}; // attach touchmove and touchend listeners element.addEventListener('touchmove', this, false); element.addEventListener('touchend', this, false); }, move: function(event) { // ensure swiping with one touch and not pinching if (event.touches.length > 1 || event.scale && event.scale !== 1) return if (options.disableScroll) event.preventDefault(); var touches = event.touches[0]; // measure change in x and y delta = { x: touches.pageX - start.x, y: touches.pageY - start.y } // determine if scrolling test has run - one time test if (typeof isScrolling == 'undefined') { isScrolling = !!(isScrolling || Math.abs(delta.x) < Math.abs(delta.y)); } // if user is not trying to scroll vertically if (!isScrolling) { // prevent native scrolling event.preventDefault(); // stop slideshow stop(); // increase resistance if first or last slide if (options.continuous) { // we don't add resistance at the end translate(circle(index - 1), delta.x + slidePos[circle(index - 1)], 0); translate(index, delta.x + slidePos[index], 0); translate(circle(index + 1), delta.x + slidePos[circle(index + 1)], 0); } else { delta.x = delta.x / ((!index && delta.x > 0 // if first slide and sliding left || index == slides.length - 1 // or if last slide and sliding right && delta.x < 0 // and if sliding at all ) ? (Math.abs(delta.x) / width + 1) // determine resistance level : 1); // no resistance if false // translate 1:1 translate(index - 1, delta.x + slidePos[index - 1], 0); translate(index, delta.x + slidePos[index], 0); translate(index + 1, delta.x + slidePos[index + 1], 0); } } }, end: function(event) { // measure duration var duration = +new Date - start.time; // determine if slide attempt triggers next/prev slide var isValidSlide = Number(duration) < 250 // if slide duration is less than 250ms && Math.abs(delta.x) > 20 // and if slide amt is greater than 20px || Math.abs(delta.x) > width / 2; // or if slide amt is greater than half the width // determine if slide attempt is past start and end var isPastBounds = !index && delta.x > 0 // if first slide and slide amt is greater than 0 || index == slides.length - 1 && delta.x < 0; // or if last slide and slide amt is less than 0 if (options.continuous) isPastBounds = false; // determine direction of swipe (true:right, false:left) var direction = delta.x < 0; // if not scrolling vertically if (!isScrolling) { if (isValidSlide && !isPastBounds) { if (direction) { if (options.continuous) { // we need to get the next in this direction in place move(circle(index - 1), -width, 0); move(circle(index + 2), width, 0); } else { move(index - 1, -width, 0); } move(index, slidePos[index] - width, speed); move(circle(index + 1), slidePos[circle(index + 1)] - width, speed); index = circle(index + 1); } else { if (options.continuous) { // we need to get the next in this direction in place move(circle(index + 1), width, 0); move(circle(index - 2), -width, 0); } else { move(index + 1, width, 0); } move(index, slidePos[index] + width, speed); move(circle(index - 1), slidePos[circle(index - 1)] + width, speed); index = circle(index - 1); } options.callback && options.callback(index, slides[index]); } else { if (options.continuous) { move(circle(index - 1), -width, speed); move(index, 0, speed); move(circle(index + 1), width, speed); } else { move(index - 1, -width, speed); move(index, 0, speed); move(index + 1, width, speed); } } } // kill touchmove and touchend event listeners until touchstart called again element.removeEventListener('touchmove', events, false) element.removeEventListener('touchend', events, false) }, transitionEnd: function(event) { if (parseInt(event.target.getAttribute('data-index'), 10) == index) { if (delay) begin(); options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); } } } // trigger setup setup(); // start auto slideshow if applicable if (delay) begin(); // add event listeners if (browser.addEventListener) { // set touchstart event on element if (browser.touch) element.addEventListener('touchstart', events, false); if (browser.transitions) { element.addEventListener('webkitTransitionEnd', events, false); element.addEventListener('msTransitionEnd', events, false); element.addEventListener('oTransitionEnd', events, false); element.addEventListener('otransitionend', events, false); element.addEventListener('transitionend', events, false); } // set resize event on window window.addEventListener('resize', events, false); } else { window.onresize = function() { setup() }; // to play nice with old IE } // expose the Swipe API return { setup: function() { setup(); }, slide: function(to, speed) { // cancel slideshow stop(); slide(to, speed); }, prev: function() { // cancel slideshow stop(); prev(); }, next: function() { // cancel slideshow stop(); next(); }, stop: function() { // cancel slideshow stop(); }, getPos: function() { // return current index position return index; }, getNumSlides: function() { // return total number of slides return length; }, kill: function() { // cancel slideshow stop(); // reset element element.style.width = ''; element.style.left = ''; // reset slides var pos = slides.length; while (pos--) { var slide = slides[pos]; slide.style.width = ''; slide.style.left = ''; if (browser.transitions) translate(pos, 0, 0); } // removed event listeners if (browser.addEventListener) { // remove current event listeners element.removeEventListener('touchstart', events, false); element.removeEventListener('webkitTransitionEnd', events, false); element.removeEventListener('msTransitionEnd', events, false); element.removeEventListener('oTransitionEnd', events, false); element.removeEventListener('otransitionend', events, false); element.removeEventListener('transitionend', events, false); window.removeEventListener('resize', events, false); } else { window.onresize = null; } } } } if (window.jQuery || window.Zepto) { (function($) { $.fn.Swipe = function(params) { return this.each(function() { $(this).data('Swipe', new Swipe($(this)[0], params)); }); } })(window.jQuery || window.Zepto) } ul, li { display: inline-block; list-style: none } li, .swipeBtn { cursor: pointer } li+li { margin-left: 10px } li::before { content: '●'; color: grey } .dot_select::before { color: blue } #mySwipe { overflow: hidden } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="swipeBtn hotspot hspot cElement" id="prevBtn">❰</div> <div id='mySwipe' style='width:600px;margin:0 auto' class='swipe hotspot hspot cElement'> <div class='swipe-wrap'> <div><span id="slide1">---- SLIDE1 ----</span></div> <div><span id="slide2">---- SLIDE2 ----</span></div> <div><span id="slide3">---- SLIDE3 ----</span></div> </div> </div> <div class="swipeBtn hotspot hspot cElement" id="nextBtn">❱</div> <ul class="swipeDot"> <li class="dot_select"></li> <li></li> <li></li> </ul>
You do not need var prevDot. You might play it right using index: $(".swipeDot li").removeClass("dot_select") .eq(index).addClass("dot_select"); See the snippet: function init() { var elem = document.getElementById('mySwipe'); window.mySwipe = Swipe(elem, { // startSlide: 4, // auto: 3000, // continuous: true, // disableScroll: true, // stopPropagation: true, // callback: function(index, element) {}, transitionEnd: function(index, element) { $(".swipeDot li").removeClass("dot_select") .eq(index).addClass("dot_select"); } }); //$(".swipe-wrap").find("div").eq(2).find("span").css({backgroundImage:"url('../images/p006_img_2.png')"}) $("#prevBtn").click(function() { window.mySwipe.prev(); }); $("#nextBtn").click(function() { window.mySwipe.next(); }); $(".swipeDot li").each(function(index) { $(this).attr("slideIndex", index); }); $(".swipeDot li").click(function() { var slideIndex = $(this).attr("slideIndex"); window.mySwipe.slide(slideIndex); }); } $(document).ready(init); function Swipe(container, options) { console.log(container); "use strict"; // utilities var noop = function() {}; // simple no operation function var offloadFn = function(fn) { setTimeout(fn || noop, 0) }; // offload a functions execution // check browser capabilities var browser = { addEventListener: !!window.addEventListener, touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch, transitions: (function(temp) { var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition']; for (var i in props) if (temp.style[props[i]] !== undefined) return true; return false; })(document.createElement('swipe')) }; // quit if no root element if (!container) return; var element = container.children[0]; var slides, slidePos, width, length; options = options || {}; var index = parseInt(options.startSlide, 10) || 0; var speed = options.speed || 300; options.continuous = options.continuous !== undefined ? options.continuous : true; function setup() { // cache slides slides = element.children; length = slides.length; // set continuous to false if only one slide if (slides.length < 2) options.continuous = false; //special case if two slides if (browser.transitions && options.continuous && slides.length < 3) { element.appendChild(slides[0].cloneNode(true)); element.appendChild(element.children[1].cloneNode(true)); slides = element.children; } // create an array to store current positions of each slide slidePos = new Array(slides.length); // determine width of each slide width = container.offsetWidth; element.style.width = (slides.length * width) + 'px'; // stack elements var pos = slides.length; while (pos--) { var slide = slides[pos]; slide.style.width = width + 'px'; slide.setAttribute('data-index', pos); if (browser.transitions) { slide.style.left = (pos * -width) + 'px'; move(pos, index > pos ? -width : (index < pos ? width : 0), 0); } } // reposition elements before and after index if (options.continuous && browser.transitions) { move(circle(index - 1), -width, 0); move(circle(index + 1), width, 0); } if (!browser.transitions) element.style.left = (index * -width) + 'px'; container.style.visibility = 'visible'; } function prev() { if (options.continuous) slide(index - 1); else if (index) slide(index - 1); } function next() { if (options.continuous) slide(index + 1); else if (index < slides.length - 1) slide(index + 1); } function circle(index) { // a simple positive modulo using slides.length return (slides.length + (index % slides.length)) % slides.length; } function slide(to, slideSpeed) { // do nothing if already on requested slide if (index == to) return; if (browser.transitions) { var direction = Math.abs(index - to) / (index - to); // 1: backward, -1: forward // get the actual position of the slide if (options.continuous) { var natural_direction = direction; direction = -slidePos[circle(to)] / width; // if going forward but to < index, use to = slides.length + to // if going backward but to > index, use to = -slides.length + to if (direction !== natural_direction) to = -direction * slides.length + to; } var diff = Math.abs(index - to) - 1; // move all the slides between index and to in the right direction while (diff--) move(circle((to > index ? to : index) - diff - 1), width * direction, 0); to = circle(to); move(index, width * direction, slideSpeed || speed); move(to, 0, slideSpeed || speed); if (options.continuous) move(circle(to - direction), -(width * direction), 0); // we need to get the next in place } else { to = circle(to); animate(index * -width, to * -width, slideSpeed || speed); //no fallback for a circular continuous if the browser does not accept transitions } index = to; offloadFn(options.callback && options.callback(index, slides[index])); } function move(index, dist, speed) { translate(index, dist, speed); slidePos[index] = dist; } function translate(index, dist, speed) { var slide = slides[index]; var style = slide && slide.style; if (!style) return; style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = speed + 'ms'; style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)'; style.msTransform = style.MozTransform = style.OTransform = 'translateX(' + dist + 'px)'; } function animate(from, to, speed) { // if not an animation, just reposition if (!speed) { element.style.left = to + 'px'; return; } var start = +new Date; var timer = setInterval(function() { var timeElap = +new Date - start; if (timeElap > speed) { element.style.left = to + 'px'; if (delay) begin(); options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); clearInterval(timer); return; } element.style.left = (((to - from) * (Math.floor((timeElap / speed) * 100) / 100)) + from) + 'px'; }, 4); } // setup auto slideshow var delay = options.auto || 0; var interval; function begin() { interval = setTimeout(next, delay); } function stop() { delay = 0; clearTimeout(interval); } // setup initial vars var start = {}; var delta = {}; var isScrolling; // setup event capturing var events = { handleEvent: function(event) { switch (event.type) { case 'touchstart': this.start(event); break; case 'touchmove': this.move(event); break; case 'touchend': offloadFn(this.end(event)); break; case 'webkitTransitionEnd': case 'msTransitionEnd': case 'oTransitionEnd': case 'otransitionend': case 'transitionend': offloadFn(this.transitionEnd(event)); break; case 'resize': offloadFn(setup); break; } if (options.stopPropagation) event.stopPropagation(); }, start: function(event) { var touches = event.touches[0]; // measure start values start = { // get initial touch coords x: touches.pageX, y: touches.pageY, // store time to determine touch duration time: +new Date }; // used for testing first move event isScrolling = undefined; // reset delta and end measurements delta = {}; // attach touchmove and touchend listeners element.addEventListener('touchmove', this, false); element.addEventListener('touchend', this, false); }, move: function(event) { // ensure swiping with one touch and not pinching if (event.touches.length > 1 || event.scale && event.scale !== 1) return if (options.disableScroll) event.preventDefault(); var touches = event.touches[0]; // measure change in x and y delta = { x: touches.pageX - start.x, y: touches.pageY - start.y } // determine if scrolling test has run - one time test if (typeof isScrolling == 'undefined') { isScrolling = !!(isScrolling || Math.abs(delta.x) < Math.abs(delta.y)); } // if user is not trying to scroll vertically if (!isScrolling) { // prevent native scrolling event.preventDefault(); // stop slideshow stop(); // increase resistance if first or last slide if (options.continuous) { // we don't add resistance at the end translate(circle(index - 1), delta.x + slidePos[circle(index - 1)], 0); translate(index, delta.x + slidePos[index], 0); translate(circle(index + 1), delta.x + slidePos[circle(index + 1)], 0); } else { delta.x = delta.x / ((!index && delta.x > 0 // if first slide and sliding left || index == slides.length - 1 // or if last slide and sliding right && delta.x < 0 // and if sliding at all ) ? (Math.abs(delta.x) / width + 1) // determine resistance level : 1); // no resistance if false // translate 1:1 translate(index - 1, delta.x + slidePos[index - 1], 0); translate(index, delta.x + slidePos[index], 0); translate(index + 1, delta.x + slidePos[index + 1], 0); } } }, end: function(event) { // measure duration var duration = +new Date - start.time; // determine if slide attempt triggers next/prev slide var isValidSlide = Number(duration) < 250 // if slide duration is less than 250ms && Math.abs(delta.x) > 20 // and if slide amt is greater than 20px || Math.abs(delta.x) > width / 2; // or if slide amt is greater than half the width // determine if slide attempt is past start and end var isPastBounds = !index && delta.x > 0 // if first slide and slide amt is greater than 0 || index == slides.length - 1 && delta.x < 0; // or if last slide and slide amt is less than 0 if (options.continuous) isPastBounds = false; // determine direction of swipe (true:right, false:left) var direction = delta.x < 0; // if not scrolling vertically if (!isScrolling) { if (isValidSlide && !isPastBounds) { if (direction) { if (options.continuous) { // we need to get the next in this direction in place move(circle(index - 1), -width, 0); move(circle(index + 2), width, 0); } else { move(index - 1, -width, 0); } move(index, slidePos[index] - width, speed); move(circle(index + 1), slidePos[circle(index + 1)] - width, speed); index = circle(index + 1); } else { if (options.continuous) { // we need to get the next in this direction in place move(circle(index + 1), width, 0); move(circle(index - 2), -width, 0); } else { move(index + 1, width, 0); } move(index, slidePos[index] + width, speed); move(circle(index - 1), slidePos[circle(index - 1)] + width, speed); index = circle(index - 1); } options.callback && options.callback(index, slides[index]); } else { if (options.continuous) { move(circle(index - 1), -width, speed); move(index, 0, speed); move(circle(index + 1), width, speed); } else { move(index - 1, -width, speed); move(index, 0, speed); move(index + 1, width, speed); } } } // kill touchmove and touchend event listeners until touchstart called again element.removeEventListener('touchmove', events, false) element.removeEventListener('touchend', events, false) }, transitionEnd: function(event) { if (parseInt(event.target.getAttribute('data-index'), 10) == index) { if (delay) begin(); options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); } } } // trigger setup setup(); // start auto slideshow if applicable if (delay) begin(); // add event listeners if (browser.addEventListener) { // set touchstart event on element if (browser.touch) element.addEventListener('touchstart', events, false); if (browser.transitions) { element.addEventListener('webkitTransitionEnd', events, false); element.addEventListener('msTransitionEnd', events, false); element.addEventListener('oTransitionEnd', events, false); element.addEventListener('otransitionend', events, false); element.addEventListener('transitionend', events, false); } // set resize event on window window.addEventListener('resize', events, false); } else { window.onresize = function() { setup() }; // to play nice with old IE } // expose the Swipe API return { setup: function() { setup(); }, slide: function(to, speed) { // cancel slideshow stop(); slide(to, speed); }, prev: function() { // cancel slideshow stop(); prev(); }, next: function() { // cancel slideshow stop(); next(); }, stop: function() { // cancel slideshow stop(); }, getPos: function() { // return current index position return index; }, getNumSlides: function() { // return total number of slides return length; }, kill: function() { // cancel slideshow stop(); // reset element element.style.width = ''; element.style.left = ''; // reset slides var pos = slides.length; while (pos--) { var slide = slides[pos]; slide.style.width = ''; slide.style.left = ''; if (browser.transitions) translate(pos, 0, 0); } // removed event listeners if (browser.addEventListener) { // remove current event listeners element.removeEventListener('touchstart', events, false); element.removeEventListener('webkitTransitionEnd', events, false); element.removeEventListener('msTransitionEnd', events, false); element.removeEventListener('oTransitionEnd', events, false); element.removeEventListener('otransitionend', events, false); element.removeEventListener('transitionend', events, false); window.removeEventListener('resize', events, false); } else { window.onresize = null; } } } } if (window.jQuery || window.Zepto) { (function($) { $.fn.Swipe = function(params) { return this.each(function() { $(this).data('Swipe', new Swipe($(this)[0], params)); }); } })(window.jQuery || window.Zepto) } ul, li { display: inline-block; list-style: none } li, .swipeBtn { cursor: pointer } li+li { margin-left: 10px } li::before { content: '●'; color: grey } .dot_select::before { color: blue } #mySwipe { overflow: hidden } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="swipeBtn hotspot hspot cElement" id="prevBtn">❰</div> <div id='mySwipe' style='width:600px;margin:0 auto' class='swipe hotspot hspot cElement'> <div class='swipe-wrap'> <div><span id="slide1">---- SLIDE1 ----</span></div> <div><span id="slide2">---- SLIDE2 ----</span></div> <div><span id="slide3">---- SLIDE3 ----</span></div> </div> </div> <div class="swipeBtn hotspot hspot cElement" id="nextBtn">❱</div> <ul class="swipeDot"> <li class="dot_select"></li> <li></li> <li></li> </ul>
JQuery Draggable - Prevent grid objects from going in the same position
I'm using JQuery Draggable to move items round a grid. Objects snap to a 32x32 grid area. I want to be able to cancel a grid snap if an object is in the same position. The drag cannot be cancelled, it must just be prevented from entering the square. After it is prevented and moved back to the previous position, if the user continues to drag into a new unoccupied grid position, it must snap to that one. I've created a demo which serves the purpose explained above however the image glitches when it tries to enter the new position but is then cancelled back to the old position. https://jsfiddle.net/dtx7my4e/1/ Here's the code in that fiddle: HTML: <div class="drop-target"> <div class="drag-item" object-id="0"></div> <div class="drag-item" style="left: 32px;" object-id="1"></div> </div> Javascript: var objects = [ [0, 0], [1, 1] ]; $(function() { $(".drag-item").draggable({ grid: [ 32, 32 ], containment: '.drop-target', drag: function (event, obj){ let objectId = $(this).attr('object-id'); var objectPositionX = $(this).position().left / 32; var objectPositionY = $(this).position().top / 32; var previousPositionX = Math.floor(objects[objectId][0]); var previousPositionY = Math.floor(objects[objectId][1]); if (objectPositionX != previousPositionX || objectPositionY != previousPositionY) { if(!isObjectInPosition(objects, [objectPositionX, objectPositionY])) { objects[objectId] = [objectPositionX, objectPositionY]; } else { obj.position.left = previousPositionX * 32; obj.position.top = previousPositionY * 32; } } } }); }); function isObjectInPosition(arrayToSearch, positionToFind) { for (let i = 0; i < arrayToSearch.length; i++) { if (arrayToSearch[i][0] == positionToFind[0] && arrayToSearch[i][1] == positionToFind[1]) { return true; } } return false; } CSS: .drag-item { background-image: url("http://i.imgur.com/lBIWrWw.png"); background-size: 32px auto; width: 32px; height: 32px; cursor: move; } .drop-target { background: whitesmoke url("http://i.imgur.com/uUvTRLx.png") repeat scroll 0 0 / 32px 32px; border: 1px dashed orange; height: 736px; left: 0; position: absolute; top: 0; width: 736px; } Thank you, any help is greatly appreciated. Toby.
If you're willing to modify draggable itself, I think it would make the logic easier to apply. Once the drag event is triggered you can do lots of things, but you have much more control if you modify the _generatePosition method of draggable. It may look more complicated at first but for this kind of behavior, it's sometimes easier to work. Basically, you can run your isInPosition function after the check for grid and containment has been applied. Normally next step is to set the new position, but if your isInPosition returns true, you prevent dragging. Something like this: 'use strict' // This is the function generating the position by calculating // mouse position, different offsets and option. $.ui.draggable.prototype._generatePosition = function(event, constrainPosition) { var containment, co, top, left, o = this.options, scrollIsRootNode = this._isRootNode(this.scrollParent[0]), pageX = event.pageX, pageY = event.pageY; // Cache the scroll if (!scrollIsRootNode || !this.offset.scroll) { this.offset.scroll = { top: this.scrollParent.scrollTop(), left: this.scrollParent.scrollLeft() }; } /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ // If we are not dragging yet, we won't check for options if (constrainPosition) { if (this.containment) { if (this.relativeContainer) { co = this.relativeContainer.offset(); containment = [ this.containment[0] + co.left, this.containment[1] + co.top, this.containment[2] + co.left, this.containment[3] + co.top ]; } else { containment = this.containment; } if (event.pageX - this.offset.click.left < containment[0]) { pageX = containment[0] + this.offset.click.left; } if (event.pageY - this.offset.click.top < containment[1]) { pageY = containment[1] + this.offset.click.top; } if (event.pageX - this.offset.click.left > containment[2]) { pageX = containment[2] + this.offset.click.left; } if (event.pageY - this.offset.click.top > containment[3]) { pageY = containment[3] + this.offset.click.top; } } if (o.grid) { //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; } if (o.axis === "y") { pageX = this.originalPageX; } if (o.axis === "x") { pageY = this.originalPageY; } } // This is the only part added to the original function. // You have access to the updated position after it's been // updated through containment and grid, but before the // element is modified. // If there's an object in position, you prevent dragging. if (isObjectInPosition(objects, [pageX - this.offset.click.left - this.offset.parent.left, pageY - this.offset.click.top - this.offset.parent.top])) { return false; } return { top: ( pageY - // The absolute mouse position this.offset.click.top - // Click offset (relative to the element) this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.top + // The offsetParent's offset without borders (offset + border) (this.cssPosition === "fixed" ? -this.offset.scroll.top : (scrollIsRootNode ? 0 : this.offset.scroll.top)) ), left: ( pageX - // The absolute mouse position this.offset.click.left - // Click offset (relative to the element) this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.left + // The offsetParent's offset without borders (offset + border) (this.cssPosition === "fixed" ? -this.offset.scroll.left : (scrollIsRootNode ? 0 : this.offset.scroll.left)) ) }; } var objects = [ [0, 0], [1, 1] ]; $(function() { $(".drag-item").draggable({ grid: [32, 32], containment: '.drop-target', // on start you remove coordinate of dragged item // else it'll check its own coordinates start: function(event, obj) { var objectId = $(this).attr('object-id'); objects[objectId] = [null, null]; }, // on stop you update your array stop: function(event, obj) { var objectId = $(this).attr('object-id'); var objectPositionX = $(this).position().left / 32; var objectPositionY = $(this).position().top / 32; objects[objectId] = [objectPositionX, objectPositionY]; } }); }); function isObjectInPosition(arrayToSearch, positionToFind) { for (let i = 0; i < arrayToSearch.length; i++) { if (arrayToSearch[i][0] === (positionToFind[0] / 32) && arrayToSearch[i][1] === (positionToFind[1] / 32)) { return true; } } return false; } https://jsfiddle.net/bfc4tsrh/1/
HTML Element Height Keeps Incrementing by the Second
Purchased an off the shelf theme for my portfolio site (yes, yes...I'm too busy to design my own right now lol). Anyway I seem to be having an issue, and I have no idea when it started, where my html height keeps growing by 30-60px every 1-2sec. I've tried viewing the console, however I can't find anything that's triggering this. I'm assuming that some funking Javascript is at play, and need help possibly tracking it down. Anyone wanna lend a hand here...? My Site UPDATE: It seems to be caused by the smoothscroll.js file. Can any JS pro help me find the offending line of code? // SmoothScroll v1.2.1 // Licensed under the terms of the MIT license. // People involved // - Balazs Galambosi (maintainer) // - Patrick Brunner (original idea) // - Michael Herf (Pulse Algorithm) // - Justin Force (Resurect) // Scroll Variables (tweakable) var framerate = 150; // [Hz] var animtime = 800; // [px] var stepsize = 80; // [px] // Pulse (less tweakable) // ratio of "tail" to "acceleration" var pulseAlgorithm = true; var pulseScale = 8; var pulseNormalize = 1; // Acceleration var acceleration = true; var accelDelta = 10; // 20 var accelMax = 1; // 1 // Keyboard Settings var keyboardsupport = true; // option var disableKeyboard = false; // other reasons var arrowscroll = 50; // [px] // Excluded pages var exclude = ""; var disabled = false; // Other Variables var frame = false; var direction = { x: 0, y: 0 }; var initdone = false; var fixedback = true; var root = document.documentElement; var activeElement; var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36 }; /** * Sets up scrolls array, determines if frames are involved. */ function init() { if (!document.body) return; var body = document.body; var html = document.documentElement; var windowHeight = window.innerHeight; var scrollHeight = body.scrollHeight; // check compat mode for root element root = (document.compatMode.indexOf('CSS') >= 0) ? html : body; activeElement = body; initdone = true; // Checks if this script is running in a frame if (top != self) { frame = true; } /** * This fixes a bug where the areas left and right to * the content does not trigger the onmousewheel event * on some pages. e.g.: html, body { height: 100% } */ else if (scrollHeight > windowHeight && (body.offsetHeight <= windowHeight || html.offsetHeight <= windowHeight)) { // DOMChange (throttle): fix height var pending = false; var refresh = function() { if (!pending && html.scrollHeight != document.height) { pending = true; // add a new pending action setTimeout(function(){ html.style.height = document.height + 'px'; pending = false; }, 500); // act rarely to stay fast } }; html.style.height = ''; setTimeout(refresh, 10); addEvent("DOMNodeInserted", refresh); addEvent("DOMNodeRemoved", refresh); // clearfix if (root.offsetHeight <= windowHeight) { var underlay = document.createElement("div"); underlay.style.clear = "both"; body.appendChild(underlay); } } // gmail performance fix if (document.URL.indexOf("mail.google.com") > -1) { var s = document.createElement("style"); s.innerHTML = ".iu { visibility: hidden }"; (document.getElementsByTagName("head")[0] || html).appendChild(s); } // disable fixed background if (!fixedback && !disabled) { body.style.backgroundAttachment = "scroll"; html.style.backgroundAttachment = "scroll"; } } /************************************************ * SCROLLING ************************************************/ var que = []; var pending = false; var lastScroll = +new Date; /** * Pushes scroll actions to the scrolling queue. */ function scrollArray(elem, left, top, delay) { delay || (delay = 1000); directionCheck(left, top); if (acceleration) { var now = +new Date; var elapsed = now - lastScroll; if (elapsed < accelDelta) { var factor = (1 + (30 / elapsed)) / 2; if (factor > 1) { factor = Math.min(factor, accelMax); left *= factor; top *= factor; } } lastScroll = +new Date; } // push a scroll command que.push({ x: left, y: top, lastX: (left < 0) ? 0.99 : -0.99, lastY: (top < 0) ? 0.99 : -0.99, start: +new Date }); // don't act if there's a pending queue if (pending) { return; } var scrollWindow = (elem === document.body); var step = function() { var now = +new Date; var scrollX = 0; var scrollY = 0; for (var i = 0; i < que.length; i++) { var item = que[i]; var elapsed = now - item.start; var finished = (elapsed >= animtime); // scroll position: [0, 1] var position = (finished) ? 1 : elapsed / animtime; // easing [optional] if (pulseAlgorithm) { position = pulse(position); } // only need the difference var x = (item.x * position - item.lastX) >> 0; var y = (item.y * position - item.lastY) >> 0; // add this to the total scrolling scrollX += x; scrollY += y; // update last values item.lastX += x; item.lastY += y; // delete and step back if it's over if (finished) { que.splice(i, 1); i--; } } // scroll left and top if (scrollWindow) { window.scrollBy(scrollX, scrollY) } else { if (scrollX) elem.scrollLeft += scrollX; if (scrollY) elem.scrollTop += scrollY; } // clean up if there's nothing left to do if (!left && !top) { que = []; } if (que.length) { requestFrame(step, elem, (delay / framerate + 1)); } else { pending = false; } } // start a new queue of actions requestFrame(step, elem, 0); pending = true; } /*********************************************** * EVENTS ***********************************************/ /** * Mouse wheel handler. * #param {Object} event */ function wheel(event) { if (!initdone) { init(); } var target = event.target; var overflowing = overflowingAncestor(target); // use default if there's no overflowing // element or default action is prevented if (!overflowing || event.defaultPrevented || isNodeName(activeElement, "embed") || (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) { return true; } var deltaX = event.wheelDeltaX || 0; var deltaY = event.wheelDeltaY || 0; // use wheelDelta if deltaX/Y is not available if (!deltaX && !deltaY) { deltaY = event.wheelDelta || 0; } // scale by step size // delta is 120 most of the time // synaptics seems to send 1 sometimes if (Math.abs(deltaX) > 1.2) { deltaX *= stepsize / 120; } if (Math.abs(deltaY) > 1.2) { deltaY *= stepsize / 120; } scrollArray(overflowing, -deltaX, -deltaY); event.preventDefault(); } /** * Keydown event handler. * #param {Object} event */ function keydown(event) { var target = event.target; var modifier = event.ctrlKey || event.altKey || event.metaKey || (event.shiftKey && event.keyCode !== key.spacebar); // do nothing if user is editing text // or using a modifier key (except shift) // or in a dropdown if ( /input|textarea|select|embed/i.test(target.nodeName) || target.isContentEditable || event.defaultPrevented || modifier ) { return true; } // spacebar should trigger button press if (isNodeName(target, "button") && event.keyCode === key.spacebar) { return true; } var shift, x = 0, y = 0; var elem = overflowingAncestor(activeElement); var clientHeight = elem.clientHeight; if (elem == document.body) { clientHeight = window.innerHeight; } switch (event.keyCode) { case key.up: y = -arrowscroll; break; case key.down: y = arrowscroll; break; case key.spacebar: // (+ shift) shift = event.shiftKey ? 1 : -1; y = -shift * clientHeight * 0.9; break; case key.pageup: y = -clientHeight * 0.9; break; case key.pagedown: y = clientHeight * 0.9; break; case key.home: y = -elem.scrollTop; break; case key.end: var damt = elem.scrollHeight - elem.scrollTop - clientHeight; y = (damt > 0) ? damt+10 : 0; break; case key.left: x = -arrowscroll; break; case key.right: x = arrowscroll; break; default: return true; // a key we don't care about } scrollArray(elem, x, y); event.preventDefault(); } /** * Mousedown event only for updating activeElement */ function mousedown(event) { activeElement = event.target; } /*********************************************** * OVERFLOW ***********************************************/ var cache = {}; // cleared out every once in while setInterval(function(){ cache = {}; }, 10 * 1000); var uniqueID = (function() { var i = 0; return function (el) { return el.uniqueID || (el.uniqueID = i++); }; })(); function setCache(elems, overflowing) { for (var i = elems.length; i--;) cache[uniqueID(elems[i])] = overflowing; return overflowing; } function overflowingAncestor(el) { var elems = []; var rootScrollHeight = root.scrollHeight; do { var cached = cache[uniqueID(el)]; if (cached) { return setCache(elems, cached); } elems.push(el); if (rootScrollHeight === el.scrollHeight) { if (!frame || root.clientHeight + 10 < rootScrollHeight) { return setCache(elems, document.body); // scrolling root in WebKit } } else if (el.clientHeight + 10 < el.scrollHeight) { overflow = getComputedStyle(el, "").getPropertyValue("overflow-y"); if (overflow === "scroll" || overflow === "auto") { return setCache(elems, el); } } } while (el = el.parentNode); } /*********************************************** * HELPERS ***********************************************/ function addEvent(type, fn, bubble) { window.addEventListener(type, fn, (bubble||false)); } function removeEvent(type, fn, bubble) { window.removeEventListener(type, fn, (bubble||false)); } function isNodeName(el, tag) { return (el.nodeName||"").toLowerCase() === tag.toLowerCase(); } function directionCheck(x, y) { x = (x > 0) ? 1 : -1; y = (y > 0) ? 1 : -1; if (direction.x !== x || direction.y !== y) { direction.x = x; direction.y = y; que = []; lastScroll = 0; } } var requestFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || function(callback, element, delay){ window.setTimeout(callback, delay || (1000/60)); }; })(); /*********************************************** * PULSE ***********************************************/ /** * Viscous fluid with a pulse for part and decay for the rest. * - Applies a fixed force over an interval (a damped acceleration), and * - Lets the exponential bleed away the velocity over a longer interval * - Michael Herf, http://stereopsis.com/stopping/ */ function pulse_(x) { var val, start, expx; // test x = x * pulseScale; if (x < 1) { // acceleartion val = x - (1 - Math.exp(-x)); } else { // tail // the previous animation ended here: start = Math.exp(-1); // simple viscous drag x -= 1; expx = 1 - Math.exp(-x); val = start + (expx * (1 - start)); } return val * pulseNormalize; } function pulse(x) { if (x >= 1) return 1; if (x <= 0) return 0; if (pulseNormalize == 1) { pulseNormalize /= pulse_(1); } return pulse_(x); } addEvent("mousedown", mousedown); addEvent("mousewheel", wheel); addEvent("load", init);
Not sure what's going on here, but the issue with smoothscroll.js still stands. Disabling it seems to have no effect on the rest of my site though so I'm moving forward.
html element doesn't move correctly with jQuery
I have to repair bottom slider on http://rhemapress.pl/www_wopr/ . If you see when you click right arrow twice, then animation back to start and animate again. Here when i click one on right arrow time this should be blocked and not possible to click second time. Numer of moves right is created dynamicly by checkWidth(); function checkWidth() { var elements = $('.items').children().length; var width = Math.ceil(elements / 5) * 820; return width; } This return realWidth witch is something like limit of offset. Variable offset is setted to 0 at start. So, if i click right, then in method moveRight() is checked if element can be moved and it's move. At end offset is increment by 820px (one page of slider), so if we've got 2 pages, then next move can't be called. But it is and this is problem! :/ My code <script type="text/javascript"> $(document).ready(function() { $('a.prev').bind('click',moveLeft); $('a.next').bind('click',moveRight); var realWidth = checkWidth(); realWidth -= 820; var offset = 0; function moveLeft(e) { var position = $('.items').position(); var elements = $('.items').children().length; if ((elements > 5) && ((offset - 820) >= 0) ) { $('.items').animate({ 'left': (position.left + 820) }, 300, function() { offset -= 820; }); } } function moveRight(e) { var position = $('.items').position(); var elements = $('.items').children().length; if ((elements > 5) && ((offset + 820) <= realWidth)) { $('.items').animate({ 'left': (position.left - 820) }, 300, function() { offset += 820; }); } } function checkWidth() { var elements = $('.items').children().length; var width = Math.ceil(elements / 5) * 820; return width; } }); </script> How can i do this correctly?
It seems like you want to prevent the click event from firing before the current animation is complete. You can do this by preventing the rest of the function from executing if the element is currently being animated: function moveLeft(e) { if ($(this).is(":animated")) { return false; }