Please see this fiddle I have set up.
You are first confronted by three links. Each link triggers divs to slide out.
The link 'john smith' slides out and in at the speed we want. When it slides out the first line slides out then when that is completed the second line slides down as though coming from the first. When it slides back it does the same motion at the same speed but reverse i.e.. the second line slide back up first and then when that is completed the first line slides back to the left.
When you click on the work link and menu slides out in the same manner as the bio. Also there is a sub menu that slides out when on clicks on item 2.
When the user clicks on the contact link one line slides out.
What we need to achieve is this; when any div is open and another link is clicked on, the visible div slides back in reverse to how they slid in. We have almost achieve this, however, the code is not quite right as the divs are not sliding back in at the same speed and in the right order, they simply slide back fast. For example, if one has clicked on 'work' and the 'item 2' link, and then you select 'contact' the opened div slide back very quickly. What I need to achieve is that they slide back in reverse to how they slid out.
To attempt to make it clear, if you click on 'work' and then 'item 2' so with menus are visible and then click on work again, you will see the sub menu slides away first before the first menu. You will also notice that the items that slide up slide back down first before the divs slide back to the left. This is what needs to happen if you click on 'contact' or 'john smith' when the menus are visible.
I know this sounds very complicated and if I can answer any questions to make it clearer I will.
Thanks
$('#bio-line-1').animate({width: 'hide'});
$('#contact-info').animate({right: 'hide'});
$('#bio-line-2').slideUp("fast");
$('#black-div, #black-credits, #igna-1-div, #igna-1-credits, #igna-2- div, #igna-2-credits, #fatal-div, #fatal-credits').fadeOut('100');
});
you can use .setTimeout() to put some delay
setTimeout(function () {
$('#contact-info').animate({right: 'toggle'});
}, 500);
DEMO
DEMO
I finally worked out how to fix it to work how I intended, however my code is very long winded. I realise there must be a way to reduce the repetition of the code by using generic functions. I will now post the working code onto Code Review for further development.
$('#menu').click(function () {
if ( $('#igna-1').css('display') != 'none' ) {
$('#igna-1').slideToggle("fast", function() {
$('#igna-2').animate({ left: 'hide' }, 300, function() {
$('#black, #igna, #igna-1').slideUp("fast", function() {
$('#fatal, #igna-2').animate({ left: 'hide' }, 300);
});
Although I see that you have found your solution but as I had started coding the TweenMax version of it, I went on and finished it. The reason I am suggesting GSAP should be the go-to tool for animations for the web is not just because it is crazy fast, or easy to jump-start or get started with, or makes some of the coolest animation effects possible with few lines of code (I can go on and on) ... but it is as intuitive as it can get.
Coming back to your animation, I have converted your animation solution into using TimelineMax / TweenMax entirely, snippet of which is as follows:
/*global TweenMax,TimelineMax,Power2,Power0*/
var getElementById=document.getElementById.bind(document);
var nameA=getElementById('name-a'),menu=getElementById('menu'),contact=getElementById('contact');
var contactInfo=getElementById('contact-info'),contactInfoAnchor=contactInfo.querySelector('a');
var igna=getElementById('igna'),ignaAnchor=igna.querySelector('a');
var ignaOne=getElementById('igna-1'),ignaOneAnchor=ignaOne.querySelector('a');
var ignaTwo=getElementById('igna-2'),ignaTwoAnchor=ignaTwo.querySelector('a');
var black=getElementById('black'),blackAnchor=black.querySelector('a');
var fatal=getElementById('fatal'),fatalAnchor=fatal.querySelector('a');
var bioLineOne=getElementById('bio-line-1'),bioLineOneParagraph=bioLineOne.querySelector('p');
var bioLineTwo=getElementById('bio-line-2'),bioLineTwoParagraph=bioLineTwo.querySelector('p');
var tlName=getTimeline(),tlContact=getTimeline(),tlWork=getTimeline(),tlIgnaTwo=getTimeline(),tlWorkIgnaTwoCombined=getTimeline();
var isTlNameDirectionForward=false,isTlContactDirectionForward=false,isTlWorkDirectionForward=false,isTlIgnaTwoDirectionForward=false,reverseTimeScale=1;
var duration=.4,easeInOut=Power2.easeInOut,easeOut=Power2.easeOut,easeIn=Power2.easeIn,easeNone=Power0.easeNone;
function init(){
setTlName();
setTlContact();
setTlWork();
setTlIgnaTwo();
setTlWorkIgnaTwoCombined();
assignListeners();
}
function setTlName(){
addParentDIVsToTimeline(tlName,[bioLineOne,bioLineTwo],['rect(10px 633px 50px 0px)','rect(10px 633px 50px 0px)']);
tlName.fromTo(bioLineOneParagraph,duration,{x:-633},{x:0,ease:easeOut,clearProps:'x'},0).fromTo(bioLineTwoParagraph,duration,{y:-40},{y:0,ease:easeOut,clearProps:'y'},duration*.3);
}
function setTlContact(){
addParentDIVsToTimeline(tlContact,[contactInfo],['rect(0px 120px 20px 0px)']);
tlContact.fromTo(contactInfoAnchor,duration,{display:'block',x:150},{display:'block',x:0,ease:easeOut,clearProps:'display, x'},0);
}
function setTlWork(){
var fromProps={display:'block',y:40},toProps={display:'block',y:0,ease:easeOut,clearProps:'display, y'};
addParentDIVsToTimeline(tlWork,[fatal,igna,black],['rect(0px 120px 20px -90px)','rect(0px 120px 26px 0px)','rect(0px 120px 26px 0px)']);
tlWork.fromTo(fatalAnchor,duration,{display:'block',x:-150},{display:'block',x:0,ease:easeOut,clearProps:'display, x'},0).fromTo(ignaAnchor,duration,fromProps,toProps,duration*.3).fromTo(blackAnchor,duration,fromProps,toProps,duration*.6);
}
function setTlIgnaTwo(){
addParentDIVsToTimeline(tlIgnaTwo,[ignaTwo,ignaOne],['rect(0px 120px 20px -90px)','rect(0px 120px 26px 0px)']);
tlIgnaTwo.fromTo(ignaTwoAnchor,duration,{display:'block',x:-150},{display:'block',x:0,ease:easeOut,clearProps:'display, x'},0).fromTo(ignaOneAnchor,duration,{display:'block',y:40},{display:'block',y:0,ease:easeOut,clearProps:'display, y'},duration*.3);
}
function setTlWorkIgnaTwoCombined(){
tlWorkIgnaTwoCombined.to(tlIgnaTwo,duration,{progress:0,ease:easeNone},0).to(tlWork,tlWork.totalDuration(),{progress:0,ease:easeNone},duration*.3);
}
function assignListeners(){
nameA.addEventListener('click',onNameAClicked,false);
menu.addEventListener('click',onMenuClicked,false);
contact.addEventListener('click',onContactClicked,false);
igna.addEventListener('click',onIgnaClicked,false);
ignaOneAnchor.addEventListener('click',playTlWorkIgnaTwoCombined,false);
ignaTwoAnchor.addEventListener('click',playTlWorkIgnaTwoCombined,false);
black.addEventListener('click',onMenuClicked,false);
fatal.addEventListener('click',onMenuClicked,false);
}
function onNameAClicked(){
isTlNameDirectionForward=!isTlNameDirectionForward;
isTlNameDirectionForward?tlName.timeScale(1).play():tlName.timeScale(1).reverse();
reverseTlContact();
if(isTlIgnaTwoDirectionForward){playTlWorkIgnaTwoCombined();}else if(isTlWorkDirectionForward){reverseTlWork();}
}
function onMenuClicked(){
isTlWorkDirectionForward=!isTlWorkDirectionForward;
isTlWorkDirectionForward?tlWork.timeScale(1).play():tlWork.timeScale(1).reverse();
reverseTlContact();
reverseTlName();
if(isTlIgnaTwoDirectionForward){playTlWorkIgnaTwoCombined();}
}
function onContactClicked(){
isTlContactDirectionForward=!isTlContactDirectionForward;
isTlContactDirectionForward?tlContact.timeScale(1).play():tlContact.timeScale(1).reverse();
reverseTlName();
if(isTlIgnaTwoDirectionForward){playTlWorkIgnaTwoCombined();}else if(isTlWorkDirectionForward){reverseTlWork();}
}
function onIgnaClicked(){
isTlIgnaTwoDirectionForward=!isTlIgnaTwoDirectionForward;
isTlIgnaTwoDirectionForward?tlIgnaTwo.timeScale(1).play():tlIgnaTwo.timeScale(1).reverse();
}
function addParentDIVsToTimeline(tl,parents,clipRects){
var length=parents.length;
for(var i=0;i<length;i+=1){tl.fromTo(parents[i],duration,{display:'none',clip:clipRects[i]},{display:'block',clip:clipRects[i],ease:easeOut,clearProps:'clip'},duration*.3*i);}
}
function getTimeline(){return new TimelineMax({paused:true});}
function reverseTlContact(){
if(isTlContactDirectionForward){
isTlContactDirectionForward=false;
tlContact.timeScale(reverseTimeScale).reverse();
}
}
function reverseTlName(){
if(isTlNameDirectionForward){
isTlNameDirectionForward=false;
tlName.timeScale(reverseTimeScale).reverse();
}
}
function reverseTlWork(){
isTlWorkDirectionForward=false;
tlWork.timeScale(reverseTimeScale).reverse();
}
function playTlWorkIgnaTwoCombined(){
isTlIgnaTwoDirectionForward=isTlWorkDirectionForward=false;
tlWork.pause(tlWork.totalTime());
tlIgnaTwo.pause(tlIgnaTwo.totalTime());
tlWorkIgnaTwoCombined.pause(0).play();
}
//
init();
#name-a {
left: 38px;
position: fixed;
top: 38px;
z-index: 1;
}
#bio-line-1 {
left: 150px;
position: fixed;
top: 35px;
width: 633px;
z-index: 1;
}
#bio-line-1 p {
color: #333333;
display: block;
float: right;
font-size: 16px;
line-height: 21px;
width: 552px;
}
#bio-line-2 {
left: 150px;
margin-top: 20px;
position: fixed;
top: 38px;
width: 633px;
z-index: 1;
}
#bio-line-2 p {
color: #333333;
display: block;
float: right;
font-size: 16px;
line-height: 21px;
width: 552px;
}
#menu {
bottom: 34px;
left: 38px;
position: fixed;
z-index: 4;
background-color: #ffffff;
}
#contact {
bottom: 34px;
position: fixed;
right: 38px;
z-index: 1;
background-color: #ffffff;
}
#contact-info {
bottom: 34px;
margin-right: 38px;
position: fixed;
right: 160px;
text-transform: lowercase;
white-space: nowrap;
}
.hidden {
display: none;
}
#fatal {
bottom: 34px;
float: right;
left: 135px;
margin-left: 36px;
position: fixed;
white-space: nowrap;
z-index: 1;
}
#black {
bottom: 61px;
float: right;
left: 171px;
margin-bottom: 18px;
position: fixed;
white-space: nowrap;
z-index: 1;
}
#igna {
bottom: 52px;
float: right;
left: 171px;
margin-bottom: 5px;
position: fixed;
white-space: nowrap;
width: 270px;
z-index: 1;
}
#igna-1 {
bottom: 72px;
left: 404px;
margin-bottom: 7px;
position: fixed;
white-space: nowrap;
width: 162px;
z-index: 1;
}
#igna-2 {
bottom: 57px;
left: 82px;
margin-left: 321px;
position: fixed;
white-space: nowrap;
width: 162px;
z-index: 1;
}
.sub-menu {
white-space: nowrap;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>
<div id="name-a">John Smith</div>
<div id="menu">Work</div>
<div id="contact">Contact</div>
<div class="hidden" id="contact-info">conatct#foo.com</div>
<div class="hidden hover" id="black">item 1</div>
<div class="hidden hover" id="igna">item 2</div>
<div class="hidden hover" id="fatal">item 3</div>
<div class="hidden hover" id="igna-1">S/S <span id="ss">15</span></div>
<div class="hidden hover" id="igna-2">A/W 14</div>
<div id="bio-line-1" class="hidden"><p>holds a Master's Degree from the University of the Arts London</p></div>
<div id="bio-line-2" class="hidden"><p>and currently works foo bar.</p></div>
Hope you find it all useful in some way.
Further reading:
Sequence JavaScript Animations Like a Pro with GSAP's
TimelineLite.
Understanding the Position Parameter.
P.S. The example above may not have done justice to the library. There may have been bugs in my code or the approach may seem overly complicated, but these shouldn't take away the credits from this GreenSock Animation Platform. Love this tool.
T
I've searched high and low but can't find a solution to this exact problem.
On a desktop browser, when the user hovers over an image, a div appears and they can click the link within the div if they want. However, on a mobile device, the hover is triggered by a click. If the user clicks in just the right spot, even though the div isn't visible yet, they can accidentally click the anchor and navigate away from the page. (In other words, the div goes from display:none to display:block at the same time that the link is clicked.)
I want to prevent that accidental click from happening on mobile browsers, however I still want the link to be usable once the div is visible.
My code:
<style>
.staffpic {
position: relative;
width: 33.33333%;
height: auto;
}
.staffpic:hover .popup {
display: block;
}
.staffpic img {
display: block;
width: 110px;
height: 110px;
margin: 0 auto;
}
.popup {
display:none;
position: absolute;
bottom: 0;
left: -5px;
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 15px;
background-color: rgba(255, 153, 0, 0.9);
color: #fff;
text-transform: uppercase;
}
</style>
<div class="staffpic">
<img src="/wp-content/uploads/image.jpg" />
<div class="popup">
John Smith, Director<br/>
CityName | Email John
</div>
</div>
Any ideas? HTML, CSS, JS and jQuery solutions are all welcome! (Maybe something more clever than what I can think of using pointer-events:none along with some jQuery?)
I'm actually about to encounter the same problem in a project, and jotted down a potential solution. Haven't tested it yet but it might help you out. The link should only trigger if the element has a display that's not 'none':
var popup = $('.popup'),
display = popup.css('display');
if (!(display === 'none')) {
popup.on('click', function(e) {
e.preventDefault();
});
}
I found a solution but it's not elegant. I wanted to post it in case someone has this problem in the future and just needs something that will work!
I added a fake link in a span with the real link then set new display styles for it and the real link based on the parent span is being hovered over.
<style>
.staffpic {
position: relative;
width: 33.33333%;
height: auto;
}
.staffpic:hover .popup {
display: block;
}
.staffpic img {
display: block;
width: 110px;
height: 110px;
margin: 0 auto;
}
.staffpic a {
display: none; /* Added */
}
.staffpic.link:hover a {
display: inline; /* Added */
}
.staffpic.link:hover .fakelink {
display: none; /* Added */
}
.popup {
display:none;
position: absolute;
bottom: 0;
left: -5px;
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 15px;
background-color: rgba(255, 153, 0, 0.9);
color: #fff;
text-transform: uppercase;
}
</style>
<div class="staffpic">
<img src="/wp-content/uploads/image.jpg" />
<div class="popup">
John Smith, Director<br/>
CityName | <span class="link">Email John<span class="fakelink">Email John</span></span>
</div>
</div>
I'd still love a cleaner solution without all this added html if someone has it.
I am making a simple php chatbox and am starting with the css/javascript first. What I want to do is when I click the header of the chat, the main part of the chat will slide up and show, and when I click the header again, it will go down, similar to the Facebook chat. I have tried things like
$(".chatheader").on("click", function () {
$(".chatcontainer").style.display = 'visible';
}
but none of them work, here are my codes
HTML
<div id="chatbox">
<div class="chatheader"><div class="chatheadertext">chatboxheader</div></div>
<div class="chatcontainer">
test
</div>
</div>
CSS
#chatbox {
right: 0;
bottom: 0;
position: absolute;
padding-right: 50px;
}
.chatcontainer {
height: 360px;
width: 320px;
border-left: 1px solid #dddddd;
border-right: 1px solid #dddddd;
float: right;
top: 100%;
display: none;
}
.chatheader {
font-family:'PT Sans';
background: #00b4ff;
width: 322px;
height: 51px;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
bottom: 360;
}
.chatheadertext {
padding-top: 15px;
padding-left: 15px;
color: #fff;
}
DEMO
I have display: hidden; on my .chatcontainer and I would like to use javascript to make the display visible when .chatheader is clicked. Thanks in advance to anyone who can help!
You can use .slideToggle():
$(".chatheader").on("click", function () {
$("#chatcontainer").slideToggle();
});
Updated Fiddle
Final code should look like this:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(function() {
$(".chatheader").on("click", function () {
$("#chatcontainer").slideToggle();
});
});
</script>
Use the jQuery slideDown() method:
$(".chatcontainer").slideDown();
And use slideUp() to hide it later.
I have a script that is dived as:
HTML:
<div id="wrapper">
<div id="container">
<div id="button">Click me!</div>
<form>
<input type="file" />
</form>
</div>
<div id="notice">File is uploaded!</div>
</div>
JavaScript(JQuery 2):
$(document).ready(function () {
$("input").on("change", function () {
$("div#notice").fadeIn();
//$("form").submit(); //If you want it to submit on your site uncomment this
});
});
CSS:
div#wrapper {
background-color: #ccc;
position: absolute;
width: 300px;
height: 200px;
}
div#wrapper > form > input {
color: rgba(0, 0, 0, 0);
zoom: 1;
filter: alpha(opacity=0);
opacity: 0;
color: rgba(0, 0, 0, 0);
}
div#container {
width: 200px;
height: 20px;
overflow: hidden;
}
div#button, input {
position: absolute;
top: 0px;
left: 0px;
cursor: pointer;
}
div#button {
z-index: 1;
background-color: #AAA;
}
input {
z-index: 2;
background-color: rgba(0, 0, 0, 0);
opacity: 0;
alpha: filter(opacity=0);
font-size: 25px;
color: rgba(0,0,0,0);
filter: alpha(opacity=0);
zoom: 1;
}
div#notice
{
background-color: green;
display: none;
position: absolute;
bottom: 0px;
left: 0px;
}
Note: This issue was there before blur was put to hide the flashing icon in IE.
In Chrome and Firefox the button only requires a single click. In IE 10 it requires a double click, which I don't want. I am trying to think of a way to make it single click.
The only thing I've tried so far is to .render("click") on the input, but that didn't work.
JSFiddle: http://jsfiddle.net/plowdawg/mk77W/
I had the same problem and found different approach. I just made that button be as big as I need with font-size on it. Then person simply can't click on text section.
<div class="divFileUpload">
<input class="fileUpload" type="file" />
</div>
and css:
.divFileUpload {
background-color: #F60;
border-radius: 5px;
height: 50px;
margin-left: auto;
margin-right: auto;
overflow: hidden;
position: relative;
width: 50%
}
.fileUpload {
cursor: pointer;
font-size: 10000px; /* This is the main part. */
height: 100%;
opacity: 0;
position: absolute;
right: 0;
top: 0;
width: 100%
}
To follow up on what SDLion said....
This might be what you see
But really on top of that there is a file upload control that has been made transparent.
Clicking on the browse button brings up the file upload dialog with one click.
In IE You have to double click the text box to the left of it if you want to see the file upload dialog.
Increase the font size of the file input to fill the button image
While #bastos.sergio is right about it happening in the text section there is a way to get around this if you are comfortable using JavaScript.
You will need:
A wrapper div tag
An inner dev tag
Some sort of form input
JQuery (tested on 2.1)
Steps:
Create the "wrapper" div
Create an inner "button " div
Place the form element underneath the inner "button" div
Set the "wrapper" and "inner" divs to the same size
Set overflow:hidden on the wrapper
Create a JQuery script for the "inner" div setting the on click function
In the "inner" function click function call .click() on the input
Seems to work for me in IE 10.
$(document).ready(
function()
{
$("#open_dialog").on("click",function()
{
$("input").click();
});
$("input").on("change",function()
{
alert($("input"));
$("#notice").html("uploading");
});
});
#open_dialog
{
position: relative;
width: 200px;
height: 50px;
color: white;
font-family: "Arial";
font-size: 14pt;
text-align: center;
top: 25px;
margin-top: -.5em;
z-index: 1;
}
#wrapper
{
width: 200px;
height: 50px;
overflow: hidden;
cursor: pointer;
border-radius: 10px;
background: green;
z-index: 0;
}
input
{
margin-top: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="open_dialog">Click Me</div>
<input type="file" />
</div>
<div id="notice">Nothing to upload</div>
The double click is happening on the text portion of the file upload, like #TravisPessetto stated.
Since it's not possible to hide/remove the text portion out of the file input control, I recommend that you put a regular button over the file input.
See here for more details.
I found another more simple solution, just trigger the event "click" on mousedown for this element only:
$("input").mousedown(function() {
$(this).trigger('click');
})
in order to avoid problems on other browsers, apply this solution to IE only:
if ($.browser.msie && parseInt($.browser.version, 10) > 8) {
$("#your_file_input").mousedown(function(event) {
if (event.which == 1) {
$(this).trigger('click');
}
})
}
here's your jfiddle modified, check it on IE 9-10:
http://jsfiddle.net/7Lq3k/
Edit: example modified in order to limit the event handling for left click only
(see: How to distinguish between left and right mouse click with jQuery for details)
I mixed various solutions to get this one that works for me (on every browser). It's written using LESS nesting.
HTML
<!--/* Upload input */-->
<div class="input-file">
Select image
<input type="file" />
</div>
LESS CSS
/*
* Input "file" type Styling
* Based on http://goo.gl/07sCBA
* and http://stackoverflow.com/a/21092148/1252920
*/
.input-file {
position: relative;
overflow: hidden;
margin: 10px;
input[type="file"] {
opacity: 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 0;
padding: 0;
cursor: pointer;
width: 100%;
height: 100%;
font-size: 10000px;
}
// For Chrome
input[type=file]::-webkit-file-upload-button {
cursor: pointer;
}
}
I'm not sure if what i want is possible but i'm using a Mootools image gallery which you can see an example of here:
</script>
function startGallery() {
var myGallery = new gallery($('myGallery'), {
timed: true,
showArrows: false,
showCarousel: false
});
}
window.addEvent('domready', startGallery);
</script>
The gallery rotation is above but what i'd like to achieve, ideally, is the second text element (with the white background) to be wider than the top text element, so it looks more like the picture underneath.
There's a lot of Javascript involved so i don't know what i should post here to enable people to help, but just let me know what i should put in here and i'll come back and edit.
Or, if some knows of somethign similar in jQuery which would allow me to get the same effect, but not require too much JS coding, i'd be much obliged.
Thanks in advance as always,
Dan
Try this css and see if its what your after.
.slideInfoZone {
position: absolute;
z-index: 10;
width: 100%;
margin: 0px;
left: 0;
top:40px;
color: #FFF;
text-indent: 0;
overflow: hidden;
padding: 10px 0 0 20px;
height: 70px;
}
.slideInfoZone h3{
background: #000;
width: 200px;
padding: 30px;
margin-left: -30px;
display:inline;
}
.slideInfoZone p {
position: absolute;
bottom: 0;
background: #FFF;
font-size: 14px;
color: #000;
margin: 20px 0 0 -20px;
padding: 10px 0 10px 20px;
width: 50%;
}
Basically what I did was remove your background color for the containing element, then I gave the p tag a bg color, and modified the padding/margin for the h3. Im not too happy with what I had to do with the h3 but without changing the markup at all it works.