I'm trying to create a custom slider using jQuery only I'm unsure on the best practice for how ot make this work.
My slider has 3 slides and a controls section each relating to a slide (1, 2, 3).
When a control is clicked I've got my slide fading out only I'm unsure on how to say if X control was clicked, add the active class to the relevant slide?
Ive made a fiddle to explain which i hope helps, what i need however is an explanation of the best practice in doing this?
Sorry if the questions hard to understand!
What I'm using to fade out my current slide, but then once its gone I cant rely on the active class to say add a class to the next element?
$('.ctrl-one').click(function(){
$('.active .slide-img').animate({
'marginRight' : "-=350px"
}, 500, 'easeOutQuint', function(){
$('.active .description').fadeOut().promise().done(function(){
$(this).parent().removeClass('active');
});
});
});
http://jsfiddle.net/Esm97/
I guess this is what you need,try this code , but am sure you can find a lot different methods.
$('.controls a').click(function() {
var current = $(this).attr('class').replace('ctrl-', '');
if (!$('.sector-banner .' + current).hasClass('active')) {
$('.active').animate({
'marginRight': "-=350px"
}, 500, 'linear', function() {
$(this).fadeOut().promise().done(function() {
$(this).css('margin-right',0);
$(this).removeClass('active');
$('.sector-banner .' + current).addClass('active');
$('.sector-banner .' + current).fadeIn();
});
});
}
});
Related
Using slider-pro, I am having trouble getting slide count for the number of slides inside the carousel. I have looked at this solution, but am having no luck. My code looks like this:
$(document).ready(function($) {
$('.slider-pro').sliderPro();
});
var slider = $( this ).data( 'sliderPro' );
$(this).append('<div class="counter"><span class="active">'+ (parseInt(slider.getSelectedSlide()) + 1) +'</span>/'+slider.getTotalSlides()+'</div>');
slider.on( 'gotoSlide', function( event ) {
$(this).find('.counter .active').text(event.index + 1);
});
But I get a console error:
TypeError: slider is undefined, can't access property "getSelectedSlide" of it
I am not much of a jquery guy, so I'm not sure why it is giving me this error when in fact the property getSelectedSlide is defined in the jquery.sliderPro.js file. Perhaps I'm not calling it correctly or need to bind the property to a class or id. I'm not sure. I've tried both, but nothing seems to work.
Thanks so much!
Unfortunately, I'm using the class selector to initialize multiple sliders on the same page with the same parameters. I don't want to use id because I will have to create a unique id for every slider instance, which I don't want and will become unmanageable. I also cannot dynamically generate an id for each slider. An example page is here:
BFMagazine
Right now, I have to hardcode the slider number/total into every slide, which isn't ideal.
The relevant Slider-Pro js used is:
$(document).ready(function($) {
$('.slider-pro').sliderPro({
width: '100%',
arrows: true,
fadeArrows: false,
buttons: false,
fade: true,
fadeDuration: 200,
thumbnailPosition: 'bottom',
thumbnailWidth: 75,
thumbnailHeight: 75,
autoplay: false,
fullScreen: false,
breakpoints: {
480: {
thumbnailWidth: 40,
thumbnailHeight: 40
}
}
});
$.each('.slider-pro', function() {
var slider = $('.slider-pro').data('sliderPro');
$('.slider-pro').append('<div class="counter"><span class="active">' + (parseInt(slider.getSelectedSlide()) + 1) +
'</span>/' + slider.getTotalSlides() + '</div>');
slider.on('gotoSlide', function(event) {
$('.slider-pro').find('.counter .active').text(event.index + 1);
});
});
});
I'm getting a console error:
TypeError: cannot use 'in' operator to search for 'length' in '.slider-pro'
I am using jquery-2.1.4.min.js
Any suggestions would be greatly appreciated.
Thanks so much!
It's a simple issue actually the code you have found is missing some other details regarding how it's being used; that code need to be used inside an object or event handler context so this will refer to the object but in your case you are trying to use it outside so there is no context for this therefore we can't use it as such.
Anyway as you have told you are new to jquery that's fine; what you need to do is instead of using this use the css selector directly if you are "outside", so you have
var slider = $('.slider-pro').data( 'sliderPro' );
// here this is not ok as it is "outside"
$('.slider-pro').append('<div class="counter"><span class="active">'+ (parseInt(slider.getSelectedSlide()) + 1)
+'</span>/'+slider.getTotalSlides()+'</div>');
slider.on('gotoSlide', function( event ) {
$(this).find('.counter .active').text(event.index + 1);
// here this is ok as it is "inside"
});
Update:
You were almost there but instead of using this each you were needed to use this each, the difference between the two is that the second one specially used for Dom nodes and you can use this magic inside to refer to each item without actually giving them any explicit property like ids
$('.slider-pro').each(function(index, element) {
//using $(element) instead of $(this) should work too
$(this).sliderPro({
//..options
});
var slider = $(this).data('sliderPro');
$(this).append('<div class="counter"><span class="active">' + (parseInt(slider.getSelectedSlide()) + 1) +
'</span>/' + slider.getTotalSlides() + '</div>');
slider.on('gotoSlide', function(event) {
$(this).find('.counter .active').text(event.index + 1);
// finds only the .counter and .active inside the current slider divsnot touching .counter and .active of other slider divs
});
});
A brief explanation would be, the $(selector).each(..) loops over all the Dom nodes that match the selector and gives you a context this that will always refer to the current item of the iteration but only within the scope of each function.For instance if matched items are a set of <div>s then you can refer to each <div> individually
I am working on a Wordpress shortcode for generating dynamically circles.
At my current version I have a problem with saving my current and my last hover state.
Here is a fiddle
I have a problem displaying the text under the circles. The text should be displayed from the last hovered circle until I hover over a new one.
Is there maybe a better solution to my problem?
I think my problem is in the hover end.
[...] ,function () {
$contentBoxPrevious = $contentBoxCurrent;
$contentBoxCurrent.removeClass('active-text');
$(this).removeClass('hover active');
}
Move this line
$contentBoxPrevious.removeClass('active-text');
from the handleOut function to the middle of handleIn function like this https://jsfiddle.net/eu0jcmh0/
What you were doing wrong was that you were removing the "active-text" class every time you moused out of the element instead of removed it when you moused on another element, hope I helped!
Your code looked way too complicated...
So I just rewrote it my way to achieve what I think you want as a result.
Here's the code:
$(document).ready(function() {
// Set all texts invisible
$(".text-content").css({
"opacity": 0
});
// Declare previous and active indexes vars
var previous_index;
var active_index;
$(".icon-circle").hover(function() {
// On mouseenter, getting this index.
active_index = $(this).data("index");
// Show associated text.
$(this).parent().find(".text-content").css({
"opacity": 1
});
// Hide previous associated text.
if (active_index != previous_index) {
$("[data-index='" + previous_index + "']").parent().find(".text-content").css({
"opacity": 0
});
}
}, function() {
// On mouseout, just keeping previous index...
previous_index = active_index;
});
});
Working Fiddle.
I am trying to create a slide effect using jquery. I want my images to have some text above them, which should fade out, then slide the image, then fade back in.
I was wondering if I can use an animate function inside another animate function, like this:
$('.slider-content').animate({
'opacity':'0'
},4000, function{
$('.slider-list').animate({
// fade("out");
'margin-left' : "+=" + left_indent
},4000,function(){
if(where == 'left') {
$('.slider-list li:first').before($('.slider-list li:last'));
} else {
$('.slider-list li:last').after($('.slider-list li:first'));
}
$('.slider-list').css({'margin-left' : '0px'});
fade("in");
});
});
});
I'm sorry if this question sounds stupid, but this came up while I was brainstorming for ideas. Is it possible?
The current code gives me an error on the third line, it says unexpected '}'.
Function should have parenthesis:
},4000, function(){
Forgive the strangely worded question, my first StackOverflow post, and I'm a novice to jQuery/JS. I've used the search feature a lot and haven't found exactly what I'm looking for:
I am having an issue essentially, where I have dynamically added divs by the end-user (they pick how many content blocks they want to use), with the same class, that need to hide and show specific divs (with unique IDs) when they are clicked. I finally figured out how to give each div a unique ID, but I'm not sure how to get the child divs of the particular div what was clicked, to fire properly on click. Hope that makes sense.
Here is the HTML I have:
<div class="resource-video">
//Unique thumbnail
</div>
<div class="overlay-container hide" style="width: 50px; height: 50px;">
<div class="video-player hide">
//Included unique video
</div>
</div>
This will end up being duplicated based on how many videos are added.
Here is the JavaScript I am using:
//Generates unique IDs for each of the divs on the page with those classes
var i = 0;
$(".resource-video").each(function(i){
$(this).attr("id","video_"+ (i+ 1) );
});
$(".overlay-container").each(function(i){
$(this).attr("id","container_"+ (i+ 1) );
});
$(".video-player").each(function(i){
$(this).attr("id","player_"+ (i+ 1) );
});
//Currently opens all of them
$(".resource-video").on("click", function(){
openModal(".overlay-container", false, true);
alert($(this).attr("id")); //Alerts the right div clicked
if ($(".video-player").hasClass("hide")){
$(".video-player").removeClass("hide").addClass("show");
$(".overlay-container").animate({ height:'300px', width: '500px' }, "slow");
}
$("#overlay").on("click", function(){
$(".video-player").removeClass("show").addClass("hide");
$(".overlay-container").css({ "height":"50px", "width":"50px",
"display":"none"});
$(this).hide();
});
return false;
});
// Probably not totally necessary, but just in case
function closeModals(){
$("body").find(".modal").hide();
$("#overlay").hide();
$("body, html").removeClass("no-scroll");
};
function openModal(divID, allowScroll, blockScreen){
closeModals();
$(divID).show();
if ( blockScreen == true ){ $("#overlay").show(); };
if ( allowScroll == false ){ $("body, html").addClass("no-scroll"); };
};
As it stands now, all of the overlays open because I am targeting the class not the IDs. Basically, I need to find out a way to have the specific overlay associated with the specific div clicked on to display without hardcoding that, since the number of divs will change all the time. I would think I could use something like $(this) or event.target, but things I tried didn't work.
Hopefully I was clear enough with my issue and made it general enough for other people to use too. Thanks for any help in advance!
This uses DOM traversal functions to find the corresponding DIVs to the one that was clicked.
$(".resource-video").on("click", function(){
var overlayContainer = $(this).next();
var videoPlayer = overlayContainer.children(".video-player");
openModal(overlayContainer, false, true);
if (videoPlayer.hasClass("hide")){
videoPlayer.removeClass("hide").addClass("show");
overlayContainer.animate({ height:'300px', width: '500px' }, "slow");
}
return false;
});
// Only need to bind this once, not every time .resource-video is clicked.
$("#overlay").on("click", function(){
$(".video-player").removeClass("show").addClass("hide");
$(".overlay-container").css({ "height":"50px", "width":"50px",
"display":"none"});
$(this).hide();
});
// Probably not totally necessary, but just in case
function closeModals(){
$(".modal").hide();
$("#overlay").hide();
$("body, html").removeClass("no-scroll");
};
function openModal(div, allowScroll, blockScreen){
closeModals();
div.show();
if ( blockScreen == true ){ $("#overlay").show(); };
if ( allowScroll == false ){ $("body, html").addClass("no-scroll"); };
};
I have the following jquery that slides a div horizontally:
$('.nextcol').click(function() {
$('.innerslide').animate({'left': '-=711px'}, 1000);
});
$('.prevcol').click(function() {
$('.innerslide').animate({'left': '+=711px'}, 1000);
});
What I want to happen is this... if the div.innerslide has a position that is left: 0px then I want to hide div.backarrow. If the position is not left: 0px, then it shows it.
Any help would be greatly appreciated.
EDIT (added HTML Markup)
<div class="backarrow prevcol">
<div id="mainleft" class="overflowhidden">
<div class="innerslide">
<div class="col">my content including next</div>
<div class="col">my content including next</div>
<div class="col">my content including next</div>
</div>
</div>
Try this:
if ($('.innerslide').css("left") == 0) {
$('div.backarrow').hide();
} else {
$('div.backarrow').show();
}
Fix for Double-Click Issue:
From what you described in your comment about the issue when the visitor double-clicks, it sounds like the double-click is causing two of the animation events to fire. To keep this from happening, you can either disable the click handler while the animation is running and re-enable it once it is finished, or you can try to write a new thread to continually check the element's position. One of these solutions is not a good idea - I'll let you figure out which one :) - but the other actually has a very simple solution that requires little change to your existing code (and may actually reduce your overhead by a teeny weeny amount):
$('.nextcol').on("click.next", function() {
$('.innerslide').animate({'left': '-=711px'}, 1000, showHideBack());
$(this).off("click.next");
});
$('.prevcol').on("click.prev", function() {
$('.innerslide').animate({'left': '+=711px'}, 1000, showHideForward());
$(this).off("click.prev");
});
Then add this this line to showHideBack() (and a complementary one to showHideForward() if you are using that):
$('.nextcol').on("click.next".....
I suggest that you write a function to set each click handler and another to remove each one. This will make your live very easy and the whole solution should reduce overhead by removing unnecessary click handlers while the animation is running.
Note: the animation method often calls its callback before the animation finishes. As such, you may wish to use a delay before calling the showHide... method(s).
Let me know if you have any questions. Good luck! :)
UPDATE:
Here is the updated version of the fiddle you gave me with all bugs ironed out. It looks like I misunderstood part of your goal in my original solution, but I straightened it out here. I have also included the updated jQuery, here:
var speed = 1000;
var back = $("div.backarrow");
var next = $(".nextcol");
var prev = $(".prevcol");
var inner = $(".innerslide");
function clickNext(index) {
next.off("click.next");
inner.animate({
'left': '-=711px'
}, speed, function() {
back.show(); //this line will only be hit if there is a previous column to show
next.delay(speed).on("click.next", function() {
clickNext();
});
});
}
function clickPrev() {
prev.off("click.prev");
inner.animate({
'left': '+=711px'
}, speed, function() {
if (inner.css("left") == "0px") {
back.delay(speed).hide();
prev.delay(speed).on("click.prev", function() {
clickPrev();
});
} else {
back.delay(speed).show();
prev.delay(speed).on("click.prev", function() {
clickPrev();
});
}
});
}
next.on("click.next", function() {
clickNext();
});
prev.on("click.prev", function() {
clickPrev();
});
I was going to also include a condition to check if you were viewing the last column, but, as I don't know what your final implementation will be, I didn't know if it would be applicable. As always, let me know if you need help or clarification on any of this. :)
You could try the step option — a callback function that is fired at each step of the animation:
$('.prevcol').click(function() {
$('.innerslide').animate({ left: '+=711px' },
{
duration: 1000,
step: function(now, fx) {
if (now === 0 ) {
$('div.backarrow').hide();
} else {
$('div.backarrow').show();
}
}
});
});
More examples of usage in this article The jQuery animate() step callback function