I have a stack of cards. They are stacked so each one has about a centimetre at the bottom visible. What I want, is when a card is clicked it moves to the right, then gets sorted to the top and moves to the left back onto the pile. I then wish to trigger a page change (to the page that's represented by the card).
How would I do this through JQuery? I'm still at a basic level with this language.
<style>
#cardStack{
height: 700px;
width: 400px;
overflow:visible;
}
#cardStack ul{
display:inline;
}
#cardStack li{
z-index:auto;
}
.top{
margin-top:-670px;
z-index:1;
}
.middle{
margin-top:-670px;
z-index:2;
}
.bottom{
margin-top:100px;
z-index:3;
}
</style>
</head>
<body><br /><br />
<div id="cardStack">
<ul>
<li class="bottom"><img src="images/cardA.png" /></li>
<li class="middle"><img src="images/card6.png" /></li>
<li class="top"><img src="images/card8.png" /></li>
</ul>
</div>
I know there's an animate function, but how would I initiate this on a click?
EDIT: Added more code above
for the hash change use ben alman's BBQ plugin
tried your code at jsbin
but because the link to the cards is missing the HTML doesn't render right
if you put here a working jsbin sample - helping you will be mush easier
concerning the animations: if you layout the Li's to have an absolute position, you can move them around freely,
so you can animate them to the left and then animate back and then change the z-index to put it on the top
[edit]
So.. here is a link to a quick solution:
you had some problems with the animations code, + better to change the position and not the marign
for ref the code:
$('#cardStack img').click(function ()
{
var img = $(this);
img.animate({left: '+=50px'},200,function()
{
img.animate({left: '-=50px'},200,function()
{
img.parent().prependTo($("ul"));
arrengeClasses();
});
});
});
function arrengeClasses()
{
var allListItems = $("#cardStack ul li");
for(var i=0;i<allListItems.length;++i)
{
allListItems.eq(i).removeClass().addClass("pos" + i);
}
}
and changed the css a bit:
#cardStack li img{
position:absolute;
top:0px;
left:0px;
}
.pos2{
z-index:1;
margin-top:100px;
}
.pos1{
z-index:2;
margin-top:50px;
}
.pos0{
z-index:3;
}
You can set an event to occur on any of the images being clicked like:
$('ul li img').click(function () {
$(this).animate( ... );
.
.
.
}
I can't give any more specific help without knowing the CSS you are using to "stack" the cards.
As for the part where you want to trigger a page change, you can use window.location to append a hash to the end. So your URL might end up being example.com/cards#joker
Related
I'm at a point where I've tried every other option, but I can't seem to solve this problem. Here's an explanation of the experience:
When visiting the page, the person is introduced to a number of images (tagged with classes, for example two of the images are tagged img01 and img02). When an image is clicked, the image maintains it's place (img01's z-index is risen) while all the other images fade away (DIV with a white fill fades in and covers img02), and a text that explains the piece fades in as well (DIV tagged object-text with img01's supporting text fades in).
While I got the img01 functionality to work, I can't seem to do the same for img02. I'm also planning on adding more tags (such as img03 and img04) and am wondering if there is a smarter, more effective way this can be structured.
For functionality reference, here's a http://jsfiddle.net/kenhimself/nvwzgus0/4/
Below, is the html, css, and the java code.
Thanks in advance!
html
<img class="img01" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div id="object-text" class="img01">
<h1>img01 Text<br/>img01 Text</h1>
</div>
<img class="img02" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div id="object-text" class="img02">
<h1>img02 Text<br/>img02 Text</h1>
</div>
<div id="filler"></div>
CSS
html, body {
width:100%;
height:100%;
}
#object {
top: 100px;
left:100px;
}
#object-text {
display:none;
z-index:100000;
bottom: 0;
left: 0;
}
#filler {
display:none;
width:100%;
height:100%;
position:fixed;
background-color: white;
z-index:1000;
opacity: 0.8;
}
h1 {
font-size:20px;
font-family: sans-serif;
font-weight: 100;
font-style: normal;
color: red;
}
.img01, .img02 {
position:absolute;
}
.img01 img, .img02 img {
width:200px;
height:auto;
}
.img01 {
top: 20px;
left: 20px;
}
.img02 {
top: 20px;
right: 20px;
}
Javascript
$("#object").click(function (e) {
e.stopPropagation();
});
$("#object").click(function (e) {
e.preventDefault();
e.stopPropagation();
$("#object").css("z-index", "2000");
$("#object-text").fadeIn("slow");
$("#filler").fadeIn("slow");
$("#inner").css("z-index", "2000");
});
$(document).click(function () {
$("#filler").fadeOut("slow");
$("#object-text").fadeOut("slow");
});
There are a few issues with your code. You should be using unique ID's for each DOM element, and targeting your images by class name. I've made a few changes to your example and restructured it slightly to show you a better approach.
http://jsfiddle.net/nvwzgus0/6/
Wrapped each image in a containing tag, removed duplicate ID's and using class names instead
<a href="#" class="img img01">
<img class="img01" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div class="object-text">
<h1>img01 Text<br/>img01 Text</h1>
</div>
</a>
<a href="#" class="img img02">
<img class="img02" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div class="object-text">
<h1>img02 Text<br/>img02 Text</h1>
</div>
</a>
<div id="filler"></div>
Added CSS class for changing z-index instead of setting it manually, to make it easier to toggle on and off.
a.top {
z-index: 2000;
}
Modified event handling to target new containing tag:
$("a.img").click(function (e) {
e.preventDefault();
e.stopPropagation();
$(this).addClass("top");
$(this).find(".object-text").fadeIn("slow");
$("#filler").fadeIn("slow");
});
Modified how images z-index is reset:
$(document).click(function () {
$("#filler").fadeOut("slow", function() {
$("a.img").removeClass("top");
});
$(".object-text").fadeOut("slow");
});
The main problem I see here is that you have two objects with the same id. Change this, and your code should work. I would recommend switching what you have as ids (object) to classes, and what you have as classes (img02 and img01) to ids.
I looked over your code some more and it seems you are doing this a lot. Make sure that when you code you NEVER reuse ids...like ever. Both your a's and your divs have duplicate ids....
Not to be mean, but this does need a lot of work. Feel free to ask any questions if you need more help.
please guide me as i'm trying to learn.
1) I am trying to make this list to expand when it hover. It work on my browser but not on jsfiddle. But problem is it wont stop expand and shrink when I move my mouse over it several time.
2) How do I make the list by the time it expand, my div will got grow longer, everything stay inside the div. I have try overflow:hidden but it doesn't work.
3) The hover that I try to make in CSS was to only change the font color of the main name but it change color of the whole name.
my JFiddle http://jsfiddle.net/Y3tc6/1/
THE JQUERY
$(".subli").hide();
$(".mainli").on("click", function (e) {
e.preventDefault();
$(this).find(".subli").slideToggle();
});
Thank You
Try this:
$(".mainli").on("mouseover", function (e) {
$(this).find(".subli").slideDown();
});
$(".mainli").on("mouseout", function (e) {
$(this).find(".subli").slideUp();
});
You will have to make some css changes. But i think this will help you with your slide down and slide up
2) How do I make the list by the time it expand, my div will got grow longer, everything stay inside the div. I have try overflow:hidden but it doesn't work.
#droplist {
display:block;
max-height:212px;
width:250px;
background-color:grey;
overflow:auto;
}
3) The hover that I try to make in CSS was to only change the font color of the main name but it change color of the whole name.
#droplist > ul > li:hover {
color:red;
}
#droplist li ul {
color:#000;
}
JSFiddle http://jsfiddle.net/Y3tc6/4/
For more information of > on CSS.
CSS '>' selector; what is it?
Sorry if it's messy, on the 3rd number.
My last edit! XD
1) Use mouseenter and mouseleave
$(".subli").hide();
$(".mainli").mouseenter(function (e) {
$(this).find(".subli").slideDown();
});
$(".mainli").mouseleave(function (e) {
$(this).find(".subli").slideUp();
});
2 & 3) You need to be more specific in you CSS to get the colors right, and use block, max-height and overflow to make the height of the div constant
#droplist {
display:block;
max-height:250px;
height:250px;
width:250px;
background-color:grey;
overflow: hidden;
}
#droplist .mainli:hover li {
color:initial;
}
#droplist .mainli:hover,
#droplist .mainli li:hover {
color:red;
}
Working demo
Try this:
$(".subli").hide();
$(".mainli").hover( function (e) {
e.preventDefault();
$(this).find(".subli").stop(true).slideToggle();
}
);
I have a small problem with jQuery slideDown() animation. When this slideDown() is triggered, it moves all stuff below downwards too.
How do I make all the stuff below the <p> being slid down, remain stationary ?
Note:
I would prefer a solution where the change is done to the <p> element, or to the slideDown call or something. Because in my actual page, there is a lot of stuff below the <p> being slid down, so changing/re-arranging all of them will take much longer for me ~
Demo # JSFiddle: http://jsfiddle.net/ahmadka/A2mmP/24/
HTML Code:
<section class="subscribe">
<button id="submitBtn" type="submit">Subscribe</button>
<p></p>
</section>
<div style="padding-top: 30px;">
<table border="1">
<tr>
<td>This table moves</td>
<td>down when</td>
</tr>
<tr>
<td>slideDown()</td>
<td>is activated !</td>
</tr>
</table>
</div>
JavaScript:
$(function () {
$("#submitBtn").click(function (event) {
$(".subscribe p").html("Thanks for your interest!").slideDown();
});
});
CSS:
.subscribe p {
display: none;
}
You can position that element as absolute:
.subscribe p {
display: none;
position : absolute; // add this line
}
Demo: http://jsfiddle.net/A2mmP/25/
What's happening with your existing code is that the element starts out as display:none; so it doesn't take up any space at all until you slide it in and it is changed to display:block, hence the movement down of the following elements.
With position:absolute it doesn't take up space in that sense, it overlaps: in fact in my updated version of your fiddle you can see a slight overlap into the table underneath - you can obviously tweak margins on the table or whatever to make it fit the way you want.
All you need is to give a fixed height of your .subscribe.
.subscribe {
height: 50px;
}
.subscribe p {
margin: 0px;
display: none;
}
Here is the jsFiddle : http://jsfiddle.net/xL3R8/
Solution
We will put the sliding element in a div element with a fixed width, preventing the document flow from being affected by the slide event.
HTML
<section class="subscribe">
<button id="submitBtn" type="submit">Subscribe</button>
<!-- this is the modified part -->
<div><p></p></div>
</section>
CSS
.subscribe div
{
/* We force the width to stay a maximum of 22px */
height:22px;
max-height:22px;
overflow:hidden;
}
.subscribe div p {
display: none;
/* We reset the top margin so the element is shown correctly */
margin-top:0px;
}
Live Demo
The problem is your CSS, it will render as block and push the other elements down when it slides in. Set it to be absolutely positioned and change the z-index to be in front, or behind.
.subscribe p {
display: none;
position: absolute;
z-index: 100;
}
Fiddle
.subscribe p {
display: none;
margin :0px;
}
IMO a good UI practice would be to, remove the subscribe button, and instead show a message there like :
"Hurray! You have been subscribed"
e.g
http://jsfiddle.net/UvXkY/
$(function () {
$("#submitBtn").click(function (event) {
$("#submitBtn").slideToggle('slow', function(){
$(".subscribe p").html("Thanks for your interest!").slideDown();
});
});
});
The actual problem your facing is display:none which will remove the space for the element p
where as visiblity:hidden and showing will get ride of this problem
Even though it will not give the proper slideDown effects so you can use the position absolute and keep some spaces for the p element will solve your problem.
one of the solution
.subscribe p {
position:absolute;
display:none;
}
.subscribe
{
position:relative;
height:50px;
}
FIDDLE DEMO
I have created a customized menu. See here. On click of this link I have a shadowbox popping up which has a long list of items. Now I want to have a "back to top" anchor link which takes me back to the top of the menu list.
I've set your lightbox with the #box id.
Html
<div id="box">
...
<!-- long content there -->
To Top
</div>
CSS (setting the width of elements)
#box {
position:relative;
width:200px;
height:250px;
overflow:auto;
}
#box #toTop {
position:absolute;
display:none;
left:150px;
top:10px;
}
jQuery
$('#box').bind('scroll', function(e) {
if ($(this).scrollTop() > 100) {
$('#toTop').fadeIn();
$('#toTop').css({'top' : $(this).scrollTop() + 100});
} else {
$('#toTop').fadeOut();
}
});
$(document).on('click', '#toTop', function(e) {
e.preventDefault();
//$('#box').scrollTop(0); //just go to top
$('#box').animate({scrollTop : 0},'slow'); //animate
});
Fiddle
Pretty easy with:
document.querySelector("iframe").contentWindow.scrollTo(0,0);
Now put a button on the page and call that on click. Oh, and omit the height:100% on your body of the iframe, this way you get rid of the second scrollbar.
You can try this out by just pasting the line above and executing it in the console of your browser with your webpage.
I'm trying to clone #main then put my ajax result there (hidden), after doing so I will make it scroll horizontally to the left hiding the current one then display the clone.
HTML:
<div class="container">
<div id="main">
<p>Click here to start</p>
</div>
</div>
CSS:
#main{
width:460px;
min-height:200px;
background:#3F9FD9;
margin:0 auto;
}
.container {
position:relative;
}
Javascript:
$('#main').click(function(){
//clone.html(data)
var clone = $(this).clone().html('<p>Ajax loaded content</p>').css(
{position:'absolute',right:'0','margin-right':'-460px',top:0}
).attr('class','love').insertAfter($(this));
$(this).css({position:'relative'});
var width = $(window).width()-$(this).outerWidth()/2;
$('#main').animate({'left':'-'+width},4000);
});
but i'm stuck on the idea on how to make both #main animate to the left and position the second div at the center?
Fiddle
EDIT: Now i'm only stuck on how to animate the clone.
I sort of took a different approach to your question, is this kind of what you are looking for?
http://jsfiddle.net/3s7Fw/5/show
I thought, rather than do some animating ourselves, why not let jQuery's hide function do it for us? This could definitely be made to work better, but it communicates the thought.
JavaScript
$('.container').on('click', '.loaded-content', function(){
$this = $(this);
//clone.html(data)
var clone = $this.clone().html('<p>Ajax loaded content</p>').attr("id", '');
$this.after(clone);
$this.hide('slow');
});
HTML
<div class="container">
<div id="main" class="loaded-content">
<p>Click here to start</p>
</div>
</div>
CSS
#main, .loaded-content{
width:460px;
min-height:200px;
background:#3F9FD9;
margin:0 auto;
float: left;
}
.container {
position:relative;
width: 920px;
}
If this is not the desired functionality, then you might be interested in a slider. There are a number of good slider plugins already out there that you can use. The difficult part would probably be adding a addNewSlide function to your chosen slider, assuming it didn't already have one.