I'm using a slideshow on my website using jquery Cycle 1.
I navigate into my slideshow with #next function. when clicking on my last slide of my slideshow it redirect me to another page (var random_next_url_enfant).
I would like to add the spacebar and the right arrow key to navigation inside my slideshow.
when I add this Js code it works, but on the last slide it starts the slideshow again instead of redirecting me to the next page.
$(document.documentElement).keyup(function (e) {
if (e.keyCode == 39)
{
$('#slider_projets').cycle('next');
}
});
here is my full code using the mouse click. on the last slide, it redirects me to another page, it works perfectly. but I would like to get the same with the spacebar and the right arrow :
$('#slider_projets').cycle({
speed: 600, //temps d'animation
timeout: 0, //fréquence
fx: 'scrollLeft',
//compteur//
pager: "#nav",
after: function(currSlideElement, nextSlideElement, options, forwardFlag) {
$('#counter_1').text((options.currSlide + 1) + ' / ' + (options.slideCount));
slideIndex = options.currSlide;
nextIndex = slideIndex + 1;
prevIndex = slideIndex - 1;
if (slideIndex == options.slideCount - 1) {
/*nextIndex = 0;*/
var random_next_url_enfant = $("#random_next_url_enfant").val();
$('#next').on("click", function(e){
e.preventDefault();
window.location = random_next_url_enfant;
});
}
if (slideIndex === 0) {
prevIndex = options.slideCount - 1;
}
}
});
I think i'm missing something but I can't find what !
here is a jsfiddle :
http://jsfiddle.net/8HsdG/
thanks a lot for your help,
You need access to your slider options outside of your slider, the reason you are not getting to the url is because there is no listener telling it to go there, only the click event.
Here is a jsfiddle that will get you very close, it has everything you need, you just have to fill in the blanks.
http://jsfiddle.net/kkemple/8HsdG/1/
I wrapped your code in an anonymous function so I could declare some scoped variables
(function () {
var slideIndex, slideCount;
// all of your code is here
})();
I then added a before call on your slider:
before: function(currSlideElement, nextSlideElement, options, forwardFlag) {
slideCount = options.slideCount;
},
then added the following code to your key events:
if ( slideIndex == slideCount ) {
//redirect to random url
e.preventDefault;
}
#kkemple, I've resolved the problem... I just had to change :
$(document.documentElement).keyup(function (e) {
if (e.keyCode == 32)
{
$('#slider_projets').cycle('next');
}
});
by
$(document.documentElement).keyup(function (e) {
if (e.keyCode == 32)
{
$("#next").trigger("click");
}
});
and it works perfectly ! anyway thanks for your help !
Related
I have a js script that is supposed to fix my side menu on scroll. It shows it being included in the view source and if I copy/paste my code into console to auto-fire it, it works perfectly.
How can I figure out why it won't fire on load? No errors are thrown either. The file in question has 2 functions, the first is to fix the menu to to top and the second deals with changing content out by checking checkboxes.
Here is my script:
// FIX SIDE BAR AFTER SCROLL
$(window).load(function() {
console.log('test');
$("a[href*=#]:not([href=#])").click(function() {
if (location.pathname.replace(/^\//, "") == this.pathname.replace(/^\//, "") && location.hostname == this.hostname) {
var o = $(this.hash);
if (o = o.length ? o : $("[name=" + this.hash.slice(1) + "]"), o.length) return $("html,body").animate({
scrollTop: o.offset().top
}, 900), !1
}
});
console.log('test2');
$(window).load(function() {
var o = $(".sticky").offset().top,
t = function() {
var t = $(window).scrollTop();
t > o ? $(".sticky").addClass("stuck") : $(".sticky").removeClass("stuck")
};
t(), $(window).scroll(function() {
t()
});
console.log('test3');
});
//RADIO BUTTON CONTENT CHANGER
$(function(){
$('input[name="pricing-radios"]').on('change', function(){
if ($(this).val()=='pricing1') {
//change to "show update"
$(".pricing-engage-chng").text("179");
$(".pricing-engage-chng-additional").text(".01");
$(".pricing-crm-chng").text("214");
$(".pricing-crm-chng-additional").text(".01");
$(".upgrade-price").text(".0025");
} else if ($(this).val()=='pricing2') {
$(".pricing-engage-chng").text("699");
$(".pricing-engage-chng-additional").text(".005");
$(".pricing-crm-chng").text("714");
$(".pricing-crm-chng-additional").text(".006");
$(".upgrade-price").text(".0015");
} else if ($(this).val()=='pricing3') {
$(".pricing-engage-chng").text("3,499");
$(".pricing-engage-chng-additional").text(".0025");
$(".pricing-crm-chng").text("3,514");
$(".pricing-crm-chng-additional").text(".00325");
$(".upgrade-price").text(".00075");
}
});
});
});
My code seems to work in my JSFiddle and as I said, copy and pasting my code into my console will fire my command and yield the desired result.
You can see the live page here as well.
Thanks for the help!
Alright so I figured this out:
The framework we use has an auto-minify function in it. So when I pulled the old code through, this part is technically minified. So my vars were returning unknown elements.
$(window).load(function() {
var o = $(".sticky").offset().top,
t = function() {
var t = $(window).scrollTop();
t > o ? $(".sticky").addClass("stuck") : $(".sticky").removeClass("stuck")
};
t(), $(window).scroll(function() {
t()
});
I ended up rewriting a function to add the class and simplified it a little more and came up with this:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
//if less than or = to 350 add class
if (scroll >= 350) {
$(".sticky").addClass("stuck");
// else remove class
} else {
$(".sticky").removeClass("stuck");
}
});
Now this one gets minified, but everything is predefined and is readable.
I have a problem with the scrolling animation. Jumpy scroll occurs when the page is scrolled after scroll-animation. I suspected the scroll-event repeats itself, but I'm not sure. Can you help me with it?
$(document).ready(function(){
var offset;
var anchor = $("#navigation").offset().top;
$(window).bind('mousewheel', function (e) {
offset = $(window).scrollTop();
if (e.originalEvent.wheelDelta < 0) {
//mouse scroll down
console.log('Down: ' + offset + " " + anchor);
if (offset >= anchor) {
// if anchor has been scrolled, user can scroll further
// the problem ocuurs in this block
return true;
} else {
// animate to anchor( nav menu)
$("body, html").animate({
scrollTop: anchor + 1
}, 200);
$("#navigation").addClass("nav-fixed");
return false;
}
} else {
//mouse scroll up
if (offset < anchor) {
$("#navigation").removeClass("nav-fixed");
return true;
}
}});
});
JSFiddle: http://jsfiddle.net/0noms3cs/
Thank you a lot!
Your issue is simple. The scroll event fires over and over again. Your line of thinking behind the cause of this issue is correct, you have a large number of animate events that get stacked up which causes this weird behavior.
You can resolve this issue by adding a boolean variable (such as scrollInitialized) that starts out as false and gets flipped to true once the scroll event has fired once.
Here's the altered JS code. Note: I only added the scrollInitialized variable and a check for it in the if statement.
Edit: I also removed the inner if-else case since it was not necessary using this design.
EDIT 2: I originally misunderstood what you wanted to do. What you need to do was add a scrollLock variable that would only be set to true for the duration of your animation. After thinking about this, I implemented it for you. Here is the Jsfiddle:
https://jsfiddle.net/04gaaapo/1/
Here is the new JS code:
$(document).ready(function () {
var scrollLock = false;
var offset;
var anchor = $("#navigation").offset().top;
$(window).bind('mousewheel', function (e) {
offset = $(window).scrollTop();
// if scroll is NOT locked and we are above the anchor
if (scrollLock === false && offset < anchor) {
if (e.originalEvent.wheelDelta < 0) {
// scrolling down
scrollLock = true;
// animate to anchor( nav menu)
$("body, html").animate({
scrollTop: anchor + 1
}, 200);
// unlock in 250ms
setTimeout(toggleLock, 250);
// add nav class
$("#navigation").addClass("nav-fixed");
} else if (e.originalEvent.wheelDelta > 0) {
// scrolling up
scrollLock = true;
// animate to top of page
$("body, html").animate({
scrollTop: 0
}, 200);
// unlock in 250ms
setTimeout(toggleLock, 250);
// remove nav class
$("#navigation").removeClass("nav-fixed");
}
}
});
function toggleLock() {
scrollLock = !scrollLock;
};
});
Here's the Link to the Fiddle.
I'm working with a carousel and I want to make the next/previous buttons functional.
I tried adding the following code but it doesn't update the index properly. Any help would be appreciated!
$($btnNext).click(function (event) {
updateSlides(index + 1);
event.preventDefault();
}
$($btnPrev).click(function (event) {
updateSlides(index - 1);
event.preventDefault();
}
When the click event on those buttons is called, that index variable is undefined. There are several different ways of figuring out the index, the method I used in the fiddle was to set an attribute on the slider and then check it on the click events:
function updateSlides(index, paused) {
$($slider).attr('data-index', index);
...
}
$($btnNext).click(function (event) {
var index = parseInt($('.slider').attr('data-index'));
if(index > $('.slider .content li').length) {
index = 0;
}
console.log('#next', index);
updateSlides(index + 1);
event.preventDefault();
});
$($btnPrev).click(function (event) {
var index = parseInt($('.slider').attr('data-index'));
if(index < 0) {
index = 0;
}
console.log('#previous', index);
updateSlides(index - 1);
event.preventDefault();
});
See the updated fiddle here: http://jsfiddle.net/sbp76sLc/14/
Normally my slideshow goes automatically to the next picture, but I want to detect if it goes backwards by an user-initiated action (keyboard arrows or controls). My solution to this would be to do this (my imaginary code):
if(jQuery("#slideshow article").hasChangedClassFrom("previous").hasChangedClassTo("current")) {
backwards = true;
}
if(backwards) { // code for backwards
jQuery("#slideshow article.previous").css("z-index", "1");
jQuery("#slideshow article.next").css("z-index", "2");
}
else { // code for forwards (normal state)
jQuery("#slideshow article.previous").css("z-index", "2");
jQuery("#slideshow article.next").css("z-index", "1");
}
The classes are already implemented, so that the current slide always has the class "current" and so on. I know this isn't valid code at all, but by reading this, I think it would be quite clear what I want to achieve. I'm not very good at JavaScript/jQuery, but I've tried searching for solutions like this without luck.
Live site // Live JS code
Based on the code from the mentioned link http://dans.no/cycle.js
Declare a variable clickindex=0;
Place the following inside the click function of jQuery("#slideshow nav a").click
clickindex = jQuery("#slideshow nav a").index(this);
if(clickindex<index){
console.log("execute some logic");
}
The jsfiddle link for my solution javascript code http://jsfiddle.net/y601tkfL/
Instead of guessing that the previous class, use the current and the previous index.
http://jsfiddle.net/whyba4L9/5/
UPDATE 2:
var stopp, antall = jQuery("#slideshow article").length;
var index = 0
function slideTo(idx) {
jQuery("#slideshow article, #slideshow nav a").removeAttr("class").filter(':nth-of-type(' + (idx+1) + ')').addClass("current");
if(jQuery("#slideshow article:nth-of-type(2)").hasClass("current")) {
jQuery("#slideshow article:first-of-type").addClass("forrige");
jQuery("#slideshow article:last-of-type").addClass("neste");
}
else if(jQuery("#slideshow article:first-of-type").hasClass("current")) {
jQuery("#slideshow article:last-of-type").addClass("forrige");
jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
}
else if(jQuery("#slideshow article:last-of-type").hasClass("current")) {
jQuery("#slideshow article:nth-of-type(2)").addClass("forrige");
jQuery("#slideshow article:first-of-type").addClass("neste");
}
if(index ==antall-1 && idx ==0 )
{
//lasto to first
}
else if(index>idx || (index == 0 && idx == antall-1))
{
alert('BACKWARDS')
}
index = idx;
};
function startCycle() {
stopp = setInterval(function() {
jQuery("#slideshow article").stop(true, true);
var idx = index + 1 > antall - 1 ? 0 : index + 1;
slideTo(idx,false);
}, 5500);
};
if (antall > 1) {
jQuery("#slideshow").append("<nav>").css("height", jQuery("#slideshow img").height());
jQuery("#slideshow article").each(function() {
jQuery("#slideshow nav").append("<a>•</a>");
}).filter(":first-of-type").addClass("current first");
jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
jQuery("#slideshow article:last-of-type").addClass("forrige");
startCycle();
jQuery("#slideshow nav a").click(function() {
clearInterval(stopp);
startCycle();
var idx = jQuery("#slideshow nav a").index(this);
if (index === idx) return;
slideTo(idx);
}).filter(":first-of-type").addClass("current");
jQuery(document).keyup(function(e) {
if (e.keyCode == 37) {
var idx = index - 1 < 0 ? antall - 1 : index - 1;
slideTo(idx);
clearInterval(stopp);
startCycle();
}
else if (e.keyCode == 39) {
var idx = index + 1 > antall - 1 ? 0 : index + 1;
slideTo(idx);
clearInterval(stopp);
startCycle();
}
});
}
Try calling this function when the user changes the image with parameter of this. I hope I correctly understood what you are asking. If not let me know and I will recode it. Also if the slide show is finished please post your html and javascript.
function whatever(this)
{
if(this.className == 'previous')
{
alert('the user has changed the image');
this.className = 'current';
}
else
{
alert('the user hasn\'t changed the image');
}
}
The dead simplest way to do this, from what I understand your question to aim at, is to put a handler on the index buttons and a method for tracking the current image.
Listen for slide change
var currentSlide = '';
$('.slideIndexButtons').on('click', function(e){
// Conditional logic that compares $(this).data('whichimage') to currentSlide
var whichImage = $(this).data('whichimage');
// ->this means attaching data-whichimage="" to each of the elements, or
// ->you can just stick with detecting the class and going from there
// Either process results in isBackwards boolean
if (currentSlide == 'prev' && whichImage == 'current') {
isBackwards = true;
}
if (isBackwards) {
// Backwards logic here
} else {
// Other logic here
}
// Unless the event we're listening for in keeping currentSlide updated is also fired when
// the slide changes due to user input, we'll need to update currentSlide manually.
currentSlide = whichImage;
});
Track the current slide
$('#slider').on('event', function(){
// This is assuming that we're strictly listening to the slider's automatic sliding
// The event you attach this to is either fired before or after the slide changes.
// Knowing which is key in getting the data you want. You are either getting
// The data from this slide $(this).data('whichimage') or
// $(this).next().data('whichimage')
// Again, you can go with classes, but it is a lot of logic which you have to
// update manually if you ever have to add or alter an image in the slide set.
// Either way, you end up with the variable targetImage
currentSlide = targetImage;
});
With any luck, your slideshow code has an API that will allow you to listen for when slide-related events are fired. Otherwise, you'll have to find a way of setting up, firing and listening for these events manually, either through callbacks passed in or by (eek!) altering the code and possibly unintentionally changing its functionality.
This should give you what you asked for. Let me know how it goes.
You can add this line at the very start of slideTo function in your cycle.js
if((idx < index && !(idx == 0 && index == antall - 1)) ||
(idx == antall - 1 && index == 0)){
jQuery.trigger('BACKWARDS')
}
and then add an event handler for "BACKWARDS" somewhere else convenient (Maybe at the end of cycle.js?).
jQuery.on('BACKWARDS', function(e){
//DO THINGS HERE
}
I wrote a plugin attrchange which I think will effectively solve your problem. attrchange is a simple jQuery plugin to detect an attribute change. The plugin internally uses one of the following compatible methods based on the browser to detect an attribute change,
Mutation Observer
DOMAttrModified
onpropertychange
Try out below demo to understand more about how you can use the plugin for your need.
Click to read more about attrchange.
Note: The plugin doesn't use polling so you can use it without any worries, however polling is supported as an extension to the plugin. You can read more if you are interested.
$('#test').one('click', function() {
$('#test').attrchange({
trackValues: true,
callback: function(event) {
$('#result').html('<div><label>Attribute Name: </label>' + event.attributeName + '</div>' + '<div><label>Old Value</label>' + event.oldValue + '</div>' + '<div><label>New Value</label>' + event.newValue + '</div>');
}
});
//this will toggleClass 'blue-background' every 2 secs
setInterval(function() {
$('#test').toggleClass('lightblue-background');
}, 2000);
});
html {
font-family: Segoe UI, Arial, sans-serif;
font-size: 13px;
}
div#test {
border: 1px solid #d2d2d2;
padding: 10px;
display: inline-block;
}
.lightblue-background {
background-color: #DBEAF9;
}
div label {
font-weight: bold;
margin-right: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/meetselva/attrchange/master/js/attrchange.js"></script>
<div id="test">
<p style="font-weight: bold;">Click anywhere in this box to Start the DEMO</p>
<p>The demo is to simply toggle a class 'lightblue-background' to this div every 2 secs.</p>
<div id="result" style="font-size: 0.9em;"></div>
See the pseudo code for your case using the plugin,
jQuery("#slideshow article").attrchange({
trackValues: true,
callback: function(event) {
if ($(this).hasClass('current') &&
(event.oldValue && event.oldValue.indexOf('previous') >= 0)) {
//code for backward
} else {
//code for forward
}
}
});
I have got a loop function that slides 2 divs over a 3rd. Working example can be found here: http://jsbin.com/OYebomEB/4/.
Main function:
var elements = ['#pointsbarDiv', '#hotlink1Div', '#pointsbarDiv', '#hotlink2Div'];
function hotlinks_loop(index) {
$(elements[index]).css({top: -75, display: 'block'}).animate({top: '+0'}, 3000, function () {
var $self = $(this);
var currentInstance = this;
setTimeout(function () {
$self.animate({top: $(window).height()}, 3000);
if(currentInstance.hotlinkStop !== true){
hotlinks_loop((index + 1) % elements.length);
}
}, 3000, currentInstance);
});
}
hotlinks_loop(0); // start with the first element
I have some code to disable onclick while hotlink divs are moving:
hotlink2BtnClick: function () {
if ($("#hotlink2Div").css("top") === "0px") {
//do stuff;
} else {
//do stuff;
}
},
However, for the stationary pointsbarDiv I cannot find a solution to disable onclick/mousedown while hotlink divs are sliding over it.
I have tried various 'If's like the the following example:
if (($("#hotlink1Div").css("top") < "76px" && $("#hotlink1Div").css("bottom") < "150px") || ($("#hotlink1Div").css("top") > "-75px" && $("#hotlink1Div").css("bottom") < "75px")))...
I am also wondering if there is way I can just disable onclick/mousedown while divs are moving within the main function provided.
I should mention that I am a newbie to javascript/jquery.
JQuery event functions get passed an event object - you can accept this in your function, and use it to stop propagation:
hotlink2BtnClick: function (ev) {
ev.stopPropagation();
http://api.jquery.com/event.stoppropagation/
Also, if you put your js examples on http://jsfiddle.net, then we can fork it and return it to you fixed.
I managed to do this by creating a an extra div giving it a z-index of -1 and setting visibility to hidden.
Then replacing the points div with this in array for the loop.
Followed by implementing a similar code solution hotlink2BtnClick().