I want to limit max height of animation when using arrows to switch. Trying to write a function, that will calculat height of div and +- step in px. But it's now writed to variable.
var maxfloorh = $('.floor-switch').height();
var actualh = $('.floor-switch').height();
$('.floor-switch li').click(function() {
$('#line').animate({
top: $(this).position().top
});
});
function floorarrs(numbr) {
switch (numbr) {
case 1:
//check here maxfloorh
$('#line').animate({
top: '-=18'
}, 400, function() {
maxfloorh-'18';
console.log(maxfloorh);
});
break
case 2:
//check here maxfloorh
$('#line').animate({
top: '+=18'
}, 400, function() {
maxfloorh+'18';
console.log(maxfloorh);
});
break
}
}
$('.arrw-up').click(function() {
floorarrs(1);
});
$('.arrw-dwn').click(function() {
floorarrs(2);
});
HTML:
<div id="floors" style="margin:60px;">
<div class="arrw-up"></div>
<div class="floor-switch">
<div id='line'></div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<div class="arrw-dwn"></div>
</div>
Live: http://jsfiddle.net/cxvec/2/
$('.arrw-up').click(function() {
if ($("#line").css("top") !== "0px") {
floorarrs(1);
}
});
$('.arrw-dwn').click(function() {
if ($("#line").css("top") !== ""+($("#pagination li").length-1)*18+"px") {
floorarrs(2);
}
});
Here is the working fiddle
I have changed the logic in your arrow click function, In css the initial top attribute of the element with id=line is set to 0px
...Now whenever the top = 0px -> the div is on 1st li hence the function is not executed ans so for the down arrow...
Note: This may note be the best solution but it's one of the solutions
Related
im creating custom toggle animation on the list of bank while onlick it will toggle down and toggle up. However my code is working but it doesn't show up like an animation form. it just close and down directly without sliding slowly. Kindly advise :
I wish to toggle down for 200 height and toggle up for 102 height
jQUERY :
$(document).ready(function(){
$(".moreBankingBtn").click(function(){
$('.bank_listSetUp').toggleClass('bank_listSetTall'); // Will add/remove class on each click
});
});
HTML :
<div name="bankDisplay2" class="bank_list_main">
<ul data-bind="foreach: thirdPayBank" class="bank_list bank_listSetUp">
<li data-bind="attr:{'data-key':key, 'data-code':bankcode}, css: memberModel.netbankCssClass($data), click: $root.netBankSelectBank" data-key="工商银行" data-code="ICBC" class="bank_2"></li>
<li data-bind="attr:{'data-key':key, 'data-code':bankcode}, css: memberModel.netbankCssClass($data), click: $root.netBankSelectBank" data-key="农业银行" data-code="ABC" class="bank_3"></li>
</ul>
</div>
CSS :
.bank_listSetUp {
height: 102px;
}
.bank_listSetTall {
height: 200px;
}
You can use JQuery UI and change your code to something like
$('.bank_listSetUp').toggleClass('bank_listSetTall',500);
Here 500 is the duration of animation.
I would also suggest you to have a look at sideToggle() function http://api.jquery.com/slidetoggle/
i found an solution for this ,
jQUERY :
$(document).ready(function(){
var open = false;
var bankListMain = $("#thirdPayForm .bank_list_main");
var ul = bankListMain.find("ul");
var button = bankListMain.find("span");
button.click(function () {
open = !open;
var height;
if (open) {
height = "200px";
button.addClass("bank_hide");
} else {
height = "102px";
button.removeClass("bank_hide");
}
TweenMax.to(ul, 0.5, { css: { height: height } });
});
});
NOTE : add tweenmax.js to make it work
try slideToggle()
$(document).ready(function(){
$(".moreBankingBtn").click(function(){
$('.bank_listSetUp').slideToggle();
});
})
It doesn't look like it's animating because you're not using the jquery animate function or the slide toggle function, although since you want to animate to two different heights you can't really use the slide functions, because I believe that's just to display and hide. Maybe try this:
$(document).ready(function(){
$(".moreBankingBtn").click(function(){
If ($('.bank_list').hasClass('bank_listSetUp')){
$('.bank_list').animate({
height: 200,
}, 'slow').promise().done(function(){
$('.bank_list').removeClass('bank_listSetUp').addClass('bank_listSetTall');
});
}
else {
$('.bank_list').animate({
height: 120,
}, 'slow').promise().done(function(){
$('.bank_list').addClass('bank_listSetUp').removeClass('bank_listSetTall');
}
});
});
Check my PLNKR, as you can see in plunker:
Menus are overflowing.
'moveLeft' and 'moveRight' button will shift menus by -/+ 1.
If you reach to first and last menu, corresponding 'moveLeft' and 'moveRight ' will be disabled.
Earlier for menucontainer class I was using overflow:hidden so menus were not oveflowing, but overflow:hidden was getting applied to child level menus also, they were cutting.
So finally I decided to remove overflow:hidden from menucontainer class.
So i thought of counting menus and making visible only required 3 menus and hiding all other. Things I am trying to achieve :
Let's assume currently 3 menus which are in middle are 444 555 666
At a time 3 menus will be visible, all others will be hidden.
clicking 'moveRight' will shift menus by +1, i.e. 555 666 777 will be visible and rest all will be hidden.
clicking on 'moveLeft' will shift menus by -1, i.e. 333 444 555 will be visible and rest all will be hidden.
Is this achievable with javascript? I am new to js any assitacne will be highly appreciate.
Note: My web page is very complex, plunker is just showing problem in simplest way.
Please dont suggest to give overflow:hidden
HTML Code
<div>
<input ng-click="myStyle={'margin-left': moveLeft()}" ng-show="menuItems > 3" ng-disabled="leftdisabled" class="left leftbtnposition" type="button" value="Move Left" />
<div class="menucontainer left">
<ul ng-style="myStyle">
<li ng-repeat="item in items"> {{item.name}}
</li>
</ul>
</div>
<input ng-click="myStyle={'margin-left': moveRight()}" ng-show="menuItems > 3" ng-disabled="rightdisabled" class="left rightbtnposition" type="button" value="Move Right" />
</div>
CSS
.menucontainer
{
width:300px;
margin-left:200px;
/* overflow:hidden;*/ not using this property now
}
.menucontainerhidden
{
width:300px;
margin-left:200px;
}
.leftbtnposition
{
position:absolute;
left:138px;
}
.rightbtnposition
{
position:absolute;
left:510px;
}
The best way I can think to do this with your current set up is to apply a class to the items that you want to be hidden based off what is currently in the selected 3 items.
I added a $scope.leftMost variable to monitor the index in $scope.items is on the left of the visible area.
Then added a boolean to each $scope.items element called isVisible.
In the html file we add an ng-class that toggles a class based on this boolean ng-class="{ hidden: !item.isVisible}"
Then based off the moveLeft and moveRight methods you have already defined we use the $scope.leftMost variable to toggle the isVisible boolean as needed.
A little CSS magic for the .hidden class thrown in as well.
.menucontainer .hidden{
opacity:0;
visibility:hidden;
}
PLUNKER
ADDITIONAL
Further to OP's comment, you can parse your returned data as it comes back into your service. For example:
.factory('MenuItems', ['$http', function ($http) {
var factory = {};
var addVisible = function(menuItems){
for(var x = 0; x < menuItems.videos.length; x++){
var menuItem = menuItems[x];
if(x < 3){
menuItem.isVisible = true;
}else{
menuItem.isVisible = false;
}
}
return menuItems;
}
factory.get = function () {
var path = '/menuItemUrl/';
return $http.get(path).then(function (resp) {
if(resp.data.length){
return addVisible(resp.data[0]);
}
});
};
return factory;
}])
Like this?
I modified the fiddle you posted in your comment(http://jsfiddle.net/j23LbLko/)
You can change the animation to whatever delay you want, it is currently set to 0.
JS
var myMargin = 112;
var numberOfVisibleItems = 3;
var numberOfItems = $('#menulist').children('li').length;
$('.left').click(function () {
if (parseInt($('#menulist').css('margin-left'), 10) >= -(myMargin * (numberOfItems - (numberOfVisibleItems + (numberOfVisibleItems - 2))))) {
$('#menulist').animate({
'marginLeft': "-=" + myMargin + "px" //moves left
}, 0, function () {
hideItems();
});
}
});
$('.right').click(function () {
if (parseInt($('#menulist').css('margin-left'), 10) >= 0) {
$('#menulist').css('margin-left', '0px!important');
} else {
$('#menulist').animate({
'marginLeft': "+=" + myMargin + "px" //moves right
}, 0, function () {
hideItems();
});
}
});
hideItems();
function hideItems() {
var currentMarginLeft = parseInt($('#menulist').css("margin-left"), 10);
var index = Math.abs(currentMarginLeft / myMargin);
$('#menulist').children('li').css("visibility", "hidden");
for (var i = 0; i < numberOfVisibleItems; i++) {
$('#menulist').children('li').eq(index + i).css("visibility", "visible");
}
}
EDIT (below)
Now just to let you know, both answers provided at the current time (my own and that of haxxxton) both have elements that are simply hidden from view. This means that when the items move left and right on the screen, your entire webpage's scrolling changes (left to right). This is because the elements still exist and are simply hidden from sight. Your best option would be to use the jsfiddle I included in my earlier comment (this one) and change the following values:
In the CSS: #outer { width:448px; } to #outer { width:336px; }
In the JS (in the left click event): if (parseInt($('#menulist').css('margin-left'), 10) >= -784) to if (parseInt($('#menulist').css('margin-left'), 10) >= -896)
JS
$('.left').click(function () {
if (parseInt($('#menulist').css('margin-left'), 10) >= -784) {
$('#menulist').animate({
'marginLeft': "-=112px" //moves left
});
}
});
$('.right').click(function () {
if (parseInt($('#menulist').css('margin-left'), 10) >= 0) {
$('#menulist').css('margin-left', '0px!important');
} else {
$('#menulist').animate({
'marginLeft': "+=112px" //moves right
});
}
});
I have a 'sticky sidebar nav' that is positioned absolutely relative to the #sidebar div, so it follows the page down on the left hand side and is always available. To make this work I had to add a height to the sidebar, so I used some code to find the height of the container dynamically. This is the code i used:
<script type="text/javascript">
function matchColHeights(col1, col2) {
var col1Height = $(col1).height();
var col2Height = $(col2).height();
if (col1Height > col2Height) {
$(col1).height(col2Height);
} else {
$(col1).height(col2Height);
}
}
$(document).ready(function() {
matchColHeights('#sidebar', 'section#main-container');
})
</script>
Currently the #sidebar div sits inside the section called section#maincontainer. A very simplified version of the html is below.
<body>
<header>Header content</header>
<section id="main-container">
<div id="sidebar">
<ul>
This is the floated ul
<ul>
</div>
<div class="content">
This is where the content of the page sits
</div>
<div class="content2">
This is where the content of the page sits (because of the design there are often more than one divs floated right
<div>Within the content divs are potential expanding divs (accordions and tabs that change size)</div>
</div>
</section>
<footer>Footer content</footer>
</body>
So the problem I have is that there is expandable content (tabs and accordions) in the content area, and when the content expands, the jQuery does not update the height of the sidebar to the new height (this new height could be shorter or longer than the original height). I have tried adding the function to my .click() handler of the accordion (haven't yet tried with the tabs) but here is the code that is used to drop my accordion down:
<!--Content Accordion-->
<script type="text/javascript">
$(document).ready(function() {
$('div.content-accordion> div').hide();
$('div.content-accordion> h4').click(function() {
var $nextDiv = $(this).next();
var $visibleSiblings = $nextDiv.siblings('div:visible');
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast');
$matchColHeights('#sidebar', 'section#main-container');
});
} else {
$nextDiv.slideToggle('fast');
$matchColHeights('#sidebar', 'section#main-container');
}
});
});
</script>
As you can see I can add the $matchColHeights('#sidebar', 'section#main-container'); function into the click function and it doesn't refresh to the new height still. I have tried a few other possibilities with no luck.
Just to let everyone know i found a solution...Took alot of messing about but code is below.
I essentially on the click had to set sidebar height back to 0, and create a function that finds the new height of the section#main-container, and then applys that as a css height to the sidebar. This changed the height of the sidebar just fine, but then the sticky sidebar wasnt readjusting to the new height, so i just pasted the code that works my sticky sidebar (the code that starts with $("aside") into the function and it refreshes just fine. Thanks to those that helped.
<!--Content Accordian-->
<script type="text/javascript">
$(document).ready(function() {
$('div.content-accordian> div').hide();
$('div.content-accordian> h4').click(function() {
var $nextDiv = $(this).next();
var $visibleSiblings = $nextDiv.siblings('div:visible');
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast', function() {
// START CHANGE SIDEBAR HEIGHT
$("#sidebar").css({ height: 0});
newheight = $("section#main-container").height();
$("#sidebar").css({ height: newheight});
$("aside").stickySidebar({
timer: 500
, easing: "easeInOutQuint"
, constrain: true
});
});
// END CHANGE SIDEBAR HEIGHT
});
} else {
$nextDiv.slideToggle('fast', function() {
// START CHANGE SIDEBAR HEIGHT
$("#sidebar").css({ height: 0});
newheight = $("section#main-container").height();
$("#sidebar").css({ height: newheight});
$("aside").stickySidebar({
timer: 500
, easing: "easeInOutQuint"
, constrain: true
});
});
// END CHANGE SIDEBAR HEIGHT
}
});
});
</script>
I believe you could write
if (col1Height !== col2Height) {
$(col1).height(col2Height);
}
instead of
if (col1Height > col2Height) {
$(col1).height(col2Height);
} else {
$(col1).height(col2Height);
}
But that won't solve your problem.
You probably have to fire that matchColHeights() function from inside a callback like this:
if ($visibleSiblings.length ) {
$visibleSiblings.slideUp('fast', function() {
$nextDiv.slideToggle('fast', function() {
$matchColHeights('#sidebar', 'section#main-container');
});
});
} else {
$nextDiv.slideToggle('fast', function() {
$matchColHeights('#sidebar', 'section#main-container');
});
}
Let me know if it worked.
here's the snippet of my code :
<ul>
<li>Home</li>
<li>Links</li>
<li>Contact</li>
</ul>
I use css to style them horizontally (menu-like) and what I would like to do is to animate all the list-items of the <ul> element. I top them when the dom is ready and animate them to the bottom to attract users' eyes when the entire page is loaded.
here's the jquery code:
$(function(){
$("ul li").css('top', '-40px'); //items are in relative position
$(window).bind("load", items_animate, false);
});
function items_animate(){
... //I'd like to animate each <li> of the <ul> changing 'top' to '0px' but not simultaneously, I want to declare a DELAY between each animation (<li>'s get down in a row)
}
I know how to sequence effects with queue() or calling functions one by one but on only one element, I'm lost in this case..
EDIT : for those who are interested, here's the code to accomplish this sequence, thanks to Joseph
var animationDelay = 600;
var offset = 200;
function blah(meh) {
setTimeout(function(){
$(meh).animate({
opacity: "0"
}, animationDelay);
},$(meh).index() * offset)
}
$("li").each(function(){
blah(this);
})
Demo
Here is another way (using opacity for clarity) that animates the list items in series with a delay in between.
<ul>
<li>Home</li>
<li>Links</li>
<li>Contact</li>
</ul>
var animationDelay = 600;
var offset = 200;
function blah(meh) {
setTimeout(function(){
$(meh).animate({
opacity: "0"
}, animationDelay);
},$(meh).index() * offset)
}
$("li").each(function(){
blah(this);
})
*pardon the less than original names... it's late :P
function slide_down_recursive(e,duration,callback)
{
$(e).animate(
{
top: '0px'
}, duration, 'linear',function()
{
if($(e).next().length == 0)
{
if(typeof(callback) == 'function')
{
callback();
}
return;
}
else
{
// Apply recursion for every sibling.
slide_down_recursive($(e).next(),duration,callback);
}
});
} // End slide_down_recursive
slide_down_recursive($('li:first-child'),500);
Here is a demo: http://jsfiddle.net/rpvyZ/
Try something like this:
$(function() {
function animateSequentially(element, properties, duration) {
element.animate(properties, duration, function() {
animateSequentially(element.next(), properties, duration);
});
}
animateSequentially($("ul > li:first-child"), {top: '0'}, 1000);
});
Edit: If you'd like them to animate sequentially but not wait for the previous one, you can try this:
$(function() {
$("ul > li").each(function(index, item) {
setTimeout(function() {
$(item).animate({top: '0'}, 500);
}, index*175);
});
});
Try the one that waits here, or the one that doesn't wait here.
Use .animates callback function to animate the next element.
$('li:eq(0)').animate({
top: "0px"
}, 5000, function() {
$('li:eq(1)').animate({
top: "0px"
}, 5000, function() {
...
});
});
as of this request, I wrote a jQuery plugin to walk sequencially through a list of (any) elements and applying css changes.
You can checkout the Plugin here:
https://github.com/ieservices/frontend-components/tree/master/jQuery/Plugins/jquery.list-effects
There I made it quite easy to apply those effects by defining the list and the effect options as a JavaScript object. For the first version I created the possiblity to define the delay of the changes between the elements as well as the options to define a starting index to define on which element the changes should be applied.
With the plugin you can do something like this:
<div id="myList">
<h4>This is my list</h4>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
By applying css stylesheet changes by rotating through the list elements:
jQuery('#myList ul li').listEffect(
{delay: '2000', attribute: 'color', value: '#ccc'}
);
Also I created and a demo in the repo, which is available here:
https://github.com/ieservices/frontend-components/blob/master/jQuery/Plugins/jquery.list-effects/demo/list-effects-demo-simple.html
So, far it can't do much, but what do you guys think of that Plugin?
I'm working on a portfolio site for an iPhone developer. In this site the iPhone app icons will act as a toggle buttons for panels that describe the application. The panels animate over the main page content. To add to this, if a panel is open and another app icon is clicked the open panels will need to close and the next app will open. Currently the script I have works great for toggling a single panel, see here: http://cncpts.me/dev/
So how can change the current script so it accepts multiple ids or classes, without creating duplicate code?
Here is the jQuery that is driving the functionality for a single toggle action.
$(document).ready(function() {
$("li.panel_button").click(function(){
$("div#panel").animate({
height: "700px"
})
.animate({
height: "600px"
}, "slower");
$("div.panel_button").toggle('zoom'); return false
});
$("div#hide_button").click(function(){
$("div#panel").animate({
height: "0px"
}, "slower"); return false
});
});
Here is the HTML:
<div id="panel">
<div id="panel_contents"></div>
<img src="images/iphone.png" border="0" alt="iPhone Development">
<div class="panel_button" id="hide_button" style="display: none;">
<img src="images/collapse.png" alt="collapse" />
</div>
</div>
give the list items a rel attribute that points to the div you are trying to show/hide.
<li rel='#panel_1' class='panel_button'>
give all the div's a common class such as 'flyaway', do a hide on any div with the same class that is not currently hidden
$('.flyaway').not(':hidden').animate({ height: "0px"}, "slower");
and show the one you want
$("li.panel_button").click(function(){
$($(this).attr('rel')).animate({
height: "700px"
})
.animate({
height: "600px"
}, "slower");
$($(this).attr('rel')+" div.panel_button").toggle('zoom'); return false
});
Here is my solution:
// Plugtrade.com - jQuery Plugin :: Bounce //
// answer for http://stackoverflow.com/questions/5234732/jquery-multiple-panel-toggle
jQuery.fn.bounce = function (el, bounceheight) {
var thisdiv = this;
var owidth = thisdiv.width();
var oheight = thisdiv.height();
var trigger = $(el);
// what we want is to make a parent div and then
// get the child div's dimensions and copy it's position
// display, width and height //
// child then becomes an absolute element nested within the
// parent div.
thisdiv.wrap('<div class="bounceparent"></div>');
// let's make a hidden button
thisdiv.append('<input type=text class="bouncehide" style="display:none" />');
var thishidebtn = thisdiv.last();
var thisparent = thisdiv.parent();
thisparent.width(owidth);
thisparent.height(oheight+bounceheight);
thisparent.css('border', '1px solid #ccc');
thisparent.css('position', thisdiv.css('position'));
thisparent.css('overflow', 'hidden');
thisdiv.css('position', 'relative');
thisdiv.css('top', oheight+bounceheight);
thisdiv.css('height', '0');
var toggle = false;
thishidebtn.click(function() {
if(toggle)
{
toggle = false;
thisdiv.animate({ top: 0, height:oheight+bounceheight }).animate({ top: oheight+bounceheight, height:0 });
}
});
trigger.click(function() {
// some code //
if(!toggle)
{
// show
$('.bouncehide').click();
toggle = true;
thisdiv.animate({ top: 0, height:oheight+bounceheight }).animate({ top: bounceheight, height:oheight });
}
else
{
// hide
toggle = false;
thisdiv.animate({ top: 0, height:oheight+bounceheight }).animate({ top: oheight+bounceheight, height:0 });
}
});
// return original object so it can be chained
return thisdiv;
}; // END -> plugin :: bounce
... and here is how you use it:
$(function(){
$('#boinky').bounce('#toggle', 50);
$('#boinkyb').bounce('#toggleb', 50);
});
jsFiddle example:
http://jsfiddle.net/523NH/14/
hope this helps you.