I have following jQuery code for re-ordering list:
$("li").live("click", function() {
var $myLi = $(this);
var listHeight = $("ul").innerHeight();
var elemHeight = $myLi.height();
var elemTop = $myLi.position().top;
var moveUp = listHeight - (listHeight - elemTop);
var moveDown = elemHeight;
var liId = $myLi.attr("id");
var enough = false;
var liHtml = $myLi.outerHTML();
$("li").each(function() {
if ($(this).attr("id") == liId) {
return false;
}
$(this).animate({"top": '+=' + moveDown}, 1000);
});
$myLi.animate({"top": '-=' + moveUp}, 1000, function() {
$myLi.remove();
var oldHtml = $("ul").html();
$("ul").html(liHtml + oldHtml);
$("li").attr("style", "");
});
});
(function($) {
$.fn.outerHTML = function() {
return $(this).clone().wrap('<div></div>').parent().html();
}
})(jQuery);
body {
font-size: 14px;
font-family: sans-serif;
}
li, ul {
position: relative;
top: 0;
left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<br /><br /><br />
<ul>
<li id="1">I am list item number 1.</li>
<li id="2">I am list item number 2.</li>
<li id="3">I am list item number 3.</li>
<li id="4">I am list item number 4.</li>
<li id="5">I am list item number 5.</li>
<li id="6">I am list item number 6.</li>
<li id="7">I am list item number 7.</li>
<li id="8">I am list item number 8.</li>
<li id="9">I am list item number 9.</li>
<li id="10">I am list item number 10.</li>
</ul>
But It's only working for re-ordering to top. I would like to know how to add reverse animation? (When the item is clicked - it moves to the bottom of the list). I'm a bit new to css animation, so I will be grateful for the help.
Related
Javascript isn't my forte, so I'm looking for help : How would you write a function which add a Class to 3 elements with interval ?
<ul>
<li class="panel">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
The idea is to add an .--active class on the 1st item when document is ready and remove it after 2sec to add it to the 2nd item and so on.
If you're using jQuery you could loop through the li's using the index, and reset the index to 0 when you reach the last li element :
if( $('li.panel.active').index() == lis_count-1 )
active_li_index = 0;
else
active_li_index++;
Hope this helps.
jQuery solution:
$(function(){
var lis_count = $('li.panel').length;
var active_li_index = 0;
setInterval(function(){
if( $('li.panel.active').index() == lis_count-1 )
active_li_index = 0;
else
active_li_index++;
$('li.panel.active').removeClass('active');
$('li.panel').eq(active_li_index).addClass('active');
}, 1000);
})
.active{
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="panel active">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Pure JS solution:
document.addEventListener('DOMContentLoaded', function(){
var lis = Array.prototype.slice.call( document.querySelectorAll('li.panel'));
var lis_count = lis.length;
var active_li_index = 0;
setInterval(function(){
var active_li = document.querySelector('li.panel.active');
if( lis.indexOf(active_li) == lis_count-1 )
active_li_index = 0;
else
active_li_index++;
active_li.classList.remove('active');
document.querySelectorAll('li.panel')[active_li_index].classList.add('active');
}, 1000);
}, false);
.active{
background-color: yellow;
}
<ul>
<li class="panel active">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Without jQuery:
function showGarland () {
var itemClass = 'panel';
var activeClass = '--active';
var wait = 2000; // 2 seconds
function toggleActive (element, index, maxIndex) {
setTimeout(function(){
element.classList.add(activeClass);
setTimeout(function(){
element.classList.remove(activeClass);
if (index == maxIndex) {
runLoop();
}
}, wait);
}, wait * index);
}
function runLoop () {
var allItems = document.getElementsByClassName(itemClass);
for (var index = 0; index < allItems.length; index++) {
var element = allItems[index];
toggleActive(element, index, allItems.length - 1);
}
}
runLoop();
}
window.addEventListener('load', showGarland);
.--active {
color:red;
}
<ul>
<li class="panel">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
since you use jQuery you can do :
jQuery(() => { // callback when DOM is ready
$('.panel1').addClass('active'); // add your class
setTimeout(() => { // function that execute the callback after 2000ms (2s)
$('.panel1).removeClass('active'); // remove your class active
}, 2000);
});
you should use different class for your differents div
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- <div class="hide">
text
</div> -->
<ul id="Items">
<li class="panel">Item 1</li>
<li class="panel hide">Item 2</li>
<li class="panel hide">Item 3</li>
</ul>
<style>
.hide{
visibility: hidden;
}
</style>
<script>
$(document).ready(function() {
var listItems = $("#Items li");
// alert(listItems);
listItems.each(function(idx, li) {
var product = $(li);
setInterval(function(){
product.css( "visibility", "visible" );
$(li).next().css( "visibility", "hidden" );
$(li).prev().css( "visibility", "hidden" );
}, 2000);
});
});
</script>
The above one works fine for two elements, but for the third element its showing quickly without displayinh the second element.
You can use something like this, you need to call toggleClass with the index you want to start, The functions addClass and removeClass supports multiple elements and multiple classes.
// Add class to element
// support multiple classes
function addClass(elements, className){
// split classes
var classArray = className.split(' ');
var els = [];
// If element does not have length property
if(elements.length == undefined)
els[0] = elements
else
els = elements;
for(e=0; e<els.length; e++){
var element = els[e];
for(i=0; i<classArray.length; i++){
if(element.className.indexOf(classArray[i])==-1){
element.className += ' ' + classArray[i];
}
}
}
}
// Remove class to element
// support multiple classes
function removeClass(elements, className){
var classArray = className.split(' ');
var els = [];
// If elements does not have length property
if(elements.length == undefined)
els[0] = elements
else
els = elements;
for(e=0; e<els.length; e++){
var element = els[e];
for(i= 0; i<classArray.length; i++){
element.className = element.className.replace(classArray[i], '').trim();
}
}
}
function toggleClass(index){
// get active elements and remove active class
removeClass(document.getElementsByClassName('active'), 'active');
// add class to element at index
addClass(document.getElementsByClassName('panel')[index], 'active');
// test if index should increment or reset
if(index<document.getElementsByClassName('panel').length - 1){
index++;
}else{
index = 0;
}
// wait 2sec until execute toggleClass again
setTimeout(toggleClass, 2000, index);
}
toggleClass(0);
.active {
color: green;
}
<ul>
<li class="panel">Item 1</li>
<li class="panel active">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Edit: By the way beware with method classList since you'll need to polyfill for browser compatibility
window.addEventListener("load",function change(i=0){
var els=document.getElementsByClassName("panel");
if(els[i-1]) els[i-1].classList.toggle("active");
els[i].classList.toggle("active");
if(i<els.length-1) setTimeout(change,2000,i+1);
});
You could use a recursive approach to iterate over the class elements slowly and toggle their active class...
Without jQuery:
function showGarland () {
var itemClass = 'panel';
var activeClass = '--active';
var wait = 2000; // 2 seconds
function toggleActive (element, index, maxIndex) {
setTimeout(function(){
element.classList.add(activeClass);
setTimeout(function(){
element.classList.remove(activeClass);
if (index == maxIndex) {
runLoop();
}
}, wait);
}, wait * index);
}
function runLoop () {
var allItems = document.getElementsByClassName(itemClass);
for (var index = 0; index < allItems.length; index++) {
var element = allItems[index];
toggleActive(element, index, allItems.length - 1);
}
}
runLoop();
}
window.addEventListener('load', showGarland);
.--active {
color:red;
}
<ul>
<li class="panel">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Consider the following markup :
<div class="col6">
<h2>Accueil</h2>
<ul class="listing">
<li>Accueil</li>
<li>Homepage Takeover</li>
<li>Homepage Promo Overlay</li>
<li>Homepage Feature Overlay</li>
<li>Homepage Feature Scroll + Takeover</li>
</ul>
<h2>Thèmes & intégrations</h2>
<ul class="listing">
<li>Le 30</li>
<li>Menu à la carte</li>
<li>Intégration thème</li>
<li>Intégration papier virtuel 1</li>
<li>Intégration papier virtuel 2</li>
</ul>
<h2>Galeries</h2>
<ul class="listing">
<li>St-Valentin noir & blanc</li>
<li>Cuisinez avec le fromage</li>
<li>Des fraises pour dessert</li>
<li>Nos meilleures recettes de homard</li>
<li>Jeudi 5#7</li>
</ul>
</div>
I want to traverse the uls with my #leftArrow and #rightArrow. I have a page with an overlay and I change the background image with these arrows. However, I'm not able to pass from the first ul to the second an so on when clicking these arrows.
Here's the Jquery
$(document).ready(function(){
var current_li;
//OPEN OVERLAY
$('.innerWrap a').click(function(){
var src = $(this).attr("title");
current_li = $(this).parent();
var text = $(current_li).text();
$('#frame h2').text(text)
$('#projectOverlay').css({'background-image': 'url(img/' + src + '.jpg)' ,});
$('#frame').fadeIn(400);
$('#projectOverlay').fadeIn(400);
})
//RIGHT
$("#rightArrow").click(function(){
if(current_li.is(":last-child")) {
var next_li = current_li.parents('ul').siblings().find('li').first();
} else {
var next_li = current_li.next();
}
var next_src = next_li.children('a').attr("title");
current_li = next_li;
})
//LEFT
$("#leftArrow").click(function(){
if(current_li.is(":first-child")) {
//var prev_li = $('.innerWrap ul li').last();
var prev_li = current_li.parents('ul').siblings().find('li').last();
} else {
var prev_li = current_li.prev();
}
var prev_src= prev_li.children('a').attr("title");
current_li = prev_li;
})
});
Any help would be appreciated !
Thanks !
https://jsfiddle.net/rgwst1xj/4/
EDIT: solution
$(document).ready(function(){
// I set current_li manually, so change it
var current_li = $('a').first().parent();
// Use your own method to determine which ul is the current one
var current_ul = 0;
//RIGHT
$("#rightArrow").click(function(){
if(current_li.is(":last-child")) {
// you may want to be more specific with $('ul').length
current_ul = (current_ul + 1)%$('ul').length;
var next_li = current_li.parent().parent().find('ul:eq('+current_ul+')').find('li').first();
} else {
var next_li = current_li.next();
}
var next_src = next_li.children('a').attr("title");
current_li = next_li;
console.log(current_li.text())
var text = $(current_li).text();
$('#frame h2').text(text);
})
//LEFT
$("#leftArrow").click(function(){
if(current_li.is(":first-child")) {
//var prev_li = $('.innerWrap ul li').last();
current_ul = (current_ul - 1)%$('ul').length;
var prev_li = current_li.parent().parent().find('ul:eq('+current_ul+')').find('li').last();
} else {
var prev_li = current_li.prev();
}
var prev_src= prev_li.children('a').attr("title");
$('#projectOverlay').animate({opacity: 0}, 200, function() {
$(this)
.css({'background-image': 'url(img/' + prev_src + '.jpg)' ,})
.animate({opacity: 1});
bgSize($('#projectOverlay'), function(width, height){
$("#frame").css("height",height)
$("#projectOverlay").css("height",height);
});
});
current_li = prev_li;
console.log(current_li.text())
var text = $(current_li).text();
$('#frame h2').text(text);
})
});
I have a jQuery mobile list which has a swipe to delete function and stores preferences locally. I am trying to implement a functionality to re-order the list items and store this within the same array, please help!
Here is my fiddle: http://jsfiddle.net/f18nfz/nUSUB/2/
So the function could be something like (http://jsfiddle.net/maziar/P2XDc/):
function moveUp(item) {
var prev = item.prev();
if (prev.length == 0)
return;
prev.css('z-index', 999).css('position','relative').animate({ top: item.height() }, 250);
item.css('z-index', 1000).css('position', 'relative').animate({ top: '-' + prev.height() }, 300, function () {
prev.css('z-index', '').css('top', '').css('position', '');
item.css('z-index', '').css('top', '').css('position', '');
item.insertBefore(prev);
});
}
function moveDown(item) {
var next = item.next();
if (next.length == 0)
return;
next.css('z-index', 999).css('position', 'relative').animate({ top: '-' + item.height() }, 250);
item.css('z-index', 1000).css('position', 'relative').animate({ top: next.height() }, 300, function () {
next.css('z-index', '').css('top', '').css('position', '');
item.css('z-index', '').css('top', '').css('position', '');
item.insertAfter(next);
});
}
$(".FieldContainer").sortable({ items: ".OrderingField", distance: 10 });
$('button').click(function() {
var btn = $(this);
var val = btn.val();
if (val == 'up')
moveUp(btn.parents('.OrderingField'));
else
moveDown(btn.parents('.OrderingField'));
});
Here is a nice example of a sortable drag&drop list with jQuery Mobile: http://jsfiddle.net/sidonaldson/pes2d/
<div data-role="page" id="page1">
<div data-role="content">
<ul data-role="listview" data-divider-theme="b" data-inset="true">
<li data-role="list-divider" role="heading">Re-order</li>
<li data-theme="c">1</li>
<li data-theme="c">2</li>
<li data-theme="c">3</li>
<li data-theme="c">4</li>
<li data-theme="c">5</li>
<li data-theme="c">6</li>
<li data-theme="c">7</li>
</ul>
<a data-role="button">Submit</a>
</div>
</div>
$(document).ready(function(e) {
$('li').removeClass('ui-corner-bottom');
$('ul')
.addClass('ui-corner-top')
.removeClass('ui-corner-all')
.sortable({
'containment': 'parent',
'opacity': 0.6,
update: function(event, ui) {
alert("dropped");
}
});
});
I have an unordered HTML list such as this:
<ul>
<li class="current"></li>
<li></li>
<li></li>
</ul>
Using jquery, I would like to automatically remove the current class from the first li element and add it to the second class. After a short period of time I would like to remove the class from the second li element and add it to the third. I would like for this to repeat as well.
I have this so far but it's not at all what I need:
$("ul li:first-child").addClass('current').delay(1000).queue(function(next){
$(this).removeClass('current');
$(this).next().addClass('current')
next();
});
If you want to be able to stop and start it:
var myInterval;
var myFunc = function() {
var cur = $('ul li.current');
if(cur.index() == $('ul li').length - 1) {
cur.removeClass('current');
$('ul li:first').addClass('current');
} else {
cur.removeClass('current').next().addClass('current');
}
};
//Start Interval
myInterval = setInterval(myFunc, 1000);
Then, to stop/start:
clearInterval(myInterval);
myInterval = setInterval(myFunc, 1000);
jsFiddle
var $li = $('ul li'), i = 0;
setInterval(function(){
i++;
if( $li.length === i ) i = 0;
$li.removeClass('current').eq(i).addClass('current')
}, 1000);
http://jsfiddle.net/mr7J6/
Try this:
var idx = 1;
setInterval(function () {
$('ul li').removeClass('current').eq(idx).addClass('current');
idx++;
if (idx == $('ul li').length) idx = 0;
}, 1000);
jsFiddle example
$(function(){
move();
});
function move(){
$("ul li.current").delay(1000).queue(function(next){
$(this).removeClass('current');
if($(this).next().addClass('current').length){
move();
}
});
}
If you need it to wrap around, you can do it using the modulus operator like this:
$(document).ready(function() {
var targets = $('ul li');
var len = targets.length;
var i = 0;
setInterval(function() {
// remove from current
$('li.highlight').removeClass('highlight');
i = (i + 1) % len;
targets.eq(i).addClass('highlight');
}, 1000);
});
Demo
Add and remove class unorder list current class using the jQuery click event.
**
Working Example
**
$(document).on('ready', function() {
$('.list-1 li').each(function(){
var t = $(this);
t.find('a').click(function(){
$('li.current').removeClass('current');
t.addClass('current');
});
});
});
.list-1 li a{text-decoration:none; color:#444; background:#ddd; padding:5px 15px 10px;}
.list-1 li.current a{background:tomato; color:#fff;}
.list-1{display:flex; flex-wrap:wrap;min-width:140px}
.list-1 li{padding:5px;margin:0 0 15px;display:block;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-inline list-1">
<li class="current">Exapmle 1</li>
<li>Exapmle 2</li>
<li>Exapmle 3</li>
<li>Exapmle 4</li>
<li>Exapmle 5</li>
<li>Exapmle 6</li>
<li>Exapmle 7</li>
<li>Exapmle 8</li>
<li>Exapmle 9</li>
</ul>
I have an array of numbers. 0,136,1084,3521,3961,5631,6510,7901,8204 (which are the current scrollTops of all of the sections on one page.) I'm trying to find a way to take the current window scrollTop and find out which of these values it's currently between so that when the page is being scrolled, the active navigation item switches.
Currently, while scrolling, 'current page' skips 0 and goes straight to 1 in the array, and as a result, is unable to catch the last page.
currentPage = 0;
divOffset = new Array();
function setCurrentPage() {
divOffset = []; //this ends up as 0,136,1084,3521,3961,5631,6510,7901,8204
//get offset and ID of each section and add to array.
$(".section").each(function() {
sectionOffset = $(this).offset();
divOffset.push(Math.round(sectionOffset.top));
});
bodyOffset = $(window).scrollTop();
for(i=0; i < divOffset.length; i++) {
if( divOffset[i] >= bodyOffset ) {
currentPage = i;
$('#mainNav li').removeClass("active");
$("#mainNav li #a-" + currentPage).parent().addClass("active");
return false;
}
}
}
My navigation looks something like this:
<ul id="mainNav">
<li class="active">home</li>
<li class="menuLI"><a>works</a>
<ul>
<li><a href='#a-1' class='navA' id='a-1'>Websites</a></li>
<li><a href='#a-2' class='navA' id='a-2'>Illustrations</a></li>
<li><a href='#a-3' class='navA' id='a-3'>Photomanipulations</a></li>
<li><a href='#a-4' class='navA' id='a-4'>Glam Guitars</a></li>
<li><a href='#a-5' class='navA' id='a-5'>Logos</a></li>
<li><a href='#a-6' class='navA' id='a-6'>Photography</a></li>
</ul>
</li>
<li>about</li>
<li>contact</li>
</ul>
You can look at it here: http://glowtagdesign.com/index2.php#a-0
Assuming the array is sorted, try this:
var i;
for (i = 0; i < arr.length && pos < arr[i]; i++)
{
}
// i is now the number of items in the array less than pos
// pos is less than the first item -> 0
// pos is greater than the last item -> arr.length