JQuery animate won't work - javascript

I'm trying to get list items to scroll up and down when I click on a link. I just can't get it to work.
UPDATE: Added a JSFiddle
jQuery:
$(document).ready(function() {
//console.log($('.nav-up'));
$('.nav-controls').on('click', '.nav-up', function(e) {
e.preventDefault();
//alert('clicked');
var navHeight = $(e.currentTarget).closest('.horz-scroll').find('.block-nav').height();
var el = $(e.currentTarget).closest('.horz-scroll').find('.block-nav > ul');
if((el.height() - navHeight) < el.position().top) {
el.animate({ top: '+=19' }, 'fast');
console.log(el.css('top'));
}
});});
HTML:
<div class="horz-scroll">
<div class="block-nav-wrapper">
<div class="block-nav">
<ul>
<li>
<div class="wrap-box-name"> <span><img src="../../../upload/1/img/arrow.png" /></span> Orinda Union School District</div>
</li>
<li>
<div class="wrap-box-name"> <span><img src="../../../upload/1/img/arrow.png" /></span> Orinda Union School District</div>
</li>
<li>
<div class="wrap-box-name"> <span><img src="../../../upload/1/img/arrow.png" /></span> Orinda Union School District</div>
</li>
<li>
<div class="wrap-box-name"> <span><img src="../../../upload/1/img/arrow.png" /></span> Orinda Union School District</div>
</li>
<li>
<div class="wrap-box-name"> <span><img src="../../../upload/1/img/arrow.png" /></span> Orinda Union School District</div>
</li>
</ul>
</div>
</div>
<div class="nav-controls">
<ul>
<li><a class="nav-up" href="#"><img src="../../../upload/1/img/prev.jpg" /></a></li>
<li><input class="nav_down" name="submit" src="../../../upload/1/img/next.jpg" type="image" /></li>
</ul>
</div>
</div>
CSS:
.nav-controls {
right: 10px;
top: 25px;
margin-left: 37%;
}
.nav-controls ul {
list-style: none;
margin: 0;
padding: 0;
}
.nav-controls ul li{
display: inline;
padding-right: 16px;
}
.block-nav-wrapper {
position: relative;
margin-bottom: 10px;
padding: 10px;
}
.block-nav {
position: relative;
height: 130px;
margin: 10px;
overflow: hidden;
}
.block-nav ul{
}
.block-nav ul li{
list-style:none;
line-height:35px;
}
console.log(el.height()); = 175
console.log(navHeight); = 130
console.log(el.position().top); = 0

A couple things before you get the answer.
You have to include jQuery in your fiddle if you're using it.
like Chris Rockwell said, use a placeholder site (I swapped everything to use http://placehold.it/)
Now, here's the fiddle: http://jsfiddle.net/QmxWc/1/. Main thing that was missing was position:relative on the <ul> you were trying to move. But you also had some logic problems with your javascript.
CSS:
.block-nav ul {
position: relative;
}
JS:
$('.nav-controls').on('click', '.nav-up', function (e) {
e.preventDefault();
//alert('clicked');
var navHeight = $(e.currentTarget).closest('.horz-scroll').find('.block-nav').height();
var el = $(e.currentTarget).closest('.horz-scroll').find('.block-nav > ul');
if ((el.height() - navHeight) > Math.abs(el.position().top)) {
el.animate({
top: '-=19'
}, 'fast');
console.log(el.css('top'));
}
});

Related

Jquery if element has same class?

Im having a page with lot of lightbox (more than one hundred)
Each time I have to add in lightbox-content and trigger-lightbox a class
like 1 2 3 4
and in the jquery i need to duplicate it to trigger the good lightbox. like
$('a#trigger-lightbox.1').click(function() {
$('.lightbox-background').fadeIn('slow');
$('#lightbox-content.1').fadeIn('slow');
});
$('a#trigger-lightbox.2').click(function() {
$('.lightbox-background').fadeIn('slow');
$('#lightbox-content.2').fadeIn('slow');
});
$('a#trigger-lightbox.3').click(function() {
$('.lightbox-background').fadeIn('slow');
$('#lightbox-content.3').fadeIn('slow');
});
$('a#trigger-lightbox.4').click(function() {
$('.lightbox-background').fadeIn('slow');
$('#lightbox-content.4').fadeIn('slow');
});
I'd like instead to have a javascript to add the class 1 2 3 etc, automatically + the jquery to trigger the lightbox-content if it has the same class
or at leat to have something like 'if trigger-lightbox- has same class of lightbox-content.
this way the code will be much shorter.
How is this possible to achieve ?
So far I tried the following:
var same = $(this).attr("class");
$('a#trigger-lightbox'+'.'+same).click(function() {
$('.lightbox-background').fadeIn('slow');
$('#lightbox-content'+'.'+same).fadeIn('slow');
});
But no success . . .
I have this codepen if that help ?
https://codepen.io/anon/pen/VQQzdJ
Really appreciate all your help !!
Working Codepen.
First of all the id should be unique in the same document, so please replace the duplicate ones by common classes, then you could use data-* attributes as the following example shows :
$('a.trigger-lightbox').click(function() {
var index = $(this).data('index');
$('.lightbox-background').fadeIn('slow');
$('.lightbox-content.'+index).fadeIn('slow');
});
$('.lightbox-background').click(function() {
$(this).fadeOut('slow');
$('.lightbox-content').fadeOut('slow');
});
$('a.trigger-lightbox').click(function() {
var index = $(this).data('index');
$('.lightbox-background').fadeIn('slow');
$('.lightbox-content.' + index).fadeIn('slow');
});
$('.lightbox-background').click(function() {
$(this).fadeOut('slow');
$('.lightbox-content').fadeOut('slow');
});
.lightbox-content {
background: white;
padding: 50px;
margin: 0 auto;
z-index: 999999;
display: none;
position: fixed;
left: 50%;
margin-left: -50px;
}
ul li {
list-style: none
}
.lightbox-background {
display: none;
background: rgba(0, 0, 0, 0.8);
width: 100%;
position: fixed;
height: 100%;
z-index: 1;
top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="lightbox-content 1">TEST 1</div>
<div class="lightbox-content 2">TEST 2</div>
<div class="lightbox-content 3">TEST 3</div>
<div class="lightbox-content 4">TEST 4</div>
<ul class="accordion-content">
<li>
<a class="trigger-lightbox" href="#" data-index='1'><p>TRIGGER 1</p></a>
</li>
<li>
<a class="trigger-lightbox" href="#" data-index='2'><p>TRIGGER 2</p></a>
</li>
<li>
<a class="trigger-lightbox" href="#" data-index='3'><p>TRIGGER 3</p></a>
</li>
<li>
<a class="trigger-lightbox" href="#" data-index='4'><p>TRIGGER 4</p></a>
</li>
</ul>
<div class="lightbox-background"></div>
Firstly you're repeating the same id attribute across multiple elements which is invalid HTML. id must be unique. Use common classes to group elements instead.
To solve this issue, and make your code more DRY, you can use a data attribute on the trigger element which relates it to the target. This way you can have an infinite amount of HTML content without ever needing to amend the JS. Something like this:
$('.trigger').click(function() {
$('.lightbox-background').add($(this).data('target')).fadeIn('slow');
});
$('.lightbox-background').click(function() {
$(this).fadeOut('slow');
$('.lightbox').fadeOut('slow');
});
.lightbox {
background: white;
padding: 50px;
margin: 0 auto;
z-index: 999999;
display: none;
position: fixed;
}
ul li {
list-style: none
}
.lightbox-background {
display: none;
background: rgba(0, 0, 0, 0.8);
width: 100%;
position: fixed;
height: 100%;
z-index: 1;
top: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="lightbox" id="lightbox1">TEST 1</div>
<div class="lightbox" id="lightbox2">TEST 2</div>
<div class="lightbox" id="lightbox3">TEST 3</div>
<div class="lightbox" id="lightbox4">TEST 4</div>
<ul class="accordion-content">
<li>
<a href="#" class="trigger" data-target="#lightbox1">
<p>TRIGGER 1</p>
</a>
</li>
<li>
<a href="#" class="trigger" data-target="#lightbox2">
<p>TRIGGER 2</p>
</a>
</li>
<li>
<a href="#" class="trigger" data-target="#lightbox3">
<p>TRIGGER 3</p>
</a>
</li>
<li>
<a href="#" class="trigger" data-target="#lightbox4">
<p>TRIGGER 4</p>
</a>
</li>
</ul>
<div class="lightbox-background"></div>
Note that I amended the positioning of the lightbox in your CSS as it didn't work well in the snippet.
You can use data attributes. Each box and its corresponding trigger have the same identifier. Simply grab the id of the trigger when you click on it, and use it to fade in the right box.
$('.trigger-lightbox').on('click', function() {
const id = $(this).data('id');
$(`.box[data-id="${id}"]`).fadeIn('slow');
});
.box {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="trigger-lightbox" data-id="1">Trigger one</a>
<a class="trigger-lightbox" data-id="2">Trigger one</a>
<div class="box" data-id="1">Box one</div>
<div class="box" data-id="2">Box two</div>

How to create a sub folder on Page?

I dont know how to approach this. I would like to be able to do the following: I have a icon for a folder that links to another page. When the user clicks on the icon, instead of going to the page, a subfolder(s) appears below the folder icon and when the user clicks on one of these folders, then it directs the user to the page.
Below is what I did orignally:
<h4>
<a href="CalMediConnect_DMgmt.cfm">
<img src="images/folder-documents-icon32.jpg" alt="Custodial" class="float-left">
Disease Management
</a>
</h4>
<br /><br />
UPDATE
I have tried the following and it appears to not be working:
The following is the script:
var tree = document.querySelectorAll('ul.tree a:not(:last-child)');
for(var i = 0; i < tree.length; i++) {
tree[i].addEventListener('click', function(e) {
var parent = e.target.parentElement;
var classList = parent.classList;
if(classList.contains("open")) {
classList.remove('open');
var opensubs = parent.querySelectorAll(':scope .open');
for(var i = 0; i < opensubs.length; i++) {
opensubs[i].classList.remove('open');
}
} else {
classList.add('open');
}
});
}
The following is the CSS:
ul.tree li {
list-style-type: none;
position: relative;
}
ul.tree li ul {
display: none;
}
ul.tree li.open > ul {
display: block;
}
ul.tree li a {
color: #4284B0;
text-decoration: none;
}
ul.tree li a:before {
height: 1em;
padding: .1em;
font-size: .8em;
display: block;
position: absolute;
left: -1.3em;
top: .2em;
}
.margin-left {
margin-left: -15px;
}
And the HTML:
<ul class="tree margin-left">
<li>
<h4>
<a href="#">
<img src="images/folder-documents-icon32.jpg" alt="Custodial" class="float-left">
Disease Management
</a>
</h4>
<ul>
<li>
<h5>
<a href="CalMediConnect_DMgmt.cfm">
<img src="images/folder-documents-icon32.jpg" alt="Custodial" class="float-left">
Disease Management
</a>
</h5>
</li>
</ul>
</li>
</ul>
Any help would be appreciated.
Here is a very basic example built with jQuery...
https://jsfiddle.net/kennethcss/8b4e6o42/
$('.folder').on('click', function(e) {
var folder = $(this).find('.sub-folder');
if (e.target !== this) return;
if(folder.hasClass('hidden')) {
folder.removeClass('hidden');
} else {
folder.addClass('hidden');
}
});
.folder {
cursor: pointer;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<ul class="container">
<li class="folder">Primary
<ul class="sub-folder hidden">
<li>Secondary</li>
<li>Secondary</li>
<li>Secondary</li>
</ul>
</li>
<li class="folder">Primary
<ul class="sub-folder hidden">
<li>Secondary</li>
<li>Secondary</li>
<li>Secondary</li>
</ul>
</li>
<li class="folder">Primary
<ul class="sub-folder hidden">
<li>Secondary</li>
<li>Secondary</li>
<li>Secondary</li>
</ul>
</li>
</ul>
Of course, you can style however you'd like; this example merely demonstrates how you might structure your HTML, CSS and JS to create a simple, folder like structure.
Gist
https://gist.github.com/kennethcss/8db1dc3326917c77846e84d263beb67d

optimizing jquery code for animating actions

I'm taking my first steps in jquery, and I've written my first piece of code for animating picture galleries. The thing is:
I have some cover pics and the related content divs, which are hidden (height: 0;).
Each time one cover pic is clicked, the related div opens (changing the height value).
If it the related div is already opened, it closes. If another related div is opened, it closes and opens the correct div.
If the "close" button is clicked, it closes the current open div.
The code is working perfectly, but I couldn't find a syntax that can be placed just once. The way it is now, I have to repeat the script for each new "cover pic / content div" (g1/lg1 g2/lg2 g3/lg3 - in the example), specifying the selector.
How can I make it work specifying just one pair of selectors for all cover pics and related content div?
Here it goes the code: (http://jsfiddle.net/samuelleal/9PL3S/3/)
$(function () {
$('.close').click(function () {
if ($(this).parent().height() > 0) {
$(this).parent().removeClass('open').animate({
height: "0px"
}, 500);
} else {}
});
$('.lg1').click(function () {
if ($('.g1').height() > 0) {
$('.g1').removeClass('open').animate({
height: "0px"
}, 500);
} else {
$('.gallery:not(.g1)').removeClass('open').animate({
height: "0px"
}, 500, function () {
$('.g1').addClass('open').animate({
height: "80px"
}, 500);
});
}
});
$('.lg2').click(function () {
if ($('.g2').height() > 0) {
$('.g2').removeClass('open').animate({
height: "0px"
}, 500);
} else {
$('.gallery:not(.g2)').removeClass('open').animate({
height: "0px"
}, 500, function () {
$('.g2').addClass('open').animate({
height: "80px"
}, 500);
});
}
});
$('.lg3').click(function () {
if ($('.g3').height() > 0) {
$('.g3').removeClass('open').animate({
height: "0px"
}, 500);
} else {
$('.gallery:not(.g3)').removeClass('open').animate({
height: "0px"
}, 500, function () {
$('.g3').addClass('open').animate({
height: "80px"
}, 500);
});
}
});
});
HTML
<body id="body">
<div id="strip" class="f4">
<ul>
<li>
<div class="lg1 pics orange" />
</li>
<li>
<div class="lg2 pics red" />
</li>
<li>
<div class="lg3 pics green" />
</li>
</ul>
<div class="gallery g1">
<div class="close blue">close</div>
<ul>
<li>
<div class="pics orange"></div>
</li>
<li>
<div class="pics orange"></div>
</li>
<li>
<div class="pics orange"></div>
</li>
<li>
<div class="pics orange"></div>
</li>
<li>
<div class="pics orange"></div>
</li>
</ul>
</div>
<div class="gallery g2">
<div class="close blue">close</div>
<ul>
<li>
<div class="pics red"></div>
</li>
<li>
<div class="pics red"></div>
</li>
<li>
<div class="pics red"></div>
</li>
<li>
<div class="pics red"></div>
</li>
<li>
<div class="pics red"></div>
</li>
</ul>
</div>
<div class="gallery g3">
<div class="close blue">close</div>
<ul>
<li>
<div class="pics green"></div>
</li>
<li>
<div class="pics green"></div>
</li>
<li>
<div class="pics green"></div>
</li>
<li>
<div class="pics green"></div>
</li>
<li>
<div class="pics green"></div>
</li>
</ul>
</div>
</div>
CSS
.pics, li {
width: 50px;
height: 50px;
display: inline-block;
margin: 0 10px;
cursor: pointer;
}
.green {
background-color: darkgreen;
}
.blue {
background-color: darkblue;
}
.red {
background-color: darkred;
}
.orange {
background-color: darkorange;
}
.close {
float: left;
height: 20px;
position: relative;
width: auto;
padding: 0 5px;
color: white;
cursor: pointer;
}
#strip > ul {
width: 100%;
height: 80px;
display: block;
}
.gallery {
height: 0;
width: 100%;
overflow: hidden;
background-color: gray;
}
ul li {
list-style: none;
}
I agree with techfoobar, that you shouldn't have multiple identical IDs on different elements, so I modified that for my answer (you could technically do it with classes, I suppose...). After changing the IDs to the classes and the classes to the IDs for the Gallery class elements (and modifying the corresponding CSS), you can give each colored square a 'gallery' attribute (to point to which gallery it opens) and attach a click event handler to all of your colored squares which looks to that gallery attribute to find which one to display:
$(document).on('click','#strip ul li div',function(){
var gallery = $(this).attr('gallery');
if ($('#'+gallery).height() > 0) {
$('#'+gallery).removeClass('open').animate({
height: "0px"
}, 500);
} else {
$('.gallery:not(#'+gallery+')').removeClass('open').animate({
height: "0px"
}, 500, function () {
$('#'+gallery).addClass('open').animate({
height: "80px"
}, 500);
});
}
});
Check it out here: http://jsfiddle.net/Qv9KR/1/

Another jQuery Quicksand jumpy transition

When I hit filter the li get a left overlapping position before to get in transition to filter. I tested the previous questions and answers but isn't solved the problem. The ul doesn't use an absolute position, the li class have left float.
here is the html
<div class="filters">
<ul id="filters" class="clearfix">
<li><a title="all" href="#" class="active"> all </a></li>
<li><a title="web" href="#"> web </a></li>
<li><a title="app" href="#"> app </a></li>
<li><a title="logo" href="#"> logo </a></li>
<li><a title="card" href="#"> card </a></li>
<li><a title="icon" href="#"> icon </a></li>
</ul>
</div>
<div id="portfolio">
<ul id="portfolio_list">
<li class="portfolio" data-id="id-1" data-type="logo">
<div class="portfolio-wrapper">
<img src="images/portfolios/logo/5.jpg" alt="" />
<div class="label">
<div class="label-text">
<a class="text-title">Bird Document</a>
<span class="text-category">Logo</span>
</div>
<div class="label-bg"></div>
</div>
</div>
</li>
<li class="portfolio" data-id="id-2" data-type="app">
<div class="portfolio-wrapper">
<img src="images/portfolios/app/1.jpg" alt="" />
<div class="label">
<div class="label-text">
<a class="text-title">Visual Infography</a>
<span class="text-category">APP</span>
</div>
<div class="label-bg"></div>
</div>
</div>
</li>
</ul></div>
And this is the jQuery call
$(document).ready(function () {
var $filter = $('#filters a');
var $portfolio = $('#portfolio_list');
var $data = $portfolio.clone();
$filter.click(function(e) {
if ($($(this)).attr("title") == 'all') {
var $filteredData = $data.find('li');
} else {
var $filteredData = $data.find('li[data-type=' + $($(this)).attr("title") + ']');
}
$portfolio.quicksand($filteredData, {
adjustHeight: 'dynamic',
duration: 800,
easing: 'easeInOutQuad'
});
$('#filters a').removeClass('active');
$(this).addClass('active');
});
});
forgot to post the css
#portfolio_list li { overflow:hidden; float: left; }
#portfolio_list .portfolio { width:19%; margin:2% 1% 0% 1%; border: 1px solid #c8c8a9; background: #fff; padding: 20px; }
#portfolio_list .portfolio-wrapper { overflow:hidden; position: relative !important; cursor:pointer; }
#portfolio_list .portfolio img { max-width:100%; position: relative; }
#portfolio_list .portfolio .label { position: absolute; width: 100%; height:50px; bottom:-50px; }
#portfolio_list .portfolio .label-bg { background: #fff; width: 100%; height:100%; position: absolute; top:0; left:0; }
#portfolio_list .portfolio .label-text { color:#000; position: relative; z-index:500; padding:12px 8px 0; }
#portfolio_list .portfolio .text-category { display:block; }
Any help is appreciated. Thanks.
The problem was cause by same ID used to style the ul and li and in same time to call it with jQuery. Is needed to use an ID without css styles to not create glitches in quicksand.

Positioning absolute element by offset

I have a drop down menu on a page and want the menu to drop down from the main item to the left. It presently drops down to the right.
I have a jsfiddle for it here.
As you can see it presently drops down to the right and resizes the page to fit. I want the menu to drop to the left and keep all the dimensions in tact. Is there an easy way. I know the jQuery menu widget can do it, but I had other issues with that.
The button is somewhere in the middle of the page, so ideally I want the drop down to be to drop down relative to the parent, not just as the jsfiddle shows which is fixed against the right hand side. Hope this clarifies.
CODE:
IN DOC READY
$(document).ready(function () {
// Menus
$('ul.menu').hide();
$('ul#viewMenu li').hover(function () {
$(this).children('ul.menu').animate({ opacity: 'show' }, 'slow');
}, function () {
$(this).children('ul.menu').animate({ opacity: 'hide' }, 'fast');
});
});
CSS
ul#viewMenu { overflow: hidden; }
ul#viewMenu li { float:left; display: block; text-align: left; line-height: 40px; }
ul#viewMenu li a { line-height: 40px; }
ul#viewMenu ul.menu { position: absolute; }
ul#viewMenu ul.menu li { float: none; }
HTML
<div style="display: inline-block; float: right;">
<ul id="viewMenu" style="list-style: none; margin: 0; padding: 0;">
<li style="display: block; float: left;"> <a class="nav-button view-type-button" style="text-align: center;" href="#"
title="Change the things.">
<span>
<img src="~/Content/themes/base/images/empty.png" style="height: 48px; width: 49px;" alt="Things" />
</span>
</a>
<ul class="view-menu-item view-menu-bottom-right menu"
style="width: 170px !important">
<li> <a class="nav-button" href="#" title="View data.">
<span class="thing1-calendar-button"></span>
<span>This 1</span>
</a>
</li>
<li> <a class="nav-button" href="#" title="View data.">
<span class="thing2-calendar-button"></span>
<span>This 2</span>
</a>
</li>
<li> <a class="nav-button" href="#" title="View data.">
<span class="thing3-calendar-button"></span>
<span>This 3</span>
</a>
</li>
</ul>
</li>
</ul>
Turns out all I needed to do was get hold of the current drawn position from the jQuery offset value. Then set the CSS position for the absolute element. Simples... when you know how!
var position = $('ul#viewMenu ul.menu').offset();
$('ul#viewMenu ul.menu').css({ top: (position.top) + 'px', left: (position.left - 160) + 'px' });
$('ul.menu').hide();
$('ul#viewMenu li').hover(function () {
$(this).children('ul.menu').animate({ opacity: 'show' }, 'slow');
}, function () {
$(this).children('ul.menu').animate({ opacity: 'hide' }, 'fast');
});
Simple. Just give this:
ul#viewMenu ul.menu {
position: absolute;
right: 0;
}
Fiddle: http://jsfiddle.net/praveenscience/T8hFW/1/

Categories

Resources