I'm trying to make a carousel-like navigation and subnavigation.
This script works almost as I expected:
https://jsfiddle.net/xpvt214o/23270/
Here is how it should work:
If the navigation overflows, make next arrow visible.
If we scroll right, make the left arrow visible.
Hide both arrows if the navigation does not overflow.
In the first script I have a few problems:
1) Prev and next arrows from both navs work for first nav
2) When I scroll right and really get to the end of the navigation, I need to click the next arrow once more before it hides.
To make appropriate arrows work with their navigations I wrap my main code in a function and replace $('.go-left') to nav.find('.go-left') and same for the right arrow. Here's the code:
https://jsfiddle.net/0z5u4vyt/5/
The arrows are supposed to work but they don't. Please, I need your help!
in your javascript code var prevArrow = nav.find('.go-left'); and var nextArrow = nav.find('.go-right'); don't get value so change your code to
var prevArrow = nav.siblings('.go-left');
var nextArrow = nav.siblings('.go-right');
function navCarousel(el) {
var nav = el;
var navFirstItem = nav.find('li:first-child');
var navLastItem = nav.find('li:last-child');
var prevArrow = nav.siblings('.go-left');
var nextArrow = nav.siblings('.go-right');
function checkNavOverflow() {
if (nav.prop('scrollWidth') > nav.width() &&
(nav.find('ul').width() - navLastItem.offset().left) < 51) {
nextArrow.css('display', 'block');
} else {
nextArrow.css('display', 'none');
}
if (navFirstItem.offset().left < 15) {
prevArrow.css('display', 'block');
} else {
prevArrow.css('display', 'none');
}
}
checkNavOverflow();
$(window).on('resize', function() {
checkNavOverflow();
// console.log(nav.find('ul').width() - navLastItem.offset().left);
});
prevArrow.click(function() {
var pos = nav.scrollLeft() - 200;
nav.animate( { scrollLeft: pos }, 300, checkNavOverflow());
});
nextArrow.click(function() {
var pos = nav.scrollLeft() + 200;
nav.animate( { scrollLeft: pos }, 300, checkNavOverflow());
});
}
navCarousel($('.category-navigation .category-navigation-container'));
navCarousel($('.subcategory-navigation .subcategory-navigation-container'));
body {
background: #20262e;
padding: 0;
margin: 0;
font-family: Helvetica;
}
.category-navigation, .subcategory-navigation {
background-color: #fff;
position: relative;
border-bottom: 1px solid grey;
}
.category-navigation-container, .subcategory-navigation-container {
overflow: hidden;
}
.category-navigation ul, .subcategory-navigation ul {
list-style: none;
display: flex;
white-space: nowrap;
}
.category-navigation ul li, .subcategory-navigation ul li {
padding: 20px;
}
.category-navigation .go-left, .subcategory-navigation .go-left, .category-navigation .go-right, .subcategory-navigation .go-right {
display: none;
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
width: 20px;
height: 20px;
background-color: grey;
z-index: 9;
border-radius: 50%;
padding: 10px;
text-align: center;
}
.category-navigation .go-left, .subcategory-navigation .go-left {
left: 0;
}
.category-navigation .go-right, .subcategory-navigation .go-right {
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="category-navigation">
<div class="go-left">←</div>
<div class="category-navigation-container">
<ul>
<li>Category Item 1</li>
<li>Category Item 2</li>
<li>Category Item 3</li>
<li>Category Item 4</li>
<li>Category Item 5</li>
<li>Category Item 6</li>
<li>Category Item 7</li>
<li>Category Item 8</li>
<li>Category Item 9</li>
</ul>
</div>
<div class="go-right">→</div>
</div>
<div class="subcategory-navigation dropdown">
<div class="go-left">←</div>
<div class="subcategory-navigation-container">
<ul>
<li>
<a href="#">
<div>Subitem 1</div>
</a>
</li>
</ul>
</div>
<div class="go-right">→</div>
</div>
TL;DR: Detect item change from the actual <ul> list and persist the data
Howdy everyone?
I'm currently doing a Trello-like based web-application using PHP as a backend and jQueryUI as a front-end.
The front-end part is made using sortable(), by defining three UL elements. One is a container / wrapper with the id Nav and the other two are actual boards that hold the items.
Case scenarios are simple:
You can reorder boards
You can move order of items inside the single board
You can move item from one board to another
The included code supports all three of them but the data should persist to the back-end powered database (I'm currently on SQLite since the project is in early phase).
Problem
The method setSortAction currently detects all three use case but once you move the item from one board to another the order of the list can't be properly detected (since they are in incremented value).
Getting the bodyContent like this: action=updateMenuItemListings&record=2&record=1&record=3
by moving the second item to the first place in the board is fine, and I can persist that change through the POST request on back-end and then onto the database.
What happens when you move the first item from the second board on the first board? You'd get value of bodyContent similar to this:
action=updateMenuItemListings&record=1&record=2&record=1&record=3
As you can see the record with value 1 duplicates.
That means I can't detect the item moved is from the second board and I have duplicate items in the order of the board.
How would you go about designing this? Can it be done by the given code or have I totally missed the logic that one should apply in this scenario?
Thank you.
$(function() {
var debugMode = true;
$("ul.droptrue").sortable({
connectWith: "ul"
});
//Set common sort settings for all lists
$(".sortable").sortable({
opacity: 0.6,
cursor: 'move'
});
//Function used to configure update calls for each sort
function setSortAction(selector, updatePage, updateAction, itemLabel) {
$(selector).sortable({
update: function() {
var itemList = $(this).sortable(
"serialize", {
attribute: "id",
key: itemLabel
});
//Create POST request to persist the update
var bodyContent = "action=" + updateAction + "&" + itemList;
if (debugMode) {
alert("DEBUG: bodyContent = \n" + bodyContent);
}
//$.post(updatePage, bodyContent, function (postResult)
//{ alert(postResult); });
}
});
}
//Set sort update action for top level and second level
setSortAction(".navLevel1",
"reorder.php",
"updateMenuListings",
"record");
setSortAction(".navLevel2",
"reorder.php",
"updateMenuItemListings",
"record");
});
#import url( 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' );
#sortable_1,
#sortable_2,
#sortable_3 {
list-style-type: none;
margin: 0;
float: left;
margin-right: 10px;
background: #eee;
padding: 5px;
width: 143px;
}
#sortable_1 li,
#sortable_2 li,
#sortable_3 li {
margin: 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
table {
font-size: 1em;
}
.ui-draggable,
.ui-droppable {
background-position: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul id="Nav" class="sortable navLevel1">
<ul id="sortable_1" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Classes</li>
<li id="item_1" class="ui-state-default">Some class</li>
<li id="item_2" class="ui-state-default">Another one!</li>
<li id="item_3" class="ui-state-default">Yep, thats enough</li>
</ul>
<ul id="sortable_2" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Presentation</li>
<li id="item_1" class="ui-state-default">Tom</li>
<li id="item_2" class="ui-state-default">Jessica</li>
<li id="item_3" class="ui-state-default">Kevin</li>
</ul>
</ul>
<br style="clear:both">
Unlike classes HTML ID's should be unique, in this way you can identify which items are from which columns.
Knowing for example that column one has 4 slots and column two has 6 would mean that a request array of 7,3,9,3,2,5,6,1,4,8,10 gets split into 4 and 6 hence
Column one: 7, 3, 9, 10,
Column two: 2, 5, 6, 1, 4, 8
$(function() {
var debugMode = true;
$("ul.droptrue").sortable({
connectWith: "ul"
});
//Set common sort settings for all lists
$(".sortable").sortable({
opacity: 0.6,
cursor: 'move'
});
//Function used to configure update calls for each sort
function setSortAction(selector, updatePage, updateAction, itemLabel) {
$(selector).sortable({
update: function() {
var itemList = $(this).sortable(
"serialize", {
attribute: "id",
key: itemLabel
});
//Create POST request to persist the update
var bodyContent = "action=" + updateAction + "&" + itemList;
if (debugMode) {
$('#report').text("DEBUG: bodyContent = \n" + bodyContent);
}
//$.post(updatePage, bodyContent, function (postResult)
//{ alert(postResult); });
}
});
}
//Set sort update action for top level and second level
setSortAction(".navLevel1",
"reorder.php",
"updateMenuListings",
"record");
setSortAction(".navLevel2",
"reorder.php",
"updateMenuItemListings",
"record");
});
#import url( 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' );
#sortable_1,
#sortable_2,
#sortable_3 {
list-style-type: none;
margin: 0;
float: left;
margin-right: 10px;
background: #eee;
padding: 5px;
width: 143px;
}
#sortable_1 li,
#sortable_2 li,
#sortable_3 li {
margin: 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
table {
font-size: 1em;
}
.ui-draggable,
.ui-droppable {
background-position: top;
}
#report {
position: fixed;
font-size: 0.5em;
bottom: 2em;
left: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<ul id="Nav" class="sortable navLevel1">
<ul id="sortable_1" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Classes</li>
<li id="item_1" class="ui-state-default">Some class</li>
<li id="item_2" class="ui-state-default">Another one!</li>
<li id="item_3" class="ui-state-default">Yep, thats enough</li>
</ul>
<ul id="sortable_2" class="droptrue navLevel2">
<li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Presentation</li>
<li id="item_4" class="ui-state-default">Tom</li>
<li id="item_5" class="ui-state-default">Jessica</li>
<li id="item_6" class="ui-state-default">Kevin</li>
</ul>
</ul>
<div id="report"></div>
<br style="clear:both">
Right now my program can dynamically create rows of squares (2 rows of 12). When you double click on one of the squares, a color picker will pop up and then you can specify the color for that square.
However, I am trying to also implement a "shortcut" so that if you drag an already colored square onto another one, that new square will also be colored.
What I have done so far:
http://codepen.io/blazerix/pen/rrwPAK
var id_num = 1;
var picker = null;
$(function () {
$(document).on('click', ".repeat", function (e) {
e.preventDefault();
var $self = $(this);
var $parent = $self.parent();
if($self.hasClass("add-bottom")){
$parent.after($parent.clone(true).attr("id", "repeatable" + id_num));
id_num = id_num + 1;
//picker = null;
} else {
$parent.before($parent.clone(true).attr("id", "repeatable" + id_num));
id_num = id_num + 1;
//picker = null;
}
});
});
$(".startLEDs").draggable({
revert:true
});
I have tried to use the draggable feature from JQuery but noticed that when I try to drag the boxes, the entire div disappears. And, also I only want the boxes to be draggable and droppable, nothing else.
Any help or feedback is much appreciated!
Here is what I have so far, but due to the id attributes not being unique after cloning, it has some quirks.
Working Example: https://jsfiddle.net/Twisty/aqfn34bs/
HTML
<div class="bottomdiv">
<div class="container">
<div id="repeatable-0">
<button class="repeat add-top">Add above</button>
<ul class="repeatable">
<li class="startLEDs" id="sLED1"></li>
<li class="startLEDs" id="sLED2"></li>
<li class="startLEDs" id="sLED3"></li>
<li class="startLEDs" id="sLED4"></li>
<li class="startLEDs" id="sLED5"></li>
<li class="startLEDs" id="sLED6"></li>
<li class="startLEDs" id="sLED7"></li>
<li class="startLEDs" id="sLED8"></li>
<li class="startLEDs" id="sLED9"></li>
<li class="startLEDs" id="sLED10"></li>
<li class="startLEDs" id="sLED11"></li>
<li class="startLEDs" id="sLED12"></li>
<li class="endLEDs" id="eLED1"></li>
<li class="endLEDs" id="eLED2"></li>
<li class="endLEDs" id="eLED3"></li>
<li class="endLEDs" id="eLED4"></li>
<li class="endLEDs" id="eLED5"></li>
<li class="endLEDs" id="eLED6"></li>
<li class="endLEDs" id="eLED7"></li>
<li class="endLEDs" id="eLED8"></li>
<li class="endLEDs" id="eLED9"></li>
<li class="endLEDs" id="eLED10"></li>
<li class="endLEDs" id="eLED11"></li>
<li class="endLEDs" id="eLED12"></li>
</ul>
<div class="timeMilli">Time(ms):
<input type="text" name="time" form="form1">
</div>
<button class="repeat add-bottom">Add below</button>
</div>
</div>
</div>
I was looking at using sortable, and so I switched it to a unorganized list in my testing and then went back to draggable but still licked the list of colors versus links. I suspect you could revert back if you desired.
CSS
div.bottomdiv {
clear: both;
position: fixed;
bottom: 0;
height: 50%;
width: 100%;
font-size: 16px;
text-align: center;
overflow: auto;
}
.container {
margin-top: 60px;
float: left
}
.timeMilli {
position: relative;
display: inline-block;
}
ul.repeatable {
list-style-type: none;
margin: 0;
padding: 0;
width: 408px;
}
ul.repeatable li {
width: 30px;
height: 30px;
float: left;
margin: 1px 1px 1px 0;
background-color: #ccc;
border: 1px solid #000000;
}
b {
position: relative;
display: inline-block;
width: 30px;
height: 30px;
background-color: #ccc;
border: 1px solid #000000;
}
.repeat {
display: flex;
flex-direction: nowrap;
flex-wrap: nowrap;
}
.repeat > * {
flex: 0 0 30px;
}
Minor changes here for ul and li.
jQuery
$(function() {
function setColor(obj, r) {
obj.css('background-color', r);
obj.attr("data-color", r);
}
function makeDrag(obj) {
obj.draggable({
helper: "clone",
opacity: 0.85
});
}
function makeDrop(obj) {
obj.droppable({
accept: ".repeatable li",
drop: function(e, ui) {
if (ui.helper.data("color")) {
setColor($(this), ui.helper.data("color"));
makeDrag($(this));
}
}
});
}
$(document).on('click', ".repeat", function(e) {
e.preventDefault();
var $self = $(this);
var $parent = $self.parent();
var id_num = $("div[id^='repeatable']").length;
if ($self.hasClass("add-bottom")) {
$parent.after($parent.clone(true).attr("id", "repeatable-" + id_num));
makeDrop($("#repeatable-" + id_num + " .repeatable li"));
makeDrag($("#repeatable-" + id_num + " .repeatable li[data-color^='#']"));
} else {
$parent.before($parent.clone(true).attr("id", "repeatable-" + id_num));
makeDrop($("#repeatable-" + id_num + " .repeatable li"));
makeDrag($("#repeatable-" + id_num + " .repeatable li[data-color^='#']"));
}
});
$(".repeatable li").on("dblclick", function(e) {
$(this).spectrum({
color: "#f00",
change: function(color) {
setColor($(this), color.toHexString());
makeDrag($(this));
}
});
});
makeDrop($(".repeatable li"));
});
I didn't see a need for the id_num and picker variables in global.
Since we will be making a number of things change colors, draggable, and droppable, I created functions to do this repeatedly.
So draggable by itself would not accomplish what you needed. You need droppable to be able to action things when the dragged item is dropped. For example, it has an out and over event that you could color the box it's over while it's over it, and then revert the color once dragged out.
For now, we stick to basics: we set a color with a Double Click event, we can then drag that color to another nearby box, and the color for that box is set to the same color when dropped.
Now if we clone things before or after, things get sticky. Will look over it later, but this should get you moving forward for now.
I have the following menu—please find below the code snippet—and wanted to know if there is a possibility to remove the unwanted jiggling effect on mouse over the links (left side area). By jiggling, I don't mean the translation to the right effect. That is a well defined thing. Just try to move slowly the mouse at the very beginning of the link(s) and u'll see the unwanted effect. Any thoughts?
/* jQuery Storage API Plugin 1.7.4 https://github.com/julien-maurel/jQuery-Storage-API */
!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof exports?require("jquery"):jQuery)}(function(e){function t(t){var r,i,n,o=arguments.length,s=window[t],a=arguments,u=a[1];if(2>o)throw Error("Minimum 2 arguments must be given");if(e.isArray(u)){i={};for(var f in u){r=u[f];try{i[r]=JSON.parse(s.getItem(r))}catch(c){i[r]=s.getItem(r)}}return i}if(2!=o){try{i=JSON.parse(s.getItem(u))}catch(c){throw new ReferenceError(u+" is not defined in this storage")}for(var f=2;o-1>f;f++)if(i=i[a[f]],void 0===i)throw new ReferenceError([].slice.call(a,1,f+1).join(".")+" is not defined in this storage");if(e.isArray(a[f])){n=i,i={};for(var m in a[f])i[a[f][m]]=n[a[f][m]];return i}return i[a[f]]}try{return JSON.parse(s.getItem(u))}catch(c){return s.getItem(u)}}function r(t){var r,i,n=arguments.length,o=window[t],s=arguments,a=s[1],u=s[2],f={};if(2>n||!e.isPlainObject(a)&&3>n)throw Error("Minimum 3 arguments must be given or second parameter must be an object");if(e.isPlainObject(a)){for(var c in a)r=a[c],e.isPlainObject(r)?o.setItem(c,JSON.stringify(r)):o.setItem(c,r);return a}if(3==n)return"object"==typeof u?o.setItem(a,JSON.stringify(u)):o.setItem(a,u),u;try{i=o.getItem(a),null!=i&&(f=JSON.parse(i))}catch(m){}i=f;for(var c=2;n-2>c;c++)r=s[c],i[r]&&e.isPlainObject(i[r])||(i[r]={}),i=i[r];return i[s[c]]=s[c+1],o.setItem(a,JSON.stringify(f)),f}function i(t){var r,i,n=arguments.length,o=window[t],s=arguments,a=s[1];if(2>n)throw Error("Minimum 2 arguments must be given");if(e.isArray(a)){for(var u in a)o.removeItem(a[u]);return!0}if(2==n)return o.removeItem(a),!0;try{r=i=JSON.parse(o.getItem(a))}catch(f){throw new ReferenceError(a+" is not defined in this storage")}for(var u=2;n-1>u;u++)if(i=i[s[u]],void 0===i)throw new ReferenceError([].slice.call(s,1,u).join(".")+" is not defined in this storage");if(e.isArray(s[u]))for(var c in s[u])delete i[s[u][c]];else delete i[s[u]];return o.setItem(a,JSON.stringify(r)),!0}function n(t,r){var n=a(t);for(var o in n)i(t,n[o]);if(r)for(var o in e.namespaceStorages)u(o)}function o(r){var i=arguments.length,n=arguments,s=(window[r],n[1]);if(1==i)return 0==a(r).length;if(e.isArray(s)){for(var u=0;u<s.length;u++)if(!o(r,s[u]))return!1;return!0}try{var f=t.apply(this,arguments);e.isArray(n[i-1])||(f={totest:f});for(var u in f)if(!(e.isPlainObject(f[u])&&e.isEmptyObject(f[u])||e.isArray(f[u])&&!f[u].length)&&f[u])return!1;return!0}catch(c){return!0}}function s(r){var i=arguments.length,n=arguments,o=(window[r],n[1]);if(2>i)throw Error("Minimum 2 arguments must be given");if(e.isArray(o)){for(var a=0;a<o.length;a++)if(!s(r,o[a]))return!1;return!0}try{var u=t.apply(this,arguments);e.isArray(n[i-1])||(u={totest:u});for(var a in u)if(void 0===u[a]||null===u[a])return!1;return!0}catch(f){return!1}}function a(r){var i=arguments.length,n=window[r],o=arguments,s=(o[1],[]),a={};if(a=i>1?t.apply(this,o):n,a._cookie)for(var u in e.cookie())""!=u&&s.push(u.replace(a._prefix,""));else for(var f in a)s.push(f);return s}function u(t){if(!t||"string"!=typeof t)throw Error("First parameter must be a string");g?(window.localStorage.getItem(t)||window.localStorage.setItem(t,"{}"),window.sessionStorage.getItem(t)||window.sessionStorage.setItem(t,"{}")):(window.localCookieStorage.getItem(t)||window.localCookieStorage.setItem(t,"{}"),window.sessionCookieStorage.getItem(t)||window.sessionCookieStorage.setItem(t,"{}"));var r={localStorage:e.extend({},e.localStorage,{_ns:t}),sessionStorage:e.extend({},e.sessionStorage,{_ns:t})};return e.cookie&&(window.cookieStorage.getItem(t)||window.cookieStorage.setItem(t,"{}"),r.cookieStorage=e.extend({},e.cookieStorage,{_ns:t})),e.namespaceStorages[t]=r,r}function f(e){var t="jsapi";try{return window[e]?(window[e].setItem(t,t),window[e].removeItem(t),!0):!1}catch(r){return!1}}var c="ls_",m="ss_",g=f("localStorage"),l={_type:"",_ns:"",_callMethod:function(e,t){var r=[this._type],t=Array.prototype.slice.call(t),i=t[0];return this._ns&&r.push(this._ns),"string"==typeof i&&-1!==i.indexOf(".")&&(t.shift(),[].unshift.apply(t,i.split("."))),[].push.apply(r,t),e.apply(this,r)},get:function(){return this._callMethod(t,arguments)},set:function(){var t=arguments.length,i=arguments,n=i[0];if(1>t||!e.isPlainObject(n)&&2>t)throw Error("Minimum 2 arguments must be given or first parameter must be an object");if(e.isPlainObject(n)&&this._ns){for(var o in n)r(this._type,this._ns,o,n[o]);return n}var s=this._callMethod(r,i);return this._ns?s[n.split(".")[0]]:s},remove:function(){if(arguments.length<1)throw Error("Minimum 1 argument must be given");return this._callMethod(i,arguments)},removeAll:function(e){return this._ns?(r(this._type,this._ns,{}),!0):n(this._type,e)},isEmpty:function(){return this._callMethod(o,arguments)},isSet:function(){if(arguments.length<1)throw Error("Minimum 1 argument must be given");return this._callMethod(s,arguments)},keys:function(){return this._callMethod(a,arguments)}};if(e.cookie){window.name||(window.name=Math.floor(1e8*Math.random()));var h={_cookie:!0,_prefix:"",_expires:null,_path:null,_domain:null,setItem:function(t,r){e.cookie(this._prefix+t,r,{expires:this._expires,path:this._path,domain:this._domain})},getItem:function(t){return e.cookie(this._prefix+t)},removeItem:function(t){return e.removeCookie(this._prefix+t)},clear:function(){for(var t in e.cookie())""!=t&&(!this._prefix&&-1===t.indexOf(c)&&-1===t.indexOf(m)||this._prefix&&0===t.indexOf(this._prefix))&&e.removeCookie(t)},setExpires:function(e){return this._expires=e,this},setPath:function(e){return this._path=e,this},setDomain:function(e){return this._domain=e,this},setConf:function(e){return e.path&&(this._path=e.path),e.domain&&(this._domain=e.domain),e.expires&&(this._expires=e.expires),this},setDefaultConf:function(){this._path=this._domain=this._expires=null}};g||(window.localCookieStorage=e.extend({},h,{_prefix:c,_expires:3650}),window.sessionCookieStorage=e.extend({},h,{_prefix:m+window.name+"_"})),window.cookieStorage=e.extend({},h),e.cookieStorage=e.extend({},l,{_type:"cookieStorage",setExpires:function(e){return window.cookieStorage.setExpires(e),this},setPath:function(e){return window.cookieStorage.setPath(e),this},setDomain:function(e){return window.cookieStorage.setDomain(e),this},setConf:function(e){return window.cookieStorage.setConf(e),this},setDefaultConf:function(){return window.cookieStorage.setDefaultConf(),this}})}e.initNamespaceStorage=function(e){return u(e)},g?(e.localStorage=e.extend({},l,{_type:"localStorage"}),e.sessionStorage=e.extend({},l,{_type:"sessionStorage"})):(e.localStorage=e.extend({},l,{_type:"localCookieStorage"}),e.sessionStorage=e.extend({},l,{_type:"sessionCookieStorage"})),e.namespaceStorages={},e.removeAllStorages=function(t){e.localStorage.removeAll(t),e.sessionStorage.removeAll(t),e.cookieStorage&&e.cookieStorage.removeAll(t),t||(e.namespaceStorages={})}});
var storage;
jQuery(function () {
storage=jQuery.localStorage;
jQuery('nav:visible ul li').click(function (e) {
//Set the aesthetics (similar to :hover)
storage.set('link',jQuery('nav:visible ul li').index(jQuery(this)));
jQuery('nav:visible ul li')
.not(".clicked").removeClass('hovered')
.filter(this).addClass("clicked hovered")
.siblings().toggleClass("clicked hovered", false);
}).hover(function () {
jQuery(this).addClass("hovered")
}, function () {
jQuery(this).not(".clicked").removeClass("hovered")
});
var pageSize = 4,
$links = jQuery(".pagedMenu li"),
count = $links.length,
numPages = Math.ceil(count / pageSize),
curPage = 1;
showPage(curPage);
function showPage(whichPage) {
var previousLinks = (whichPage - 1) * pageSize,
nextLinks = (previousLinks + pageSize);
$links.show();
$links.slice(0, previousLinks).hide();
$links.slice(nextLinks).hide();
showPrevNext();
}
function showPrevNext() {
if ((numPages > 0) && (curPage < numPages)) {
jQuery("#nextPage").removeClass('hidden');
jQuery("#msg").text("(" + curPage + " of " + numPages + ")");
} else {
jQuery("#nextPage").addClass('hidden');
}
if ((numPages > 0) && (curPage > 1)) {
jQuery("#prevPage").removeClass('hidden');
jQuery("#msg").text("(" + curPage + " of " + numPages + ")");
} else {
jQuery("#prevPage").addClass('hidden');
}
}
jQuery("#nextPage").on("click", function () {
showPage(++curPage);
storage.set('page',curPage);
});
jQuery("#prevPage").on("click", function () {
showPage(--curPage);
storage.set('page',curPage);
});
if(storage.isSet('page')){
var page= storage.get('page');
curPage = page;
showPage(page);
}
if(storage.isSet('link')){
var link = storage.get('link')+1;
jQuery('nav:visible ul li:nth-child('+link+')').addClass("clicked hovered");
var newUrl = jQuery('nav:visible ul li:nth-child('+link+') a').attr('href');
if(newUrl!=location.href)location.href=newUrl;
}
});
.hidden {
display: none;
}
body {
font: normal 1.0em Arial, sans-serif;
}
nav.pagedMenu {
color: red;
font-size: 2.0em;
line-height: 1.0em;
width: 8em;
position: fixed;
top: 50px;
}
nav.pagedMenu ul {
list-style: none;
margin: 0;
padding: 0;
}
nav.pagedMenu ul li {
height: 1.0em;
padding: 0.15em;
position: relative;
border-top-right-radius: 0em;
border-bottom-right-radius: 0em;
-webkit-transition:
-webkit-transform 220ms, background-color 200ms, color 500ms;
transition: transform 220ms, background-color 200ms, color 500ms;
}
nav.pagedMenu ul li.hovered {
-webkit-transform: translateX(1.5em);
transform: translateX(1.5em);
}
nav ul li:hover a {
transition: color, 1200ms;
color: red;
}
nav.pagedMenu ul li span {
display:block;
font-family: Arial;
position: absolute;
font-size:1em;
line-height: 1.25em;
height:1.0em;
top:0; bottom:0;
margin:auto;
right: 0.01em;
color: #F8F6FF;
}
a {
color: gold;
transition: color, 1200ms;
text-decoration: none;
}
#pagination, #prevPage, #nextPage {
font-size: 1.0em;
color: gold;
line-height: 1.0em;
padding-top: 250px;
padding-left: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<nav class="pagedMenu">
<ul style="font-size: 28px;">
<li class="" style="margin-bottom: 5px;">Link 1</li>
<li class="" style="margin-bottom: 5px;">Link 2</li>
<li class="" style="margin-bottom: 5px;">Link 3</li>
<li class="" style="margin-bottom: 5px;">Link 4</li>
<li class="" style="margin-bottom: 5px;">Link 5</li>
<li class="" style="margin-bottom: 5px;">Link 6</li>
<li class="" style="margin-bottom: 5px;">Link 7</li>
<li class="" style="margin-bottom: 5px;">Link 8</li>
<li class="" style="margin-bottom: 5px;">Link 9</li>
<li class="" style="margin-bottom: 5px;">Link 10</li>
<li class="" style="margin-bottom: 5px;">Link 11</li>
<li class="" style="margin-bottom: 5px;">Link 12</li>
</ul>
</nav>
<div id="pagination">
Previous
Next
<span id="msg"></span>
</div>
Jsfiddle here
I think you don't need jQuery at all
Replace:
nav.pagedMenu ul li.hovered {
-webkit-transform: translateX(1.5em);
transform: translateX(1.5em);
}
nav ul li:hover a {
transition: color, 1200ms;
color: red;
}
With:
nav.pagedMenu ul li:hover a {
transition: padding-left 500ms,color 1200ms;
padding-left:1.5em;
color: red;
}
http://jsfiddle.net/dh7920rq/
The problem with your implementation is that: when your <li> is hovered, it moves to the right, but your mouse is still at the original position, causing mouseout immediately which causes the unwanted effect.
If we don't move the <li>, but instead increase the padding-left of the <a>, the mouse is still inside the <li> (or increase margin-left of the <a>)
http://jsfiddle.net/dh7920rq/1/
Updated:
Use jQuery to keep the state as requested by the OP:
Replace:
nav.pagedMenu ul li.hovered {
-webkit-transform: translateX(1.5em);
transform: translateX(1.5em);
}
nav ul li:hover a {
transition: color, 1200ms;
color: red;
}
With:
nav.pagedMenu ul li.hovered a{
transition: margin-left 500ms,transition: color 1200ms;
margin-left:1.5em;
color: red;
}
The idea is the same: http://plnkr.co/edit/880ZtUiCwbRNGBNGuURU?p=preview
You can do this effect by giving padding to the a element.
Jsfiddle