jQuery click event not correct after second click - javascript

I've been playing around with this all evening, but can't seem to figure out whats wrong with my code.
http://jsfiddle.net/486egfut/
When you click the menu button, the navigation will show up, animated with CSS. When you click it again, it disappears. Also CSS animated.
But if you click it a third time, the class collapsed gets added, and immediately removed again.
What is the correct way of doing this. Animating the height of an element with CSS, and toggling the display after the animation with jQuery?
I've also tried multiple .on() events, but unsuccesfull (see below)
$('body').on('click', '.icon-mobile-menu', function(e){
e.preventDefault();
$(this).addClass('menu-open');
$nav.addClass('collapsed').height(312);
}).on('click', '.menu-open', function(e){
e.preventDefault();
$(this).removeClass('menu-open');
$nav.css('height', '').on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
$nav.removeClass('collapsed');
});
});
Thanks.

The problem is that the handler of the transition effect you are binding triggers EVERYTIME when there is a height change, which includes when you try to collapse the dialog.
Here is a working fix, although it is a bit dirty:
$(document).ready(function () {
var $nav = $('.navigation'),
$header = $('.header');
$('.icon-mobile-menu').on('click', function () {
$(this).toggleClass('menu-open');
if ($nav.hasClass('collapsed')) {
$nav.css('height', '').on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function () {
// Fix goes here
if ($nav.height() == 0){
$(this).removeClass('collapsed');
}
});
} else {
$nav.addClass('collapsed').height(75); // fixed height is for demo purposes only.
}
});
});
http://jsfiddle.net/486egfut/12/
Note: Why your first click is working is because you only bind that transition handler on your first click.

u can try
(function ($) {
$(document).ready(function () {
$('.icon-mobile-menu').on('click', function () {
$(this).toggleClass('menu-open');
$('.navigation').toggleClass('nav-slide');
});
});
})(jQuery);
.icon-mobile-menu {
background: red;
padding: 5px 10px;
cursor: pointer;
}
.menu-open {
background: blue;
color: white;
}
.navigation {
margin-top: 4px;
background: green;
padding: 5px 10px;
opacity: 0;
height: 0;
overflow: hidden;
-moz-transition:all 0.35s cubic-bezier(0.7, 0, 0.3, 1);
-o-transition: all 0.35s cubic-bezier(0.7, 0, 0.3, 1);
-webkit-transition: all 0.35s cubic-bezier(0.7, 0, 0.3, 1);
transition: all 0.35s cubic-bezier(0.7, 0, 0.3, 1);
}
.nav-slide{
height: 75px;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<header class="header">
<span class="icon-mobile-menu">menu</span>
</header>
<div class="navigation">
<ul>
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>
</div>

Related

Smooth toggle Javascript function

Well what I want to do is to toggle a menu when is clicked but it's not smooth and it feels tough, I'm a newbie in JS but I do know CSS and HTML well enough, so is there a way to smooth this toggle function?
menu unclicked:
menu clicked:
const toggleButton = document.getElementsByClassName("nav__toggle-button")[0];
const navbarLinks = document.getElementsByClassName("nav__links")[0];
toggleButton.addEventListener("click", () => {
console.log("clicked");
navbarLinks.classList.toggle("active");
toggleButton.classList.toggle("open");
});
If you want to solve this with CSS you can 'animate' the two divs with the transitions property: https://www.w3schools.com/css/css3_transitions.asp
close state:
div {
opacity: 0;
transition: opacity 1s;
}
open state:
div.active {
opacity: 1;
transition: opacity 1s;
}
Two minors:
don't use BEM classes to trigger an event listener, use instead a proper class (js-click or something..)
a small refactor for your first two lines:
const [toggleButton] = document.querySelectorAll(".nav__toggle-button")
const [navbarLinks] = document.querySelectorAll(".nav__links")
You can apply transition and transform properties to the element through CSS.
For example, if you are using a drop down menu and controlling the slide and the opacity:
transform: translateY(-10px);
transition: opacity 150ms ease-in-out, transform 150ms ease-in-out;
You could check out:
https://developer.mozilla.org/en-US/docs/Web/CSS/transition
All you need is a transition and transform property that you can toggle. Transform CSS property is used for handling dimensions, orientation etc of a DOM element. Adding transition adds an effect where the transform properties if changed, change gradually.
const closeButton = document.getElementById("close")
closeButton.addEventListener("click", () => {
const menu = document.getElementById("nav-links")
menu.classList.toggle("closed-list");
})
ol {
width: 100%;
list-style-type: none;
background: gray;
transition: all 0.4s ease-in-out;
}
.closed-list {
transform: scaleY(0);
transform-origin: top;
}
li {
text-align: center;
padding: 12px 0px;
color: white;
font-weight: 700;
font-size: 18px;
}
#close-container {
text-align: right;
}
<div>
<div id="close-container">
<button id="close">
open/close
</button>
</div>
<ol id="nav-links">
<li>Test 1</li>
<li>Test 2</li>
<li>Test 3</li>
<li>Test 4</li>
</ol>
</div>

JQuery Mobile Listview Swipe Menu

I have a standard JQM page with a ListView with auto generated dividers.
I'd like to be able to add some functionality tat would allow the user to swipe left OR right on an item within the listview and it done either of the following;
1) Reveal a star icon and create some info in localstorage. On swiping a second time change the icon to a 'hollow' star and remove the value in localstorage
2) Reveal a 'hollow' star icon which when clicked on creates a value in locastorage and the icon is replaced with a 'filled' star. Likewise, if the star is pressed a second time, the localstorage value is removed and the icon reverts to a 'hollow' star
Im sure Ive seen info on a similar topic elsewhere but can't seem to find it today. So any pointers, tips, links would be greatly appreciated.
Thanks.
Create span element which will contain star. Add spans before each li element.
<ul data-role="listview" id="list">
<span class="yellowStar"></span>
<li>Item 1</li>
<span class="hollowStar"></span>
<li>Item 2</li>
<span class="hollowStar"></span>
<li>Item 3</li>
<span class="hollowStar"></span>
<li>Item 4</li>
<span class="hollowStar"></span>
<li>Item 5</li>
</ul>
Apply the following CSS for both filled and hollow stars.
.ui-listview>.ui-li-static {
overflow: initial; /* to hide spans underneath */
-webkit-transition: -webkit-transform 300ms ease; /* transition effect */
-moz-transition: -moz-transform 300ms ease;
-o-transition: -o-transform 300ms ease;
transition: transform 300ms ease;
}
ul span {
float: right;
padding: 1.3em 20px;
z-index: -1;
}
ul .yellowStar {
background-image: url(filled.png);
background-repeat: no-repeat;
background-position: center;
}
ul .hollowStar {
background-image: url(hollow.jpg);
background-repeat: no-repeat;
background-position: center;
}
And then attach swipeleft to reveal star.
$(document).on("click", "ul span", function () {
$(this).toggleClass("yellowStar hollowStar");
}).on("swipeleft", "ul li", function (e) {
$(this).off("click");
$(this).css({
transform: "translateX(-40px)"
}).one("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function () {
$(this).one("click swiperight", function () {
$(this).css({
transform: "translateX(0)"
});
});
});
});
Whenever swipe is fired, it also fires click, hence, .off("click") is essential when swipe triggers. However, once the transition ends, click and swiperight listeners are attached to close/hide star.
Demo

jQuery - Click Add/Remove Class - Multiple Buttons

For some reason when I add the second click function it stops working completely. I was wondering if anybody could help pin point what the issue might be?
What I'm trying to do:
The default state is "day" and when "night" is clicked, it removes the day class and adds the night class. Which changes the background image. Which works... Sort of. However, when I add the function for the day button to add the day class and remove the night class is breaks and doesn't work.
Here's a fiddle of what I have: http://jsfiddle.net/790hqykq/3/
$(document).ready(function () {
$('.night').click(function () {
$('#room').addClass('night');
$('#room').removeClass('day');
});
$('.day').click(function () {
$('#room').addClass('day');
$('#room').removeClass('night');
});
});
Thanks!!
Edit: Also - Is there any way to fade this class change? Similar to fadeIn/fadeOut? Thanks!
jsFiddle Demo
The problem with your fiddle is that the #room element has the class day. So does the anchor element. When the event handler is setup
$('.day').click(function () {
It is also assigned to the room element, and as a result of that, #room ends up also having the event handler attached to it. This causes day to always be selected as the element's class, even when night is clicked.
You should consider changing the class name to something like daycolor and nightcolor
<div id="room" class="daycolor">
and
#room.daycolor {
background: #00CCFF;
}
The element with ID room has the class day, as one of the elements within it.
When you attach the handler, it's being attached to both elements.
This should solve your problem:
$(document).ready(function () {
$('.timeButton.day').click(function () {
$('#room').addClass('day').removeClass('night');
});
$('.timeButton.night').click(function () {
$('#room').addClass('night').removeClass('day');
});
});
As per your complement about fading, you can use CSS 3 to achieve this:
#room {
-webkit-transition: background 0.5s linear;
-moz-transition: background 0.5s linear;
-ms-transition: background 0.5s linear;
-o-transition: background 0.5s linear;
transition: background 0.5s linear;
}
Demo
Change the classnames on your children elements and use that selector for your events.
jsFiddle
HTML:
<div id="container">
<div id="room" class="day">
<a class="timeButton day1">Day</a>
<a class="timeButton night1">Night</a>
</div>
</div>
JS:
$(document).ready(function () {
$('.night1').click(function () {
$('#room').addClass('night');
$('#room').removeClass('day');
});
$('.day1').click(function () {
$('#room').addClass('day');
$('#room').removeClass('night');
});
});
Style:
#container {
width: 300px;
margin: 0 auto;
}
#container a, #container div {
float: left;
display: block;
}
#room {
width: 300px;
height: 200px;
position: relative;
}
#room.day {
background: #00CCFF;
}
#room.night {
background: #0000CC;
}
#room .day1 {
left: 30px;
border: 1px solid black;
}
#room .night1 {
right: 30px;
border: 1px solid black;
}
#room .timeButton {
position: absolute;
width: 80px;
height: 25px;
top: 30px;
cursor: pointer;
text-align: center;
}
#room .timeButton:hover {
background: #fff;
}
Here is another solution, where I just change the css-style via jquery.
Javascript:
$(document).ready(function () {
$('.day').click(function () {
$('#room').css("background-color", "#00CCFF");
});
$('.night').click(function () {
$('#room').css("background-color", "#0000CC");
});
});
Also you need to add a background-color to #room:
background: #00CCFF;
Fiddle:
http://jsfiddle.net/790hqykq/7/
In your script, you reference to ".night" instead ".nightButton".
$('.nightButton').click(function () {
$('#room').addClass('night');
$('#room').removeClass('day');
});
$('.dayButton').click(function () {
$('#room').addClass('day');
$('#room').removeClass('night');
});
To achieve the transition, you can add this CSS propertie to #room.
-webkit-transition: background 2s; /* For Safari 3.1 to 6.0 */
transition: background 2s;
http://jsfiddle.net/790hqykq/13/
you can add css3 for the transitions from day to night.
it wont working in older IE browsers 9 and under but is excellent in all modern browsers.
browser support. You can use this generator to make the code faster.
#room {
width: 300px;
height: 200px;
position: relative;
-webkit-transition: background 1000ms ease-in-out;
-moz-transition: background 1000ms ease-in-out;
-ms-transition: background 1000ms ease-in-out;
-o-transition: background 1000ms ease-in-out;
transition: background 1000ms ease-in-out;
}
Demo jsfiddle

Animate easy in and easy out when hover a link

Hi guys i want to make a menu similar to this site: http://tommasoraspo.com/creativepartners/DesignLovers/index.html
But I don't know how i would animate the Bookmark to show up when i hover a link. I thought in using animate.css (slideInDown animation) but then it would only show up when hover over but wouldn't get back when hover out.
Initiate Animation on Hover:
function animationHover(element, animation){
element = $(element);
element.hover(
function() {
element.addClass('animated ' + animation);
},
function(){
//wait for animation to finish before removing classes
window.setTimeout( function(){
element.removeClass('animated ' + animation);
}, 2000);
});
}
The site you point to isn't using an javascript. Rather, they are using css3 transitions to animate the background position of an image that is "off-canvas" when the site is loaded.
Here's a fiddle with the relevant css/html.
You may have to tweak the values to suit your specific design and image.
HTML:
<ul class="nav">
<li>Menu Item 1
</li>
<li>Menu Item 2
</li>
<li>Menu Item 3
</li>
<li>Menu Item 4
</li>
</ul>
CSS:
ul.nav {
list-style: none;
margin: 0;
}
ul.nav li {
float: left;
margin: 0 0 0 30px;
}
ul.nav li.current a, ul.nav li a:hover {
background-position: 50% 0;
}
ul.nav li a {
height: 50px;
line-height: 50px;
display: block;
padding: 50px 20px 0;
position: relative;
background: url(http://lorempixel.com/50/70/abstract/) no-repeat 50% -90px;
-webkit-transition: background-position 0.2s linear;
-moz-transition: background-position 0.2s linear;
transition: background-position 0.2s linear;
}

Jquery Hover Class Fade with Background Image

I have the following Jquery script below that adds a the .hover class on rollover and then removes it on rollout. Currently, the background (whether image or color) fades in and out nicely. However, I don't want the menu text to fade in and out.
I'm aware of the CSS3 fade transitions and the Jquery color plugins but would like to have the option of fading in image backgrounds as well (which is why I'd like to fade in a class rather than just background-color.) Any help would be most appreciated:)Thanks in advance.
Jquery
$(document).ready(function () {
//Set the anchor link opacity to 0 and begin hover function
$("#menu-sample-menu li a").hover(function () {
//Fade to an opacity of 1 at a speed of 200ms
$(this).fadeOut(0).addClass('hover').fadeIn(300);
//On mouse-off
}, function () {
//Fade to an opacity of 0 at a speed of 100ms
$(this).fadeOut(300)
.queue(function () {
$(this).removeClass('hover').fadeIn(0).dequeue()
});
});
});
HTML
<nav id="access">
<ul id="menu-sample-menu" class="menu">
<li id="menu-item-198" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-198">Health Care Professional
</li>
<li id="menu-item-197" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-197">Web Designer
<ul class="sub-menu">
<li id="menu-item-199" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-199">Construction Worker
</li>
</ul>
</li>
</ul>
</nav>
Style
#access li {
position:relative;
float:left;
padding:0;
margin:0;
}
#access ul li:first-child {
padding-left:0;
}
#access a {
display:block;
padding:15px 24px;
color:#f0f0f0;
text-decoration:none;
}
#menu-sample-menu li {
color: black;
text-shadow: 0px 1px 4px #777;
background-color: green;
padding: 0 12px 0 12px;
}
#menu-sample-menu li a.hover {
background-color: orange;
background-image: url(images/over.jpg);
}
You can do this without javascript: http://jsfiddle.net/WjrnB/1/
Simply use:
#menu-sample-menu li a:hover {
background-color: orange;
background-image: url(images/over.jpg);
}
instead of
#menu-sample-menu li a.hover {
background-color: orange;
background-image: url(images/over.jpg);
}
and add:
#menu-sample-menu li a {
-khtml-transition: all 0.5s;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-o-transition: all 0.5s;
-ms-transition: all 0.5s;
transition: all 0.5s;
}
Xarcell's answer is probably the best simplicity-wise. If you are looking to accomplish this with JavaScript, one option would be using JQuery-UI which has addClass and removeClass functions which incorporate transitions.
Basically, the HTML and CSS is the same as above, but the JS would look as follows:
$(document).ready(function () {
//Set the anchor link opacity to 0 and begin hover function
$("#menu-sample-menu li a").hover(function () {
//Fade 'hover' class in at 300ms
$(this).addClass('hover', 300);
//On mouse-off
}, function () {
//Fade 'hover' class out at 300ms
$(this).removeClass('hover', 300);
});
});
And, of course, you would have to include JQuery-UI (I usually use Cloud Flair's CDNJS):
http://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js
Personally, I would use this method if I was already using JQuery-UI. Otherwise, I would go with Xarcell's solution.

Categories