I have a few items on a site I'm building that onclick activate a modal like this.
Right now the animation is a one-way in that, when you close it or click off from the modal's focus, it just disappears. From what I've been reading, people seems to use the fadeIn/slideIn animation for one time effects, but is it possible, to reverse the animation so instead of just changing display to none, it slides back out?
#modal{bottom: 0; opacity: 1; transition: bottom 400ms, opacity 400ms; }
#modal.hidden{bottom: -300px; opacity: 0}
Then in button click event:
$("#modal").addClass("hidden")
On close event:
$("#modal").removeClass("hidden")
If you need pure javascript, it would be a bit more code but essentially that's it
Depending on how you've structured your code, you can approach this in a few ways:
Make use of the animation-direction: reverse; CSS property
Use a Javascript framework (like jQuery) that enables manipulation of DOM elements (with jQuery you could do something like: $('element').slideIn(); to show the modal and $('element').slideOut(); to hide the modal).
Use CSS classes and apply / unapply them with Javascript (the option I'd recommend, and have given an example below):
$(document).ready(function() {
$('.open').on('click', function(e) {
e.preventDefault();
if ($('.modal').hasClass('hide')) {
$('.modal').removeClass('hide');
}
$('.modal').addClass('show');
});
$('.close').on('click', function(e) {
e.preventDefault();
$('.modal').addClass('hide');
if ($('.modal').hasClass('show')) {
$('.modal').removeClass('show');
}
});
});
.modal {
position: fixed;
top: 0;
left: 0;
width: 300px;
height: 300px;
left: -305px;
z-index: 999;
transition: all 0.3s ease;
background: #ffffff;
border: 1px solid blue;
}
.modal.show {
left: 150px;
}
.modal.hide {
left: -305px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click here to open modal</p>
<div class="modal">
<p>This is a modal window.</p>
<p>Click here to close</p>
</div>
Please note that this example is only there to illustrate a proof of concept - you'll need to tidy it yourself :)
Related
I have parent element which has mouseover event handler implemented using .mouseover() in Jquery.
It has 2 child elements, one contains image element, and second contains description element which has absolute position. On parent mouseover description slides on the image element.
Simplified version of code for the project would look like this:
$('.main-parent').mouseenter(function(){
$(this).addClass('item-hovered');
}).mouseleave(function(){
$(this).removeClass('item-hovered');
});
.main-parent {
position: relative;
}
.child-description {
color: #fff;
font-size: 2em;
position: absolute;
bottom: -45%;
opacity: 0;
transition: all 350ms;
}
.item-hovered .child-description {
bottom: 10%;
opacity: 1;
transition: all 350ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-parent">
<div class="child-image">
<img src="https://www.w3schools.com/w3css/img_lights.jpg">
</div>
<div class="child-description">
<h4 class="title">Title</h4>
<p class="subtitle">Subtitle</p>
<p>Lorem ipsum paragraph...</p>
</div>
</div>
As expected, .child-description is firing mouseover bind to .main-parent element, as it is its child and a part of it.
Is there a way to ignore .child-description element so that it doesn't fire function on mouseover event. The thing is before you hover the element, it is bellow the image made "invisible" to user using opacity: 0;, but it still can be hovered and used to fire mouseover of parent element.
I haven't find answer for this particular solution on stackoverflow, and if there is let me know. I appreciate your help :)
Yes, you would intercept the event for that child and then call event.preventDefault() and event.stopPropagation() as shown below.
Also, JQuery no longer recommends event shortcut methods, like mouseenter. Instead, they suggest using on().
$(".child-description").on("mouseover", function(event){
event.preventDefault(); // Cancel the event for this element
event.stopPropagation(); // Prevent the event from propagating to other elements
});
$('.main-parent').on("mouseenter", function(){
$(this).addClass('item-hovered');
}).on("mouseleave", function(){
$(this).removeClass('item-hovered');
});
.main-parent {
position: relative;
}
.child-description {
color: #fff;
font-size: 2em;
position: absolute;
bottom: -45%;
opacity: 0;
transition: all 350ms;
}
.item-hovered .child-description {
bottom: 10%;
opacity: 1;
transition: all 350ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-parent">
<div class="child-image">
<img src="https://www.w3schools.com/w3css/img_lights.jpg">
</div>
<div class="child-description">
<h4 class="title">Title</h4>
<p class="subtitle">Subtitle</p>
<p>Lorem ipsum paragraph...</p>
</div>
</div>
check whether child-description is the target of the event
$('.main-parent').mouseenter(function (e) {
if (!$(e.target).hasClass('child-description')) {
$(this).addClass('item-hovered');
}
}).mouseleave(function () {
$(this).removeClass('item-hovered');
});
Trying adding the following css rule to .child-description.
pointer-events: none;
.child-description {
color: #fff;
font-size: 2em;
position: absolute;
bottom: -45%;
opacity: 0;
transition: all 350ms;
pointer-events: none;
}
.item-hovered .child-description {
bottom: 10%;
opacity: 1;
transition: all 350ms;
pointer-events: auto;
}
This should prevent the element from responding to any mouse events. You will have to swap pointer-events: none; for pointer-events: auto; once you want the element to register interactions.
https://caniuse.com/#feat=pointer-events
I see some interesting answers here, so, I thought I would offer my own.
Why not use event.target and (in this particular case) event.target.className? Sample JSBIN Demo Online
For instance...
$('.main-parent').mouseover(function(e) {
if(e.target.className == 'subtitle') {
console.log("Child mouseover!");
return; // child mouseover, ignore
}
console.log("Parent mouseover!");
return true; // parent mouseover, activate some behavior
});
The advantage here should be observable -- you have quick, easy control of the paths of logic in relatively little code.
You should be able to prevent this using the stopPropagation method:
$('.child-description').on("mouseenter mouseleave", function(event) {
event.stopPropagation();
});
I have a question I can't seem to figure out myself.
Say I have created a paragraph that says "+1". When I click a button that already exists in my code, I can make this paragraph appear above the button and I can transform it so that it's 'y' increases and it moves up while fading slowly.
So, you click the button, a +1 appears above and moves up while fading.
How do I make it so I can create a new instance of this +1 without removing the first one if I click the button before the first one has a chance to disappear?
So, if I clicked the button really fast, a stream of +1's would appear above the button and slowly fade out, one by one. Any idea of how I would go about doing this?
Thank you!!
Here's a solution using jQuery:
$('button').on('click', function() {
var $newPlus = $('<div class="plus">+1</div>');
$('#area').append($newPlus);
setTimeout(function(){ $newPlus.addClass('fade'); }, 50);
setTimeout(function(){ $newPlus.remove(); }, 650);
});
#area {
position: relative;
padding: 70px;
}
#area .plus {
position: absolute;
left: 100px;
top: 50px;
opacity: 1;
transition: top 300ms ease-out, opacity 600ms ease-in-out;
}
#area .plus.fade {
top: 0px;
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="area">
<button>Plus One</button>
</div>
This is my jfiddle
And this is my actual code
$card.animate({
left: "1000px"
}, 500, function(){
$card.hide(500);
});
(I dont know why 'left' didnt work on jfiddle) Basically ive got a container with 5 $cards there. When user swipes the card (already implemented) the animate() is triggered and the card slides to the rightand then disappears. How can I implement such thing in CSS animations instead of using Jquery? Ive read that CSS animations run faster (and I proved it on my mobile device, the hide() runs really slow)... Any help or advice will be appreciated
First of all, create a class that you can trigger via jQuery that will have the animation.
Then, using you have two options: transition or animation. Transitions are simpler and more direct, but you can do more with animations.
Here is how I would suggest to do it: a transition for the movement, and an animation to recreate the hide() function.
#keyframes hide {
99% { display: auto; }
100%{ display: none; opacity: 0; }
}
.myelement {
transition: all .5s;
position: absolute;
left: 0;
}
.myelement.toLeft {
left: 2000px;
animation: hide .5s 1 forwards;
}
To trigger it, simply do this:
$(".myelement").addClass("toLeft");
Here is a working JSFiddle.
And like #MohitBhardwaj said, it is necessary for you to set position to absolute, relative, or static in order for positioning (i.e., the left property) to work.
It's also important to note that a transition needs an initial value. I added left: 0 to do this. Otherwise, (with a CSS transition) it would simply jump to 2000px because there is no starting point.
Also, because 2000px as a left value is very large, I suggest you change the parent element's scroll to overflow: hidden, so that the extraneous scroll bar doesn't appear.
Your left didn't work, because you need to set position to a value other than static (which is default) for it to work.
As for using CSS, you can add a class instead of animating in jQuery. This class can change the transition which you can set in css as per your requirements.
var my_div = $('.myelement');
my_div.on('click', function() {
var $this = $(this);
$this.addClass("gone");
setTimeout(function(){
$this.hide();
}, 600 );
})
#mywrapper
{
overflow: hidden;
}
.myelement {
height: 200px;
width: 200px;
background-color: red;
opacity: 1;
position: relative;
transition: all 0.5s ease;
opacity: 1;
left: 0px;
}
.myelement.gone
{
left: 500px;
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="mywrapper">
<div class="myelement">
Click me please
</div>
</div>
The little popup window appears in the middle of the original page.
The original page is covered by grey shade if not by the popup window.
The underneath original page can still be scrolled up and down.
Follow these steps:
1) Create this CSS rule:
.overlay {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
opacity: 0.5;
background: #666;
filter: alpha(opacity=50); /* opacity for IE browsers */
}
2) Add this code to your jQuery:
$("body").prepend("<div class='overlay'></div>");
3) When done, remove it like this:
$(".overlay").remove();
Didn't test this, but it should work (maybe with very minor modifications). This is one way, if you prefer doing it by yourself. You can, however, use existing solutions such as Twitter's Bootstrap lib which is cool, and I recommend it.
http://twitter.github.com/bootstrap/
Regards.
You could use the JQueryUI dialog widget http://jqueryui.com/dialog/#modal
This is easy enough to achieve with some simple CSS...
The overlay (the grey background) is fixed in place and covers everything below:
#overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
opacity: 0;
filter: alpha(opacity=0);
z-index: 2; // above content
}
The "dialog" itself is similar in style, but smaller:
#dialog {
display: none;
position: fixed;
width: 500px;
height: 250px;
background-color: #fff;
z-index: 3; // above 'overlay'
}
The top and left attributes can be calculated with simple JavaScript, so that the dialog can be positioned in the center of the browser:
positionDialog = function() {
if (typeof window.innerHeight != 'undefined') {
dialog.top = parseInt(window.innerHeight / 2) - dialog.height;
dialog.left = parseInt(window.innerWidth / 2) - dialog.height;
}
}
And also upon window resize:
$(window).resize(function() {
positionDialog();
}
Notice how the CSS sets these DIVs to display: none. They are hidden until called, which is done by setting them to display: block.
These days, I find that it's much simpler and more robust to rely on jQuery UI's excellent dialog widget.
It's called a light box. There's a way that you can do it using only CSS:
http://www.emanueleferonato.com/2007/08/22/create-a-lightbox-effect-only-with-css-no-javascript-needed/
The key for darkening the background is the CSS opacity property of a box that you cover the background with, which you can set a black background and use this CSS for transparency:
-moz-opacity: 0.8;
opacity:.80;
You could take a look at the modal included in Twitter Bootstrap: http://twitter.github.com/bootstrap/javascript.html#modals
Is there a way to change how fast the tooltip from an element's "title" attribute? I'd like it if the tooltip appeared immediately, but it seems to take a few seconds to appear.
No, there's no way. The title attribute is implemented in a browser dependent fashion. For example I remember differences between IE and FF when using \r\n inside it.
Mozilla's docs explain the limits and functionality well.
If you want customization you may take a look at third party plugins such as qTip2 which mimic it using divs and stuff and provide you full control.
You could use jqueryUI as suggested. An example of controlling the duration on the show property:
$( ".selector" ).tooltip({ show: { effect: "blind", duration: 800 } });
Jquery UI tooltip is extremely simple and customizable: Just download or include jquery UI in your page.
If you want all the tooltips of your page to show immediately at hover, just use this:
$(document).tooltip({show: null});
Note that this applies to all elements that have a 'title' attribute.
You can modify the selector to affect only a class, and set custom speed or effect:
$('.yourClass').tooltip({show: {effect:"none", delay:0}});
Unfortunately, there is no way to do this yet,
so I am using the following methods to help. (No dependencies required)
<style>
[title] {
position: relative;
}
[title]:after {
content: attr(title);
position: absolute;
left: 50%;
bottom: 100%; /* put it on the top */
background-color: yellow;
width: max-content;
opacity: 0;
-webkit-transition: opacity 0.75s ease-in-out; /* 👈 Change the time to meet your requirements. */
}
[title]:hover:after {
opacity: 1;
}
</style>
<div style="min-height:5rem"></div>
<div style="min-width: 5rem; border: 2px solid red;" title="hello world">my div</div>
<button title="for debug">button</button>
If you don't want the title to conflict with it, you can use data-* w3school.data-* help you, for example.
<style>
[data-tooltip] {
position: relative;
}
[data-tooltip]:after {
content: attr(data-tooltip);
position: absolute;
left: 50%;
bottom: 100%; /* put it on the top */
background-color: yellow;
width: max-content;
opacity: 0;
-webkit-transition: opacity 0.75s ease-in-out;
}
[data-tooltip]:hover:after {
opacity: 1;
}
div[data-tooltip]:after {
left: 5px!important;
}
</style>
<div style="min-height:5rem"></div>
<div style="min-width: 5rem; border: 2px solid red;" data-tooltip="hello world">my div</div>
<button data-tooltip="for debug">button</button>
<button title="for debug">title only</button>
<button data-tooltip="my tool tip msg" title="my title msg">title and tooltip</button>
below link may help you too.
fade in and out on simple css tooltip
It isn't possible to change how fast default browser's tooltip appear, but you can use one of the tooltip plugins (here is few: http://www.1stwebdesigner.com/css/stylish-jquery-tooltip-plugins-webdesign/ ) where you can customise lot's of things, including delay.
TippyJS has a billion customization options.
https://atomiks.github.io/tippyjs
https://github.com/atomiks/tippyjs