CSS-3 Transform bug, menu appearing stuck - javascript

I am using this plugin called transit.js to create a simple menu animation and basically I have the following menu, see below:
The code for the open and close of the menu is as follows:
$('.main-header .nav-toggle-button').on('click' , function() {
// $('.main-header .navigation').toggleClass('show');
if ($('.main-header .navigation').hasClass('show')) {
$('.main-header .navigation').stop().removeClass('show');
return false;
}
$('.main-header .navigation').stop().transition({
perspective: '1000px',
rotateY: '180deg',
duration : 0
}, function() {
$(this).addClass('show').stop().transition({ rotateY: '0' });
});
return false;
});
DEMO HERE, (I am sorry, the fiddle just doesn't recreate this issue.)
BUG: As you can see on close there is no animation, the menu goes away, now this bug occurs when the page is scrolled more than
200px+ and below 992px width, so basically when you click on the
hamburger, the menu opens with a rotate animation but when you
click the hamburger again the menu sometimes doesn't close even though
the 'show' class has been removed form the menu.
This is one of these bugs that is just beyond me, inspecting in the console and going through the JS code has just not really helped.
I would really appreciate if anyone can point out what I am doing wrong here, as the JS and CSS really seems to be perfect but the css transforms using transit is just not working as expected.

As already mentioned seems to be a Chrome bug, I tried editing the CSS on your demo and this solution seems to work ... try adding a "z-index" to -1 here:
#media (max-width: 992px)
.navigation {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #fff;
background: rgba(255,255,255,.95);
z-index: -1; // ADD THIS
}

An alternate solution to your problem..
The problem I found is, on smaller screens, your mini-menu appears on-click of hamburger icon. But it doesn't disappear when clicked on hamburger icon again.
However, it disappears immediately if you scroll the window. So, I added two lines inside the if statement which actually scrolls the window 1px down and then 1px up (to keep the position of the document same). Add the following code inside your if statement (before return false; line).
window.scrollBy(0, 1);
window.scrollBy(0, -1);

I think that your mistake is that you re using the hover event to add and remove the animation, he just fire once that your mouse is over the element:
/* dropdown */
$('.navigation .dropdown-menu-item').hover(function() {
$('.navigation .dropdown-menu-item').find('.dropdown-menu-list').removeClass('opened');
$(this).find('.dropdown-menu-list').stop().transition({ 'y' : '20px' , duration: 0 } , function() {
$(this).addClass('opened').stop().transition({ 'y': 0 });
});
return false;
}, function() {
$(this).find('.dropdown-menu-list').removeClass('opened');
});
Use mouseenter and mouseleave events to add and remove the dropdown list animation, by this way you gonna have the events fired at over and leave:
$(document).on('.navigation .dropdown-menu-item', 'mouseenter', function(){
$('.navigation .dropdown-menu-item').find('.dropdown-menu-list').removeClass('opened');
$(this).find('.dropdown-menu-list').stop().transition({ 'y' : '20px' , duration: 0 } , function() {
$(this).addClass('opened').stop().transition({ 'y': 0 });
});
return false;
})
$(document).on('.navigation .dropdown-menu-item', 'mouseleave', function(){
$(this).find('.dropdown-menu-list').removeClass('opened');
})

Here is css solution...
with this your menu will open and close smoothly
add following css to your code and over-wright
#media(max-width:991px) {
.navigation {
transition: all 0.4s;
-webkit-transition: all 0.4s;
display: block;
transform: rotateY(90deg) !important;
-webkit-transform: rotateY(90deg) !important;
perspective: 1000px !important;
-webkit-perspective: 1000px !important;
opacity: 0;
visibility: hidden;
}
.navigation.show {
display: block;
opacity: 1;
transform: rotateY(0deg) !important;
-webkit-transform: rotateY(0deg) !important;
visibility: visible;
}
}
ENJOY...

Related

How can I stop this jQuery from bugging out?

So I'm trying to create a box that has two layers: The front layer and the back layer. They're going to be stacked on top of each other so the back layer is hidden by default.
When you hover over the top of the box (front layer technically), then the front layer is supposed to slide up revealing the back layer. I tried to do this by using .slideUp() and .slideDown() but it kept bugging out revealing both layers at the same time. So then I switched to just .slideUp() and .fadeIn() but that didn't seem to help too much.
As you can see, it sometimes shows both divs when it's not supposed to and it also slides multiple times randomly. How could I make this more efficient?
Here is a JsFiddle
UPDATE:
Questions seeking debugging help ("why isn't this code working?") must
include the desired behavior, a specific problem or error and the
shortest code necessary to reproduce it in the question itself.
Questions without a clear problem statement are not useful to other
readers.
That is the reason people are voting to close this answer... What does this question not have, from that list?
Desired behavior? - Check
Specific problem? - Check
Shortest code necessary? - Check
Clear problem? - check
You don't really need to use slideUp and slideDown, you can achieve the slide effect by using the transform and transition CSS3 properties.
Updated JS fiddle: https://jsfiddle.net/9uw2q24h/3/
Javascript:
$('.outer').hover(function() {
$(this).children('.front').addClass('front-up');
}, function() {
$(this).children('.front').removeClass('front-up');
});
CSS:
.outer {
position: relative;
.front,
.back {
text-align: center;
width: 100%;
}
.back {
display: block;
}
.front {
position: absolute;
transition: 0.5s ease;
}
.front-up {
transform: translateY(-100%);
}
}
If you have to support older browsers, make sure to add the vendor prefixes to the transition and tranform rules (-webkit-, -moz-, etc.).
You can do this like:
var running = false;
$('.outer').hover(function() {
if (!running) {
running = true;
$(this).children('.front').slideUp(function() {
$(this).next('.back').slideDown(function() {
running = false;
});
});
}
}, function() {
if (!running) {
running = true;
$(this).children('.back').slideUp(function() {
$(this).prev('.front').slideDown(function() {
running = false;
});
});
}
});
Explanation: as soon as the animation starts you save the status in a variable in order to avoid conflicts (otherwise it will be called again). Additionally with the slideDown and slideUp combined you have a much smoother animation. You had a not very nice flickering with your combination of fadeOut and slideDown
Fiddle: https://jsfiddle.net/dL7ckq6b/
With a slight tweak to your CSS, specifically making your elements' position property absolute, will cause your back element to be behind your front element from the start, now you only have to show/hide your front element.
Javascript:
$('.outer').hover(function() {
$('.front').slideUp();
console.log("IN");
}, function() {
$('.front').slideDown();
console.log("OUT");
});
I did also update the CSS to more clearly show the effect happening.
CSS:
.outer {
.front,
.back {
text-align: center;
position: absolute;
padding: 20px 10px;
border: 2px solid yellow;
}
.front {
z-index: 10;
background-color: red;
}
.back {
z-index: 0;
background-color: blue;
}
}
Here is the JSFiddle: https://jsfiddle.net/z8e7eb4b/

How can I make this Jquery animate() with css3 animations?

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>

Invert scroll on rotate(180d)

Having a small problem. (Refer to fiddle)
I've got a container in my project that has been rotated 180 deg, with a container inside that has been rotated another 180 back to the original state.
I need to invert the scroll.
How would i go about this?
Dont mind wasting your time with a method, that reverts the basic setup.
The basic setup has to stay.
http://jsfiddle.net/vavxy36s/
Description of fiddle:
"Start" marks the initial string and "end" ofcourse the last one.
If you try scrolling you will realize, that it's inverted as to how one would normally scroll.
.class1 {
height: 200px;
background-color: blue;
color: white;
width: 100px;
overflow-y: scroll;
overflow-x: hidden;
direction: rtl;
-webkit-transform: rotate(180deg);
}
.class2 {
direction: ltr;
-webkit-transform: rotate(180deg);
}
EDIT: Just mousewheel scroll, has to be inverted.
Edit: Your original setup has different behaviors in Chrome and in [IE & Firefox]. In Chrome, the scroll is already inverted, but in FF and IE, the scroll remains normal. My solution reverts it in both cases, but the behaviors remain different across browsers.
You could add these styles:
/* ...
Your original styles
...
*/
.class1 {
overflow: hidden;
position: relative;
}
.class2 {
position: absolute;
bottom: 0;
}
And then, using jQuery, modify the bottom CSS property of .class2:
var scrollPos = 0,
diff = $('.class2').height() - $('.class1').height();
$('.class1').on('mousewheel', function(e) {
scrollPos = Math.min(
0,
Math.max(
-diff,
scrollPos + e.originalEvent.wheelDelta
)
);
$('.class2').css('bottom', scrollPos);
});
JS Fiddle Demo
You could use the mousewheel library to catch and invert the scroll movement.
$(".class1").mousewheel(function(event) {
event.preventDefault();
this.scrollTop -= (event.deltaY * event.deltaFactor * -1);
});
You can view a demo here: http://jsfiddle.net/fduu20df/1/

Can you fix a div and make it change opacity, size and position as you scroll with CSS3

I'm not even sure how to search this question. But effectively I'm trying to figure out how this website is achieving this fixed opacity/size changing effect on their table: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial . If you scroll down you'll see the effect on the table. When you hover over it it pops out having the data more visible.
The only thing I can think of is using a fixed div that when scrolled past a certain point triggers a jquery UI event that shrinks while decreasing opacity and then an on hover event that reverses this effect.
Achieving this animation in the way I described above seems inefficient and I'm not sure if more (or all) can be done with CSS3. So basically can you achieve the effect shown on the page provided completely or almost completely in CSS3.
Also i looked at the source of the page and couldn't fish it out of the css and scripts they include.
Here's a fiddle of what I have so far. Haven't started on scrolling yet:
HTML
<div id="stuff">Blahblah</div>
CSS
div {
width:250px;
height:250px;
border:2px solid #a1a1a1;
}
JavaScript
$( "#stuff" ).click(function() {
$( "#stuff" ).animate({
width: "20%",
height:"20px",
opacity: 0.4
}, 1500 );
});
http://jsfiddle.net/thed0ctor/1kx5jg1e/
You could do this easily with a combination of CSS3 transform and a bit of Javascript / jQuery:
Demo Fiddle: http://jsfiddle.net/abhitalks/hcwyth8n/2/
Relevant CSS:
#hanger {
width: 200px; height: 200px;
background-color: #00f;
position: fixed; /* Position fixed important */
top: 10px; right: 10px;
opacity: 1;
transition: 0.5s all; /* Animate transitions */
}
#hanger.dim { /* Style to make it appear dimmed */
transform: scale(.75); /* Make it smaller */
opacity: 0.5; /* Make it dimmer */
}
#hanger.dim:hover { /* To change back on hover only when it is dimmed */
transform: scale(1); /* Back to original size */
opacity: 1; /* Back to original opacity */
}
Relevant jQuery Code:
$(window).on("scroll", function() { /* When window scrolls, */
if ($(window).scrollTop() > 50) { /* Check if it scrolls more than 50 pixels */
$("#hanger").addClass("dim"); /* Apply class dim */
} else {
$("#hanger").removeClass("dim"); /* Otherwise remove class dim */
}
});
Hope that helps.
.
Pseudo code only:
window.scroll(function(){
if (window.scrolltop > selectedElement.offset().top){
selectedElement.animate({
transform: scale(.75),
opacity: .5
position: fixed
});
}else{
selectElement.animate({
transform: scale(.75),
opacity: 1
position: static
});
}
});
The links provided in the he pseudo code should point you in the right direction.

get previous siblings, accordion effect

I'm trying to get an accordion effect on a DIV when hovering.
The right side of the accordion is working already, but the left one isn't.
I put my code in jsFiddle
Can someone please help me with the left side? I've been trying it for hours but it won't work :(
Javascript:
$(document).ready(function () {
$('.middle').hover(function () {
$(this).siblings().stop().animate({
opacity: 1
}, 200);
},
function () {
$(this).siblings().stop().animate({
opacity: 0
}, 200);
});
});
The reason the right is fading, and the left isn't is because you are applying a CSS transition to the right side spans.
You can easily address this by applying the same transition to <span> tags:
.squares span {
transition-property:opacity;
transition-duration:1s;
transition-delay:0.1s;
}
In fact, you could condense your code and make it easier to adjust overall by combining repeated styles across the multiple spans into single definitions.
For example:
.squares span {
opacity: 0;
float: left;
width: 139px;
height: 138px;
transition-property:opacity;
transition-duration:1s;
transition-delay:0.7s;
}
span.middle {
background:#0f0;
opacity: 1;
}
span.left1,
span.right1 {
background:#00F;
transition-delay:0.1s;
}
span.left2,
span.right2 {
background:#0FF;
transition-delay:0.3s;
}
span.left3,
span.right3 {
background:#0F0;
transition-delay:0.5s;
}
span.left4,
span.right4 {
background:#FF0;
transition-delay:0.7s;
}
See the working example here: http://jsfiddle.net/uBBZ2/14/
In your css you set the transition-property and transition-duration settings on the right side blocks, but not the left side ones. If you comment them out, both transitions happen quickly and at the same time. If you add those settings mirrored to the left side, they both happen more slowly.

Categories