display div when "element" reaches top of page - javascript

I am new to jQuery, I built this page and what I would like to happen is when a block e.g. 2011 1 October reaches the top of the page it displays the content for that specific div via the id or date-attr.
When you click on a date it will display the content for that date but I would like it to appear once that date block reaches the top of the page.
I have looked around the net but no luck thus far.

Use scroll event to make checks for divs you are interested in - assing class for them for instance.
http://api.jquery.com/scroll/
In that event callback you can check each elements position
http://api.jquery.com/each/
To determine position element on page use
http://api.jquery.com/offset/ - top component
But don't take this value - you need to substract Window scroll position which is returned by
$(window).scrollTop()
And make some border values when element should be opened and when closed.

As per your description that I understood, you will have to add one line of code to your "main.js" file.
// javascript + jquery scripts
// script for fading in content boxes -->
$(".square").on("click", function() {
var id= $(this).attr("contentId");
//$("#details");
$('#details').fadeOut('slow', function() {
$(this).html($("#" + id).html()).fadeIn('fast');
});
});
// active link -->
$(".square").click(function() {
$(".square").removeClass("active");
$(this).addClass("active");
$("html, body").scrollTop($(this).position().top); // THIS IS THE LINE TO BE ADDED TO SCROLL TO THE CURRENT DATE ITEM
});
// fade in main content div / intro
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 10) {
$('.topBlock').fadeOut();
} else {
$('.topBlock').fadeIn();
}
});
// hide intro text onClick on list
$( "li" ).click(function() {
$( ".topBlock" ).hide().animate();
});
var viewportHeight = $(window).height();
//$j(".parallax_section_holder").css("height",$j(window).height()-116);
//alert(viewportHeight);
I hope I have solved your issue, and if not, then please provide me the exact code link in jsfiddle.
Regards.

Related

Trouble with Javascript in Wordpress

I'm trying to create an element in a Wordpress site where a piece of content begins partway down the screen, and sticks to the top of the screen when the user scrolls down.
I've tried various things, and none of them have worked. The most recent attempt uses Javascript to give and take away a class to the content I'm trying to move/fix.
The code is
jQuery( document ).ready(function($) {
alert( "test1!" );
var wrap = $("#wrap");
wrap.on("scroll", function(e) {
if (this.scrollTop > 147) {
wrap.addClass("fix-search");
alert("test2");
} else {
wrap.removeClass("fix-search");
}
});
});
The file is enqueuing properly since the first test alert ("test1" fires, but "test2" doesn't fire as I scroll down the screen. I've had that same piece of code working in a modified version of the original code on codepen (http://codepen.io/anon/pen/NqKKVN) so I can only assume this is something weird with Wordpress interacting with Javascript.
So yeah, anyone know a way to either do that I'm wanting to do in a way that will work with wordpress, or to get the above piece of code working properly?
EDIT: This has been solved. For the reference of anyone else with the same problem the piece of code that eventually worked was
jQuery( document ).ready(function($) {
var scrollTop = $(window).scrollTop();
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
var wrap = $("#menu-all-pages");
if (scrollTop > 147) {
wrap.addClass("fix-search");
console.log("Menu at top");
} else {
wrap.removeClass("fix-search");
console.log("Menu at set point");
}
console.log(scrollTop);
}
window.onscroll = scrollUpdate;
});
I have implemented a similar solution in my blog a few years ago. I got it working by scripting this way:
Add a variable scrollTop which would contain the value in pixels
scrolled from the window top.
var scrollTop = $(window).scrollTop();
See, I use jquery function scrollTop applied to the selected object "window". It would return the value scrolled from the very top of the browser. It does work on Wordpress, I have tried it on my blog.
Put this code in a function scrollUpdate. We'll call it later to update
the scroll value from top
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
}
The function should also contain all the logic checking the scrollTop value and thus applying styles and etc.
Let's make this function be called on every scroll.
window.onscroll = scrollUpdate;
Try it yourself!
P.S. I got a weird feeling, but you should better use hide / show instead of adding a whole css class to the page.

jQuery scroll to next element via up/down buttons - how to add handling for manual scrolling that would otherwise confuse this?

I am trying to implement two static buttons for navigating up or down between about 10 containing div tags on a single fairly deep page of content.
I want the buttons to smoothly scroll to the next part of the page (next containing div) whenever they are clicked on.
The problem with this solution is that if you manually scroll up and down the page using the browser scroll bar or the mouse wheel then the logic of the code is not aware of this and when you next click next/prev a scroll takes place that is not actually relevant to the viewable area you see, totally ruining the user experience.
You can test this in this demo: http://jsfiddle.net/aVJBY/ . If you click NEXT once it works. Now scroll down to near the bottom of the content and click PREV. In theory the page should go one step back from the bottom of the page. Instead it returns to the top of the page.
Maybe I just need to scrap this code and use some external library which is fine, but I can't find anything appropriate. Anyone have an idea on how to make my code resolve this issue?
The code I am using so far is here:
$('div.section').first();
$('a.display').on('click', function(e) {
e.preventDefault();
var t = $(this).text(),
that = $(this);
if (t === 'next' && $('.current').next('div.section').length > 0) {
var $next = $('.current').next('.section');
var top = $next.offset().top;
$('.current').removeClass('current');
$('body').animate({
scrollTop: top
}, function () {
$next.addClass('current');
});
} else if (t === 'prev' && $('.current').prev('div.section').length > 0) {
var $prev = $('.current').prev('.section');
var top = $prev.offset().top;
$('.current').removeClass('current');
$('body').animate({
scrollTop: top
}, function () {
$prev.addClass('current');
});
}
});
I resolved this with the wonderful jQuery inview plugin - https://github.com/protonet/jquery.inview An overview of what I did follows...
I first setup some variables, the pageItems array contains all the divs I need to monitor...
var posNext=0;
var posPrev=0;
var pageItems = ["pageone", "pagetwo", "pagethree", "pagefour", "pagefive"];
I then setup the following in document ready. Thanks to the inview plugin and the jQuery bind event, on a page scroll (of any kind, either by my buttons, manually or via mouse wheel) the plugin is run. I first search the array of page items for a match with what is returned by the $(this).attr("id") value. I then adjust the posNext/posPrev variables with values based on the current div in view.
$(document).ready(function (){
$(".divclass").bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) {
matchPos = pageItems.indexOf($(this).attr("id"));
// Determine prev/next positions now we have an index. The position values used in click events later
if ( (matchPos+1)==pageItems.length ){
posNext=matchPos;
posPrev=matchPos-1;
}else if (matchPos==0){
posNext=matchPos+1;
posPrev=0;
}else{
posNext=matchPos+1;
posPrev=matchPos-1;
}
} else {
// dont update index
}
});
});
Finally also within document.ready I have binds to catch clicks on the buttons I have on screen all the time. These use a jQuery animate call to scroll to the div id value specified via the array index values in posNext/posPrev.
$(".down-button").click(function(e){
event.preventDefault();
$('html, body').stop().animate({
scrollTop: $("#"+pageItems[posNext]).offset().top
}, 500);
});
$(".up-button").click(function(e){
event.preventDefault();
$('html, body').stop().animate({
scrollTop: $("#"+pageItems[posPrev]).offset().top
}, 500);
});

How to prevent links to anchors in a child div from affecting main url?

Consider the following snippet:
<div id="help"></div>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script>
var loadPage = function (){
$("#help").load("http://localhost:3000/manual.html");
}
onload=loadPage;
</script>
This exists on my main page:
http://localhost:3000/
The above code works fine and loads my manual page. But if I click a link like this in manual.html:
<a href='#introduction'>Introduction</a>
Then the page in the help div jumps to the #introduction section, however the url in my browser updates to:
http://localhost:3000/#introduction
This is pointless because the #introduction anchor only exists in manual.html, how can I prevent the links in the #help div from affecting the address bar in the browser?
Try this
$('a').click(function(e) {
e.preventDefault();
$("#help").load($(this).attr('href'));
})
By using offset and preventDefault
$('a').click(function(e) {
// Go to '#introduction'
var targetId = $(this).attr('href');
$('html, body').offset({ top: $(targetId).offset().top, left: 0 });
// this prevent 'http://localhost:3000/#introduction'
e.preventDefault();
});
See this post
I already had a function that could scroll the #help window to a heading, when you click on objects in the parent it scrolls to the relevant section in the help window:
var moveTo = function(destination){
//position of the top of the help window - does not change.
var helpWindow = $("#help").offset().top;
//difference between current scroll position and target position.
var relativeDistance = $(destination).position().top - helpWindow;
//add the distance from current position to the top to get distance to target from top
var absoluteDistance = relativeDistance+ $("#help").scrollTop();
$("#help").animate({
scrollTop: absoluteDistance
}, 1000);
}
Using e.preventDefault() I was able to use this function to do what I want.
For others heading down this path there are two other small things to consider.
Firstly, make sure you nest the .click() function inside the callback from page load, as the hyper links won't exist until the page is loaded. Secondly, You will probably want to use a child selector eg $('#help a').click() to ensure you are only altering the behaviour on links inside the child.
$("#help").load("http://localhost:3000/manual.html", function(){
$('#help a').click(function(e) {
e.preventDefault(); //suppress standard link functionality
moveTo($(this).attr('href')); //scroll to link instead.
})
});

Scroll to element inside modal window

I have a modal window and need to be able to open the modal and then scroll the user to a specific spot in the modal.
I am getting the modal contents with AJAX to a PHP script.
eg mypage.php?loc=someid
In the PHP script I have this JS to do the scrolling:
$( document ).ready(function() {
$('.modal-body').animate({
scrollTop: $("#<?php echo $_GET['loc'];?>").offset().top
}, 1000);
});
in the PHP page is some HTML like this:
<div id="someid"></div>
My content loads correctly but the amount of scroll that happens appears to be relative to the link that opened the modal so it does not actually find the div in the doc.
I am guessing my JS needs a little tweaking.
It seems I need to be able to calculate the offset of the element from the top of the modal content.
I can fake this by setting the value against the element I am scrolling to like this. But I really need a programmatic way of calculating this. Obviously different devices will not work correctly as shown.
$( document ).ready(function() {
$('.modal-body').animate({
scrollTop: $("#<?php echo $_GET['loc'];?>").attr('distance')
}, 1000);
});
//Trying to find out how far this div is from the top of the modal window?
<div id="someid" distance="670"></div>
User found solution but doesn't appear to have added it, so for the sake of completeness, here it is
$( document ).ready(function() {
setTimeout(function() {
var $el = $("#<?php echo $_GET['loc'];?>")
var elpos = $el.position();
$('.modal-body').animate({
scrollTop: elpos.top
}, 1000);
},500);
});
The solution found by the OP and reposted by Rob Quincey works well, HOWEVER do remember that position give you the position relative to the element's parent element.
If the element is a bare <div> it is not problem, but if the grandparent element has some margin or padding properties, then the position of the parent element will be pushed down the page. Which means that the position of this element will also be pushed down. So to the the scrolling to work properly, you need to add the position of the parent element viz:
$( document ).ready(function() {
setTimeout(function() {
var $el = $("#<?php echo $_GET['loc'];?>")
var elpos = $el.position();
var elparentpos = $el.parent().position();
$('.modal-body').animate({
scrollTop: elpos.top + elparentpos.top;
}, 1000);
},500);
});
And then, if necessary, work your way up the DOM tree until you get to the top element which would normally be your modal div. But you only need to address elements which have some top end margin or padding.

Keep clicked link in viewport when calling jQuery's slideUp function

I have the following html structure repeated multiple times on a page:
<div class="item">
<div class="header">
...
Close All Expanded
</div>
<div class="expanded">
...
</div>
</div>
And some jQuery to close all the divs with class expanded when the link is clicked:
$('.closeExpanded').click(function(e){
e.preventDefault();
$('.expanded').slideUp('slow');
});
However I want to ensure that the link you've just clicked remains in view and moves as little as possible. Currently clicking on a link halfway down the page causes the link to move up out of the viewport as divs above it are closed.
Is there a nice graceful way I can keep the link that's been clicked in the viewport?
Update:
I've tried the answers suggested so far but so far none completely work (e.g. clicking link number 30 in each of these leads to link number 30 ending up outside of the viewport)
mrtsherman's solution: http://jsfiddle.net/Qan5p/38/
Mohsen's solution: http://jsfiddle.net/Qan5p/39/
roXon's solution: http://jsfiddle.net/Qan5p/40/
You will need to modify the scrollTop property of the page to keep things in place. Fortunately, as elements are shrunk they will be triggering scroll events you can hook into.
//untested, but should look something like this
var linkPosition = null;
$('.closeExpanded').click(function(e){
e.preventDefault();
linkPosition = $(this).offset().top - $(document).scrollTop();
//in callback to slideUp clear linkPosition so that we know to stop tracking scroll events
$('.expanded').slideUp('slow', function() {
linkPosition = null;
});
});
$(document).scroll( function(){
//check to see if we should be keeping link on screen
if (linkPosition != null) {
//keep the link in position
//I'm not so sure about this bit of the code, but I think you get the idea. All you have to do
//is properly calculate the new offset to keep the link looking like it is in the same position
var newPos = $(document).scrollTop() + linkPosition;
$(document).scrollTop(newPos);
}
});
$('.closeExpanded').click(function(e){
e.preventDefault();
$('.expanded').css({
'position' : 'absolute', // make it position absolute to prevent moving
'left' : $(this).offset().left,
'top' : $(this).offset().top
}).slideUp('slow', function(){
$('.expanded').css('position', 'static');
});
});
Fiddle: http://jsfiddle.net/mohsen/Qan5p/10/
WORKING DEMO
The easiest way:
Wrap contents into dynamically generated divs.
First animate the contents,
Than animate the wrapper elements
$('.expanded').wrapInner('<div class="wrapper" />');
$('.expanded').each(function() {
$(this).height($(this).children('.wrapper').height());
});
$('.closeExpanded').click(function(e) {
e.preventDefault();
$('.wrapper').animate({height: '0px'}, 800, function() {
$('.expanded').slideUp(800);
});
});

Categories