How to make a partially hidden div? - javascript

I want to make a half shown div in a page, like a footer. When I click it I want it to slide up. The div will contain information on it.
I achieved this somehow, but my problem is that the div does not get really hidden it just changes the position.
You can find the demo here: http://jsfiddle.net/8ZFMJ/394/
var clicked=false;
$(".two").on('click', function(){
if(clicked)
{
clicked=false;
$(".two").css({"bottom": -430});
}
else
{
clicked=true;
$(".two").css({"bottom": "-200px"});
}
});

I had a similar problem a while ago, in fact I think it was my first stackoverflow question. Unfortunately it got poorly received.
Anyway, the problem is currently that you are just changing the position of the div - that's what .bottom does. I think what you want to do is change the height, see this JSFiddle in which I managed to switch the div between states (no animation yet).
It makes simple use of css's overflow-y: hidden; to hide the div's contents when it is small, and all the JS does is toggle between heights:
if(clicked)
{
$(".two").css("height", 10);
}
else
{
$(".two").css("height", 250);
}
clicked = !clicked;
clicked = !clicked just flips the boolean state of the variable.
Now, to add the animation, we can use jQuery's .animate and produce this beautiful Fiddle
Basically, all we had to do in between is use animate instead of css. Simple, really.
TL;DR
final JSFiddle

.two must be absolute positioned inside .container that must be relative positioned. Then you just change the bottom with a negative value and that will hide the footer.
CSS:
html, body { height: 100%; }
.container {
position: relative;
height: 100%;
overflow: hidden;
}
.two {
position: absolute;
background-color: yellow;
width: 100%;
height:250px;
bottom: -200px;
transition: bottom 1s;
}
jQuery:
var clicked=false;
$(".two").on('click', function(){
if(clicked)
{
clicked=false;
$(".two").css({"bottom": "-200px"});
}
else
{
clicked=true;
$(".two").css({"bottom": 0});
}
});
http://jsfiddle.net/8ZFMJ/398/

Related

Change image on click of mouse by passing class name from one element to the next

I have a situation where I want to change the background image when I click the mouse. I want to remove the class from one element and add the same class to the next element. Then based on that particular class name, I want to perform fadeIn and fadeOut using jquery. However, only the first image is changed when I use the class. When I click the second image, it wont change. But when I replace the class with div, background image changes on each click until it reaches the last image. Can anyone help me understand what I am missing. Thank you.
$(function(){
$("div").not(".active").hide();
$(".active").click(function(){ //When I change .active to div, it works.
$(this).fadeOut(function(){
$(this).removeClass("active");
$(this).next().addClass("active");
$(this).next().fadeIn()
})
})
})
body, html{
height: 100%;
width:100%;
background-color: yellow;
}
#one{
background:url("../Images/one.jpg") fixed center no-repeat;
width:100%;
height: 100%;
}
#two{
background:url("../Images/two.jpg");
width:100%;
height: 100%;
}
#three{
background:url("../Images/three.jpg");
width:100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="one" class="active"></div>
<div id="two"></div>
<div id="three"></div>
</body>
You need to use on() instead of click() because you are adding the class dynamically.
$(function(){
$("div").not(".active").hide();
$("body").on('click', '.active', function(){ //When I change .active to div, it works.
$(this).fadeOut(function(){
$(this).removeClass("active");
$(this).next().addClass("active");
$(this).next().fadeIn()
})
})
})
Maybe you need to use .delegate
change your code like this:
$('body').delegate('.active', 'click', function() {
$(this).fadeOut(function() {
$(this).removeClass("active");
$(this).next().addClass("active");
$(this).next().fadeIn()
})
})
or you change bind the click on body to judge the e.target
see the details here delegate
You may do it like this:
first add specific class .bg-div to these divs because targeting ALL divs with this $("div") is so generic and it'll hide everything other than the active one, in case you have other divs they'll be hidden.
hide all divs with class .bg-div except the one which has .active.
on click event, you can still target bg-div div because there's only one which has .active class, since all other bgDivs are hidden already from the previous step. fadeOut() this one.
increase the counter index by one.
now if the value of index equals the length -number - of bgDivs, then reset the coutner to 0, this is for when you're showing the last bg-div.
fadeIn() the next div.
jsFiddle 1
$(function() {
var bgDivs = $(".bg-div"),
index = 0;
bgDivs.not(".active").hide();
bgDivs.on('click', function() {
$(this).fadeOut('fast');
index += 1;
// if the counter value is less than the number of bgDivs, keep this value
// else, set it to 0 and start over because we're on the last div
index = (index < bgDivs.length) ? index : 0;
$(bgDivs[index]).fadeIn('fast');
});
})
body,
html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
background-color: yellow;
}
.bg-div {
width: 100%;
height: 100%;
}
#one {
background: url("//dummyimage.com/1000x700?text=one") fixed center no-repeat;
background-size: cover;
}
#two {
background: url("//dummyimage.com/1000x700?text=two") fixed center no-repeat;
background-size: cover;
}
#three {
background: url("//dummyimage.com/1000x700?text=three") fixed center no-repeat;
background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<div id="one" class="bg-div active"></div>
<div id="two" class="bg-div"></div>
<div id="three" class="bg-div"></div>
</body>
Update 1:
You'd notice there's a moment where the horizontal scrollbar appears when while switching the background div, this is because these divs are stacked under each others but when hidden there's no problem, the problem only appears the moment you switch the background div, to fix this add these lines to your .bg-div CSS:
position:absolute;
top:0;
left:0;
jsFiddle 2
Update 2:
You can totally get rid of .active class and don't rely on it if you add generic display:none; to your .bg-div CSS, then in the #one rule add display:block. by doing this you no more need this line:
bgDivs.not(".active").hide();
jsFiddle 3
This is useful not only because of less code, but also the background divs other than the first one will be hidden when the page first load from the beginning since it's in the CSS and not wait until your js script to hide them

expanding an inline-block jumps to above row

I have a series of articles
<section>
<article>1</article>
<article>2</article>
<article>3</article>
....
<article>999</article>
<section>
arranged in a grid of three per row
section {
position: relative
}
article {
display: inline-block;
width: 33%;
}
and I want that they expand horizontally to fully occupy its row when clicked.
so I create an expanded class
.expanded {
position:absolute;
left:0px;
width: 100%;
}
and apply it on click
$("article").click(function(){
$(this).toggleClass("expanded");
});
I am almost there, as you can see in the fiddle here http://jsfiddle.net/aqw339r0/1/
When I click on any of the articles they expand to the full width of the row; but the problem is that when I click the first article of a row (except the first row) it "jumps" to the row immediately above.
I have tried changing the position and display attributes of both article and .expanded but I cannot get the behavior I need. For example: When I change the position:absolute of .expanded, the blocks 5 and 6, "jump" to the row below. Similar when I remove display:inline-block and change to float:left.
Do you have any ideas of why this happens and how to correct it?
Using the solution from #Rick (minus the css top edit) and then toggling an additional element to keep other elements in place, this should do what is needed: Fiddle
$("article").click(function() {
$(this).toggleClass("expanded");
if ($(this).hasClass("expanded"))
{
$(this).before("<article class='blank'> </article>");
}
else
{
$(this).prevAll('.blank').first().remove();
}
});
To explain further, when the element is clicked:
if ADDING the class 'expanded', then this will also add a blank article element (before) as a placeholder to keep the flow consistent. This is important because when the element with class 'expanded' becomes position: absolute it is removed from the normal flow of the content.
if REMOVING the class 'expanded', then this will also remove the blank article placeholder element. The prevAll function looks through all previous elements with the class 'blank' and then takes the first() one and removes it. Because it was inserted 'before', this is guaranteed to remove the correct blank article placeholder.
When position:absolute is set on an <article> element, that takes it out of the normal content flow, and causes the offset. We can correct it by adding an empty <article> as a placeholder when the click triggers, and removing it when click again.
var open = false;
jQuery("article").click(function () {
open = !open;
if (open) {
$(this).addClass("expanded");
$(this).before("<article class='holder'> </article>");
} else {
$("article").removeClass("expanded");
$(".holder").remove();
}
});
p.s. I'm not that good at jQuery, any suggestions are welcome.
jsfiddle
I can't think of a pure CSS solution, but since you're using jQuery anyway, simply hard-code the expanded element's top:
$("article").click(function() {
$(this).css('top', $(this).position().top);
$(this).toggleClass("expanded");
});
Fiddle
The top style will be ignored once the expanded class is removed.
Try this
<section>
<article>1</article>
<article>2</article>
<article>3</article>
</section>
<section>
<article>4</article>
<article>5</article>
<article>6</article>
<section>
<section>
<article>7</article>
<article>8</article>
<article>9</article>
</section>
section {
position:relative;
}
article {
width: 30%;
min-width: 200px;
min-height: 200px;
display: inline-block;
border: 1px solid black;
}
.expanded {
width: 100%;
background-color:#eef;
left:0px;
top:0;
position:absolute;
transition: 0.2s linear;
}
// if you want others to close while expanding
$("article").click(function(){
$('article').removeClass("expanded");
$(this).toggleClass("expanded");
});
// esle if you want everything to be expanded
$("article").click(function(){
$(this).toggleClass("expanded");
});

Hide portion of element offscreen and push & reveal on click

I'm building a responsive page that, when viewed on mobile, includes some popular behaviors.
I have an element that includes text and a link. The text portion needs to cover 100% of the width of the viewport and when clicked/tapped the link should push the text content left and reveal the link.
Fiddle: http://jsfiddle.net/Flignats/0n0fwm20/
HTML:
<div id="container">
<div id="block-one">
I'm a bunch of informational text.
</div>
<div id="block-two">
I'm a link!
</div>
</div>
CSS:
#container {
width: 100%;
height: 100px;
}
#block-one {
float: left;
width: 75%;
height: 100px;
background-color: #626366;
}
#block-two {
float: left;
width: 25%;
height: 100px;
background-color: #969696;
}
#block-two a {
color: blue;
}
How can I have block-one span the full width of the screen, block-two hidden off the screen, and, on click, animate (the margin?) block-two into view with block-one pushed to the left?
My apologies if I missed a clear example on site, most other questions were more complex.
I'd prefer not to build a jquery mobile page, though the push and reveal panels would accomplish this action. I'm also using Angular if nganimate is preferred over javascript.
Here is pure css solution: http://jsfiddle.net/3wcfggmf/
I've used trick with label and checkbox:checked to recognize if element is clicked or not.
input:checked + #block-one {
width: 75%;
}
If I didn't understand you correctly please let me know and I'll modify this PURE css solution for you :)
I forked your fiddle here with a working example: http://jsfiddle.net/90gm224q/
Added CSS to yours:
#container * { transition: width .4s; }
#container.clicked #block-one { width:25%; }
#container.clicked #block-two { width:75%; }
The JS:
var container = document.getElementById('container'),
link = document.getElementById('block-two').getElementsByTagName('a')[0];
link.onclick = function() {
container.className = 'clicked';
return false;
}
Assuming I understood your question correctly, you can play with the CSS values for width to achieve your desired effect.
You could accomplish this via CSS transistions and a JavaScript class toggle.
Demo - http://jsfiddle.net/Leh5t9t6/
In my demo, clicking #block-one toggles a class which fires the CSS transision. I included a pure JavaScript and jQuery version in the demo (you mentioned you'd prefer not use jQuery).
I also edited the styles slightly to accommodate the off-screen link.
Pure Javascript
var element = document.getElementById('block-one');
element.addEventListener('click', function () {
this.classList.toggle('reveal');
}, false);
jQuery
$('#block-one').on('click', function(){
$(this).toggleClass('reveal');
});

Pass click through to fixed element

I have a static element that is above a fixed element. When the upper static element is clicked, I want to pass this click through to the fixed element. How can I do this? Here is a working example (I wasn't able to get this to work in JSFiddle).
<body>
<div class="lower" onclick="lowerClick()"></div>
<div class="upper" onclick="upperClick()"></div>
</body>
<script>
function lowerClick() {
alert("LOWER CLICK");
};
function upperClick() {
alert("UPPER CLICK");
};
</script>
//CSS file
.lower {
height: 100px;
width: 100%;
z-index: -1;
position: fixed;
background-color:blue;
}
.upper {
height: 50px;
width: 100%;
z-index: 1;
position: static;
background-color:red;
pointer-events: none;
}
I thought that adding pointer-events:none to my upper element would make this work, but when I click the top element, nothing happens.
In fact pointer-events:none works expectedly. But what prevents you from clicking on the lower is the body element. Because of setting z-index:-1 on your lower, it will be sent to behind of its parent (which is the body). So you can set the z-index of the body to a more negative number, of course the postion should be some value other than static (default):
body {
z-index:-1000;
position:relative;
}
Demo
You can use the following css for the upper div
.upper {
pointer-events:none;
}
...also avoid negative z-index, and instead use 1 for lower and 2 for upper. Also why put static and not absolute element at the top?

jquery scroller with multiple visible items

I'm trying to build a scroller using jQuery.
The items within the scroller are display:inline-block and there can be multiple items visible in the x and y planes at any given time.
Can anyone help with my scroller?
Here is a jsfiddle with what I currently have. The animated sliding isnt working. I'm trying to make all of the contents slide together outside of the wrapper while the next page of items slide in.
http://jsfiddle.net/GR9ZR/
if (~~ (counter / totalVisible) == currentPage) {
item.show();
item.animate({
"left": -(item.position().left)
});
} else {
item.animate({
"left": -(item.position().left)
});
item.hide();
}
If you want to animate the position, in your CSS you must give the element you are trying to animate a property of position: relative;.
Consider a simple example, in which I want to animate a block to move right, when I click on the document page.
Codepen sketch: http://cdpn.io/vdCth
HTML
<div class='item'></div>
CSS
.item {
background: #ccc;
display: inline-block;
height: 50px;
position: relative;
width: 50px;
}
jQuery
$('html').on('click', function(){
$('.item').animate({
left: "+=50"
}, 200, function(){
});
});
Now remove the position: relative; from your CSS, and you will see the animation no longer occurs, as demonstrated in this fork: http://cdpn.io/LcakK
Hope that helps.

Categories

Resources