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
Related
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>
As you see, I have list and button. When 'click' event triggered on the button, I dynamically add new element to the list. After new element is added to the list, I want to animate it on hover state with javascript, but it's not working. Everything is fine with hard coded list elements.
First solution which comes to mind is to hard code max number of the list elements and when hide what is unnecessary. But what, if i don't know max number of elements?
Here is code
Html
<section>
<div class='wrap'>
<ul>
<li class="box"></li>
<li class="box stacked"></li>
</ul>
</div>
<button> addBox </button>
</section>
Css/Sass
.box
width: 100px
height: 100px
border: 1px solid black
background: orange
flex-basis: 1
.stacked
margin-left: -50px
.up
animation-name: boxUp
animation-duration: 300ms
animation-timing-function: ease-in-out
animation-delay: 0s
animation-iteration-count: 1
animation-direction: normal
animation-fill-mode: forwards
#keyframes boxUp
from
transform: translate(0, 0)
to
transform: translate(0, -25px)
Javascript
$('button').click(function(e) {
$('ul').append($('<li>').attr('class', 'box stacked'));
});
$('.box').hover(function() {
$(this).addClass('up');
}, function(){
$(this).removeClass('up');
});
Since it is a dynamically added element, it won't be present in the DOM at the time the event handlers are attached. So, you will have to use delegation from a parent which is present in the DOM right from the start (that is, use a parent which is a static content of the page and is present right from load).
You could use either the below:
$('body').on('mouseenter mouseleave', `.box`, function() {
$(this).toggleClass('up');
});
or the one below which you ended up using:
$('ul').on('mouseenter mouseleave', 'li', function(){
$(this).toggleClass('up');
});
CodePen Demo
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>
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;
}
I'm currently working on a website, and I got a navigation bar, which I placed at the bottom of the page, I want to make it so that when I click on one of my buttons, the navigation bar slides up to the top of my page, and when i click on that same button again, it goes back to its original position (bottom of the page).
Ive already got this piece of code written in JQuery to make my navigation bar slide up:
jQuery:
$(document).ready(function () {
$('.nav-top').click(function () {
$('#navigation').animate({ "top": "0" }, 500);
})
});
HTML:
<nav id="navigation">
<div class="logo">
<span class="color">B</span>AICA
</div>
<div id="menu">
<ul>
<li>
About me
</li>
<li>
Portfolio
</li>
<li>
Contact
</li>
</ul>
</div>
</nav>
CSS:
#navigation {
background-image: url('../images/header/navigation/bl-opacity50.png');
*background-image: url(../images/header/navigation/bl-opacity50.png);
background-repeat: repeat;
position: absolute;
width: 100%;
height: 100px;
z-index: 1000;
}
Do i have to write some kind of IF statement?
EDIT:
It all worked out fine, but when I try to make a second button, for making my navigation bar move back to the bottom of my page, its not doing anything, so what i want is a button for moving the navigation bar to the top of the page, and a button for moving it to the bottom of the page?
Use .toggleClass and keep the positioning in the CSS:
http://jsfiddle.net/WkFP2/
Yes, You have to write an if statement in your jquery code. The reason is , your jquery code will work only for the first time, where it moves the div from bottom to div. When you click it again, it will still make the element to move to top only. So you need an if statement which calculates the current position of your div and move it to either top or bottom.
$(document).ready(function () {
$('.nav-top').click(function () {
if($('#navigation').position.top()!=0)
$('#navigation').animate({ "top": "0" }, 500);
else
$('#navigation').animate({ "bottom": "0" }, 500);
})
});
You can add a css transition with a .toggleClass if you can set the height in the #navigation.top styling (using 85% as an example).
#navigation.top {
top: 85%;
}
The transitions
#navigation {
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
position: absolute;
width: 100%;
height: 100px;
z-index: 1000;
top: 0;
border: 1px solid #333;
}
Here's a fiddle (forked from a previous answer).
http://jsfiddle.net/CmbPJ/