.effect('slide'... not showing next object - javascript

I was browsing around stackoverflow for slider and found this one http://jsfiddle.net/skram/tHZLY/2/ (Somehow I can't find the topic...)
code :
var $pages = $('.page');
$('#nxt').click(
function() {
var $cur = $('.active');
var $next = $cur.next();
if ($next.length == 0) return;
$cur.removeClass('active');
$next.addClass('active');
$('.page').not('.active').effect('slide',{direction:'right',mode:'hide'});
$('.active').effect('slide',{direction:'right',mode:'show'});
});
$('#prev').click(
function() {
var $cur = $('.active');
var $prev = $cur.prev('.page');
if ($prev.length == 0) return;
$cur.removeClass('active');
$prev.addClass('active');
$('.page').not('.active').animate({"width": 0}, "slow");
$('.active').animate({"width": 200}, "slow");
});
When I change .animate with .effect , next div is not showing.
JSFIDDLE with the change: http://jsfiddle.net/tHZLY/12/

The problem is that you're using 2 different methods to show/hide divs.
You should use either slide or width.
Width of not .active divs is initially set to 0px in CSS, so that they can be animated later on, using .animate({"width": 200}) . But it does not work with .effect('slide', ...) as it deos not actually affect the width property.
.animate({"width": 0}) does not make the element invisible, while you're applying .hide() on:
.effect('slide',{direction:'right',mode:'hide'});
Check this experiment .
To get this to work with .effect('slide', ...), you should remove width: 0px; from CSS of the divs, place all .page divs at one position (for demo purposes used simple position: absolute;) and do not mix 2 different show/hide methods on prev/next:
// hide not active divs:
$('.page:not(.active)').hide();
$('#nxt').click(function(){
var $cur = $('.page.active');
var $next = $cur.next('.page');
if ($next.length == 0) return;
$cur.removeClass('active').effect('slide',{direction:'left',mode:'hide'});
$next.addClass('active').effect('slide',{direction:'right',mode:'show'});
});
$('#prev').click(function() {
var $cur = $('.page.active');
var $prev = $cur.prev('.page');
if ($prev.length == 0) return;
// do not mix up .aniamte(width) with .effect(slide)!
$cur.removeClass('active').effect('slide',{direction:'right',mode:'hide'});
$prev.addClass('active').effect('slide',{direction:'left',mode:'show'});
});
DEMO

Related

A different approach to add/remove classes and animate elements

I have 5 list items, when one is clicked the only method I know is to animate all the elements then reanimate the selected element to the new width. Can anyone advise me how I can cut down this process so only the current active item gets animated and the class removed and then the new item gets animated and the active class added?
JS
var test = $('#test'),
test_li = test.children(),
small = 60,
large = 200;
test_li.on('click', function(e) {
if( !$(this).hasClass('active') ){
test_li.animate({ width: small }, 300).removeClass('active'); //animates every single li every time
$(this).animate({ width: large }, 300).addClass('active');
}
});​
Fiddle Here: http://jsfiddle.net/TSNtu/1/
var test = $('#test'),
test_li = test.children(),
small = 60,
large = 200;
test_li.on('click', function(e) {
// if clicked element is active itself then do nothing
if ($(this).hasClass('active')) return;
// remove active from others
$('.active', test).animate({
width: small
}, 300).removeClass('active');
// animate the clicked one
$(this).animate({
width: large
}, 300).addClass('active');
});
DEMO
With a single chain
var test = $('#test'),
test_li = test.children(),
small = 60,
large = 200;
test_li.on('click', function(e) {
// if clicked element is active itself then do nothing
if ($(this).hasClass('active')) return;
$(this) // clicked li
.animate({
width: large
}, 300)
.addClass('active')
.siblings('.active') // other li
.animate({
width: small
}, 300)
.removeClass('active');
});
DEMO

jQuery scroll to div on hover and return to first element

I basically have a div with set dimensions and overflow: hidden. That div contains 7 child divs (but only shows one at a time) that I would like to be smoothly scrolled through vertically when their respective links are hovered.
However, the first section (div) doesn't have a link and is the default section when no link is hovered.
Take a look at this jsFiddle to see a basic structure of what I'm talking about: http://jsfiddle.net/YWnzc/
I've attempted to accomplish this with jQuery scrollTo but haven't been able to get it to work.
Any help would be greatly appreciated. Thanks.
Something like this?
http://jsfiddle.net/YWnzc/5/
code:
jQuery("#nav").delegate("a", "mouseenter mouseleave", function (e) {
var i, self = this,
pos;
if (e.type == "mouseleave") {
i = 0;
}
else {
//Find out the index of the a that was hovered
jQuery("#nav a").each(function (index) {
if (self === this) {
i = index + 1; //the scrollTop is just calculated from this by a multiplier, so increment
return false;
}
});
}
//Find out if the index is a valid number, could be left undefined
if (i >= 0) {
//stop the previous animation, otherwise it will be queued
jQuery("#wrapper").stop().animate({
scrollTop: i * 200
}, 500);
//I would retrieve .offsetTop, but it was reporting false values :/
}
e.preventDefault();
});
FYI : That JSFIDDLE you sent me to went to MooTools framework, not jQuery... fyi. (might be why its not working?
Copy and paste this code exactly and it will work in jQuery for animated scrolling.
Try this for smooth scrolling within the DIV, I tested it - it works great. You
$(function() {
function filterPath(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
}
var locationPath = filterPath(location.pathname);
var scrollElem = scrollableElement('#wrapper');
// Any links with hash tags in them (can't do ^= because of fully qualified URL potential)
$('a[href*=#]').each(function() {
// Ensure it's a same-page link
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath
&& (location.hostname == this.hostname || !this.hostname)
&& this.hash.replace(/#/,'') ) {
// Ensure target exists
var $target = $(this.hash), target = this.hash;
if (target) {
// Find location of target
var targetOffset = $target.offset().top;
$(this).click(function(event) {
// Prevent jump-down
event.preventDefault();
// Animate to target
$(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
// Set hash in URL after animation successful
location.hash = target;
});
});
}
}
});
// Use the first element that is "scrollable" (cross-browser fix?)
function scrollableElement(els) {
for (var i = 0, argLength = arguments.length; i <argLength; i++) {
var el = arguments[i],
$scrollElement = $(el);
if ($scrollElement.scrollTop()> 0) {
return el;
} else {
$scrollElement.scrollTop(1);
var isScrollable = $scrollElement.scrollTop()> 0;
$scrollElement.scrollTop(0);
if (isScrollable) {
return el;
}
}
}
return [];
}
});
FYI : Credit for this code does not go to me as an individual developer, although I did slightly tweak the code. The owner and creator of this code is Chris Coyier and you can find more about this scrolling code here:
http://css-tricks.com/snippets/jquery/smooth-scrolling/
Here's a working example: http://jsfiddle.net/YWnzc/7/
And the code (pretty similar to rizzle's, with a couple changes that I'll explain):
$('a').hover(function(){
var selector = $(this).data('section');
var scrollAmount = $(selector).offset().top + $('#wrapper')[0].scrollTop - 129;
$('#wrapper').animate({scrollTop: scrollAmount}, 250);
},function(){
$('#wrapper').animate({scrollTop: 0}, 250);
});
First, var selector = $(this).data('section'); because in jsFiddle, the href attribute was returning the full path of the page + the hash. So I changed it to an html5 data attribute (data-section).
The next line is similar to rizzle's, except that we grab the offset of the section and add it to the current scrollTop value of the #wrapper. As he pointed out, there are some weird offset issues going on still, and I found that subtracting 129 did the trick. While this 129 number might seem like something that is likely to break, I did test out changing the sizes of the sections, making them not equal, etc, and it continued to work. I'm using Chrome, and perhaps a non-webkit browser would need a different constant to subtract. But it does seem like that 129 number is at least some kind of constant.
The rest should be pretty self-explanatory.
One thing to note: as you move your cursor over the <a> tags, the content of the #wrapper div will seem to jump around, but that's just because the mouseleave part of the hover event briefly gets triggered as the cursor moves. I'm sure you can solve that one though :)
$("#nav a").hover(function () {
var sectionName = $(this).attr("href");
var sectionPos = $(sectionName).offset().top;
var wrapperPos = $("#wrapper").offset().top;
var wrapperScroll = $("#wrapper").scrollTop();
var scrollPos = sectionPos - wrapperPos + wrapperScroll;
$("#wrapper").stop().animate({scrollTop:scrollPos}, 600);
}, function () { $("#wrapper").stop().animate({scrollTop:0}, 600); });

Accessible and dynamic animated information box

I have started with the example and added to the code to make it:
Dynamic in height
Accessible with JS turned off
Have I done this correct? Will this work on most browsers?
Working version visable here:
Original:
$('#example-links a').hover(function(){
var index = $("#example-links a").index(this);
$('#example-content').animate({"marginTop" : -index*220 + "px"}); // multiply by height+top/bottom padding/margin/border
});
My modified code, it just seems a little long compared to the above:
var maxHeight = 0, container_maxHeight = 0;
var example_content = $("#example-content");
var example_div = example_content.children("div");
example_div.each(function() {
if($(this).height() > maxHeight) {
maxHeight = $(this).height();
container_maxHeight = $(this).outerHeight(true);
}
});
example_div.height(maxHeight);
$("#example-content-container").css({
"overflow":"hidden",
"height": container_maxHeight+"px"
});
$('#example-links a').bind('click mouseover', function(e){
var index = $("#example-links a").removeClass("active").index(this);
$(this).addClass("active");
example_content.stop().animate({"marginTop" : -index*container_maxHeight + "px"});
e.preventDefault();
});
I bind both the click and mouseover because I want it to work via mouseover but then I also want it to work when browsing on a mobile phone that doesn't have a mouse to activate the hover.
Everything seems fine, the only thing I would add to make it more accessible if JS is off, are the section ids. You can check it here.
For each section, you add an id to the wrapping div, and then on your side links you link to that id.
I would clean up your code a little bit more:
(function($){
$(document).ready(function(){
var maxHeight = 0, container_maxHeight = 0,
example_content = $("#example-content"),
example_div = example_content.children("div");
example_div.each(function() {
var $section = $(this);
if($section.height() > maxHeight) {
maxHeight = $section.height();
container_maxHeight = $section.outerHeight(true);
}
});
example_div.height(maxHeight);
$("#example-content-container").height(container_maxHeight);
var $tabs = $('#example-links a');
$tabs.bind('click mouseover', function(e){
var index = $tabs.removeClass("active").index(this);
$(this).addClass("active");
example_content.stop().animate({"marginTop" : -index*container_maxHeight + "px"});
e.preventDefault();
});
});
})(jQuery);

Help with modifying my custom JQuery slider to allow continous scrolling

You can view my custom slider here: http://www.awaismuzaffar.com/examples/index.html
And below is the JQuery code for it:
$(document).ready(function() {
// Slider Function
var slideWidth = $('div.slide').width();
// Set the left position of each div element
$('div.slide').each(function(index){
$(this).css('left', index * slideWidth ); // Multiply each div element by the index(0, 1 etc) so each div is placed inline
});
// Next step is to animate the div elements
var clickCount = 1;
var slideCount = $('div.slide').length;
// Set the previous button to hide when loading with the first slide
if(clickCount == 1){
$('a#previous-button').css('background-color', '#cccccc');
}
$('a#next-button').click(function() {
if(clickCount < slideCount) {
$('div.slide').animate({"left":"-=" + slideWidth}, 'slow');
$('a#previous-button').css('background-color', '#ffffff');
clickCount++;
}
if(clickCount == slideCount) {
$('a#next-button').css('background-color', '#cccccc'); // Hide or grey out button
}
});
$('a#previous-button').click(function() {
if(clickCount > 1){
$('div.slide').animate({"left":"+=" + slideWidth}, 'slow');
$('a#next-button').css('background-color', '#ffffff');
clickCount--;
}
if(clickCount == 1){
$('a#previous-button').css('background-color', '#cccccc'); // Hide or grey out button
}
});
});
I am trying to modify this slider to allow continous scrolling.
I am not sure exactly how to achieve this, I am assuming I need to use append, but I am not sure how to make use of it.
Thanks.
You're doing things a little manually, I'm thinking someone else might've solved the problem. But in any case, in your click next button, you'd need to load in additional content when you hit the end. So if I were you, I'd do something like this:
$('a#next-button').click(function() {
...
if(clickCount == slideCount) {
$('a#next-button').css('background-color', '#cccccc');
$.get(moreContentUrl, objectRepresentingCurrentScrollPosition, loadContent);
spinner.show(); // show some kind of spinner here (you can also hook up a default spinner on all ajax events with a global ajax handler
}
});
function loadContent(response) {
// append your content (your controller should return just the <div class="slide" /> elements, and give them a class="slide newSlide" so you can distinguish them below
// you can also do client side templating here. would be more efficient, then just return the items as objects instead of html
$('#slide-container').append(response.itemsHtml);
// slide all new divs right
$('div.newSlide').animate({"left":"+=" + slideWidth}, 'fast');
$('div.newSlide').removeClass('newSlide');
// update variables and un-grey the next button
$('a#previous-button').css('background-color', '#ffffff');
slideCount += response.itemCount;
// hide the spinner shown when starting the load
spinner.hide();
}
Give it a shot, hope it works. Now, to clean up that code a little bit, I'd suggest using css classes instead of inline background colors, etc.
Here's a solution (somewhat like Shaz's), just less code :):
$(document).ready(function(){
$('#previous-button').click(function(){slidePanel(-1)});
$('#next-button').click(function(){slidePanel(1)});
var n = 0;
var animating = false;
$('#slide-'+n).css('display', 'block');
function slidePanel(delta)
{
if(!animating)
{
animating = true;
var d = (delta > 0 ? $('#slide-'+n).width()*-1 : $('#slide-'+n).width());
$('#slide-'+n).animate({
left: "+="+d
}, 'slow', function() { $(this).css('display', 'none'); animating = false; });
n = (n + delta) % $('div.slide').length;
n = n < 0 ? $('div.slide').length + n : n;
$('#slide-'+n).css('left', $('#slide-container').offset().left +(d*-1));
$('#slide-'+n).css('display', 'block');
$('#slide-'+n).animate({
left: 0
}, 'slow');
}
}
});
Check out the sample here.
(I know there's a way to figure out the "current slide" with a one liner equation, but I think I'm brain dead atm :P)
(Edited to account for repeatedly clicking)
Try something like this: http://fiddle.jshell.net/Shaz/dsBkf/

How do I drag multiple elements at once with JavaScript or jQuery?

I want to be able to drag a group of elements with jQuery, like if I selected and dragged multiple icons on the Windows desktop.
I found the demo of threedubmedia's jQuery.event.drag:
http://threedubmedia.com/code/event/drag/demo/multi
http://threedubmedia.com/code/event/drag#demos
I think this plugin is great. Is this good and popular library? Do you know websites or applications which use it?
Are there any other libraries or plugins to drag multiple objects?
Can jQuery UI drag multiple objects?
var selectedObjs;
var draggableOptions = {
start: function(event, ui) {
//get all selected...
selectedObjs = $('div.selected').filter('[id!='+$(this).attr('id')+']');
},
drag: function(event, ui) {
var currentLoc = $(this).position();
var orig = ui.originalPosition;
var offsetLeft = currentLoc.left-orig.left;
var offsetTop = currentLoc.top-orig.top;
moveSelected(offsetLeft, offsetTop);
}
};
$(document).ready(function() {
$('#dragOne, #dragTwo').draggable(draggableOptions);
});
function moveSelected(ol, ot){
console.log(selectedObjs.length);
selectedObjs.each(function(){
$this =$(this);
var pos = $this.position();
var l = $this.context.clientLeft;
var t = $this.context.clientTop;
$this.css('left', l+ol);
$this.css('top', t+ot);
})
}
I am the author of the of the threedubmedia plugins. I added this functionality for supporting multiple elements, because I could not find a satisfactory solution anywhere else.
If you need a solution that works with the jQuery UI, here is a plugin which adds some multi-drag functionality, though the demos don't seem to work correctly in Firefox for Mac.
http://www.myphpetc.com/2009/11/jquery-ui-multiple-draggable-plugin.html
This worked for me.
Fiddle here:
var selectedObjs;
var draggableOptions = {
start: function(event, ui) {
//get all selected...
if (ui.helper.hasClass('selected')) selectedObjs = $('div.selected');
else {
selectedObjs = $(ui.helper);
$('div.selected').removeClass('selected')
}
},
drag: function(event, ui) {
var currentLoc = $(this).position();
var prevLoc = $(this).data('prevLoc');
if (!prevLoc) {
prevLoc = ui.originalPosition;
}
var offsetLeft = currentLoc.left-prevLoc.left;
var offsetTop = currentLoc.top-prevLoc.top;
moveSelected(offsetLeft, offsetTop);
selectedObjs.each(function () {
$(this).removeData('prevLoc');
});
$(this).data('prevLoc', currentLoc);
}
};
$('.drag').draggable(draggableOptions).click(function() {$(this).toggleClass('selected')});
function moveSelected(ol, ot){
console.log("moving to: " + ol + ":" + ot);
selectedObjs.each(function(){
$this =$(this);
var p = $this.position();
var l = p.left;
var t = p.top;
console.log({id: $this.attr('id'), l: l, t: t});
$this.css('left', l+ol);
$this.css('top', t+ot);
})
}
Thanks to ChrisThompson and green for the almost-perfect solution.
I wanted to add (this coming up high in google), since none of the plugins in this thread worked and it is not nativity supported by jquery ui, a simple elegant solution.
Wrap the draggable elements in a container and use an event to drag them all at once, this allows for singles draggables and multidraggables (but not really selective draggables).
jQuery(document).click(function(e) {
if(e.shiftKey) {
jQuery('#parent-container').draggable();
}
});
Check this out:
https://github.com/someshwara/MultiDraggable
Usage:$(".className").multiDraggable({ group: $(".className")});
Drags the group of elements together. Group can also be an array specifying individual elements.
Like:$("#drag1").multiDraggable({ group: [$("#drag1"),$("#drag2") ]});
Put your items into some container and make this container draggable. You will need to set handle option to be a class of your item element. Also you will need to recalculate items position after drag. And obviously when you deselect items you have to take them from this container and put back to their origin.
This is what i used, Worked in my case.
function selectable(){
$('#selectable').selectable({
stop: function() {
$('.ui-selectee', this).each(function(){
if ($('.ui-selectee').parent().is( 'div' ) ) {
$('.ui-selectee li').unwrap('<div />');
}
});
$('.ui-selected').wrapAll('<div class=\"draggable\" />');
$('.draggable').draggable({ revert : true });
}
});
};
there is Draggable in the jquery UI
all you would have to do is:
$(selector).draggable(); // and you are done!
see example here: http://jsfiddle.net/maniator/zVZFq/
If you really want multidragging you can try using some click events to hold the blocks in place
$('.drag').draggable();
$('.drag').click(function(){
console.log(this, 'clicked')
var data = $(this).data('clicked');
var all = $('.all');
if(data == undefined || data == false){
$(this).data('clicked', true);
this.style.background = 'red';
$(this).draggable('disable');
if(all.children().length <= 0){
all.draggable().css({
top: '0px',
left: '0px',
width: $(window).width(),
height: $(window).height(),
'z-index': 1
});
}
var top = parseInt(all.css('top').replace('px','')) +
parseInt($(this).css('top').replace('px',''))
var left = parseInt(all.css('left').replace('px','')) +
parseInt($(this).css('left').replace('px',''))
$(this).css({
top: top,
left: left
})
$('.all').append($(this));
}
else {
$(this).data('clicked', false);
this.style.background = 'grey';
$(this).draggable('enable');
$('body').append($(this));
if(all.children() <= 0){
all.draggable('destroy');
}
/*
var top = parseInt(all.css('top').replace('px','')) -
parseInt($(this).css('top').replace('px',''))
var left = parseInt(all.css('left').replace('px','')) -
parseInt($(this).css('left').replace('px',''))
$(this).css({
top: top,
left: left
})*/
}
})
See example here: http://jsfiddle.net/maniator/zVZFq/5

Categories

Resources