find anchor and set active with jquery - javascript

i have 3 content boxes and all have a menu with anchor-links to the content-boxes below!
(the links are included and dynamic)
yesterday i received help with the script.. and its working very good when i have a large content-box.
see here: http://jsfiddle.net/wv9EQ/7/
now i got an problem when i have an small content-box
see here: http://jsfiddle.net/wv9EQ/8/
when i am for example between box 2 and 3 both anchors getting active.
any ideas to fix that? i just want an active anchor only for the box i am currently inside
i use this script:
$(function(){
var sections = {},
_height = $(window).height(),
i = 0;
//// Grab positions of our sections
$('.section').each(function(){
sections[this.name] = $(this).offset().top;
});
$(document).scroll(function(){
var $this = $(this),
pos = $this.scrollTop();
for(i in sections){
if(sections[i] > pos && sections[i] < pos + _height){
$('a').removeClass('active');
$('.nav_' + i).addClass('active');
}
}
});
$('.head-nav-button').click(function()
{
$('a').removeClass('active');
$('.nav_' + $(this).attr('href').replace('#', '')).addClass('active');
});
});

Leave the function after setting a section to active: http://fiddle.jshell.net/doktormolle/nCasy/

Using a offset and break after the first activated menu seems to work:
Trivial parts:
offset = 50; // Should be at least the height of your nav bar
if(sections[i] - pos + offset > 0){
$('a').removeClass('active');
$('.nav_' + i).addClass('active');
break;
}
Full code in fiddle here: http://jsfiddle.net/wv9EQ/10/

Related

how to check if element is fully visible into view port in JQuery

I have gone many Stack Overflow answer for the same question and i am able to get if the element is visible but even if the element is little visible i am getting true.
I have total of 40 elements same class with 1,2 .. appended to it. here is my code
$(window).scroll(function() {
var total = $(".singleElement").length;
for(var i=1;i<=total;i++){
var top_of_element = $(".singleElement."+i).offset().top;
var bottom_of_element = $(".singleElement."+i).offset().top + $(".singleElement."+i).outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
var top_of_screen = $(window).scrollTop();
if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
var myID = $(".singleElement."+i).attr("data-my_id");
console.log(myID);
}
}
});
now when I scroll, so as soon as second element is visible, not entirely, i got the id but at the same time i get the id of first element as well. What i want is if previous element is entirely disappear and next one is on the screen fully then i should get the id.

Responsive collapsible tables one at a time:

First time on stackoverflow, so please don't beat me up too much.
I'm working with an existing code from codepen and trying to figure out how to make the tables expand one at a time.
Currently if we click on more than one "+" icon, they remain open, wondering how we can make it so that previous items expanded will close when clicking on the "+" sign.
I tried adjusting the layout here to no avail:
$('.js-tdToggle').on('click', function(){
if(window.innerWidth < 681){
$(this).toggleClass("fa-plus-square fa-minus-square");
var trParent = $(this).parent().parent();
trParent.toggleClass("collapse");
} else {
$(this).toggleClass("fa-plus-square fa-minus-square");
var tdParent = $(this).parent();
tdParent.next("td").toggleClass("collapse");
}
});
Original Source Codepen
You have to add code where you do the opposite action on every other toggle. JQuery's .not() function is very useful for this. With my changes the JavaScript looks like this:
$('.js-tdToggle').on('click', function() {
var $otherToggles = $(".js-tdToggle.fa-minus-square");
if (window.innerWidth < 681) {
$(this).toggleClass("fa-plus-square fa-minus-square");
$otherToggles.not(this).toggleClass("fa-minus-square fa-plus-square");
var trParent = $(this).parent().parent();
trParent.toggleClass("collapse expand");
var $otherParents = $otherToggles.parent().parent();
$otherParents.removeClass("expand").addClass(" collapse");
} else {
$(this).toggleClass("fa-plus-square fa-minus-square");
$otherToggles.not(this).toggleClass("fa-minus-square fa-plus-square");
var tdParent = $(this).parent();
tdParent.next("td").toggleClass("collapse expand");
var $otherParents = $($otherToggles).not(this).parent();
$otherParents.next("td").toggleClass("expand collapse");
}
});
You can refer to my forked pen to see it in action: codepen.io

Jquery scroll function to determine whether div is within viewport not working

I am trying to build a function which checks whether a set of divs are within the visible viewport. I have the following code:
$(window).scroll(function(){
var $w = $(window);
var bottom_edge_y = $w.scrollTop() + $w.height();
var top_edge_y = $w.scrollTop();
$('#itin_list').children('div').each(function () {
var scrollTop = $(window).scrollTop(),
divOffset = $('#'+ $(this).attr('id')).offset().top,
if(top_edge_y < divOffset< bottom_edge_y){
alert("caught");
}
});
)};
However this code alerts every time, even if the divOffset is not within the range specified in the if condition. What is the issue? Thanks in advance.
There is a problem with your if condition. You cannot compare 3 numbers in a single comparison like this.
Instead of `if(top_edge_y < divOffset< bottom_edge_y),
use this:
if(top_edge_y < divOffset && divOffset<bottom_edge_y)`

JavaScript Jquery function that is triggered on event executes all at once instead of right time

I made a function that Is made to be trigered when user scrolls on a element on the page. In this case when user scrolls to an id then it fades in. The problem is that they fade in all at the same time with the first scroll instead of when they reaching the element That is supposed to allow it to fade in! Please help me make my function work.
Thanks a lot
var selected={
//// Storing selectors
items:[],
/// Function that stores items and hides them from the page
selectFunc: function(select) {
//// Store selected element
selected.items.push(select);
/// hide selector from the page
$(select).hide();
}
};
//// Function triggeres on scroll
$(window).scroll(function() {
/// loops trough the selected elements
for(i=0; i<selected.items.length; i++){
var currentItem = selected.items[i];
///// calculates your position and item position
var hT = $(currentItem).offset().top,
hH = $(currentItem).outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
////// check if you are in the position
if (wS > (hT+hH-wH)){
$( currentItem ).fadeIn( 2500 );
}
}
});
//// Using my function to select id about and p element in it.
selected.selectFunc("#about p");
selected.selectFunc("#about input");
In your for loop, you are doing an iteration for each element in selected.items. What's in there? Two strings: "#about p", and "#about input".
So for each of these selectors, you show them all. You need to get every element separately.
Another problem is that hiding these elements means they are not taking up the space they should on the page, so you might not be able to scroll down. You can solve that by changing their opacity instead of making them display:none (what .hide() is doing).
Here is your code with some modifications:
var selected = {
//// Storing selectors
items: [],
/// Function that stores items and hides them from the page
selectFunc: function(select) {
//// Store selected element
var items = $(select);
for (var i = 0, l = items.length; i < l; i++) selected.items.push(items[i]);
/// hide selector from the page
items.css('opacity', 0);
}
};
//// Function triggeres on scroll
$(window).scroll(function() {
/// loops trough the selected elements
for (i = 0; i < selected.items.length; i++) {
var currentItem = selected.items[i];
///// calculates your position and item position
var hT = $(currentItem).offset().top,
hH = $(currentItem).outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
////// check if you are in the position
if (wS > (hT + hH - wH)) {
$(currentItem).animate({
'opacity': 1
}, 2500);
}
}
});
//// Using my function to select id about and p element in it.
selected.selectFunc("#about p");
selected.selectFunc("#about input");
// Simulating a scroll to show the first elements
$(window).scroll();
JS Fiddle Demo

make div do -200px multiple times?

I am trying to move a div -200px from his original position when I press a button. Now I want to be able to do this multiple times.
function leftAnimate(){
original = document.getElementById("sliderzelf").setAttribute("style", "margin-left: -200px;");
}
This piece of code ( I assume, correct me if Im wrong.) really sets the attribute ONCE to -200px. Is there any way I can make this do -200px from every new starting position?
Since you have used the jquery-animate tag, I shall presume you have jQuery. In which case the following should work:
function leftAnimate() {
$("#sliderzelf").css("margin-left", "-=200");
}
call this function however you like, add a css transition on the element if you want it to slide or whatever. happy coding!
function leftAnimate(){
var el = document.getElementById("section");
var curMargin = window.getComputedStyle(el)['margin-left'].replace('px', '');
var newPos = Number(curMargin - 200);
original = el.setAttribute("style", "margin-left:" + newPos + "px;");
}
if you element is an absolute element, try use the Left instead margin-left, or
You can try with jQuery:
function leftAnimate(){
var actualPosition = $("#sliderzelf").css("left");
original = document.getElementById("sliderzelf").setAttribute("style", "margin-left: " + (actualPosition - 200).toString() + "px;");
}
Using pure javascript:
function leftAnimate(){
//get the button
var btn = document.getElementById("sliderzelf");
//get the current margin
var currentMargin = btn.style.marginLeft.replace("px", "");
//calculate the new margin
var newMargin = currentMargin - 200;
//check if the new margin is valid (optional)
if (newMargin >= 0)
btn.setAttribute("style", "margin-left: " + newMargin + "px;") //set the new margin
}
<button id="sliderzelf" style="margin-left: 600px" onclick="leftAnimate()">
Click me!
</button>
With jquery just change the function to:
$("#sliderzelf").css('margin-left', '-= 200');

Categories