How can I load the content of tumblr nextPage on indexPage - javascript

I'm developing a tumblr theme for my personal portfolio, but I'm encountering a serious problem in my work section, I want to create an horizontal slider effect, when I click next to see older posts,
like this:
http://tympanus.net/Tutorials/WebsiteScrolling/
I have this to define my nextPage, #section4 is where I have the posts of my work:
<!-- Next Page -->
{block:NextPage}
<div>
<a id="next-button" href="{NextPage}#section4" class="next panel" style="position:relative; top:630px; left:1550px;">next</a>
</div>
{/block:NextPage}
<!-- / Next Page -->
Well, this is defined to open an other page:
"indexPage".tumblr.com#section4
when I click next it goes to:
"indexPage".tumblr.com/page/2#section4
Is there a way I can do this slide effect on my index page or at least give the illusion, that I'm making slide effect, when moving to other page?

If I understand your question correctly, it is as serakfalcon mentioned but I'll add in tumblr specific points. You need to do three things specifically. I won't go into too much tumblr template codes and styling it and stick to these
Loading the data dynamically
Dynamically creating a new section/page
Getting the navigation to work with new sections
Loading the data
This is actually the easy bit. For tumblr, as you mentioned, we can manually go to the next page by clicking the "next page" link. In tumblr this will look something like
{block:NextPage}
<li></li>{lang:Next page}</li>
{/block:NextPage}
Since the pages are on the same domain, we can override the link to get the page using AJAX. We will be getting the raw HTML for this page. Which will include all the other parts of the page like the three other sections. There may be some tumblr template magic that we can do to limit this, but I'll consider that outside the scope. So how do we get the content specifically? We can feed the raw HTML into jquery for it to build document objects, and we can then select the content that has the post from there. So something like.
$(document.body).on('click',".static",function(e){ //delegated
var xhr=$.get($(this).attr("href"),function(a){ //a is next page's HTML
$loaded=$(a); //loaded now has a temporary object with next page's objects
var postsHTML=$loaded.find("#posts").html() //contains posts we can embed
//what to find depends on your template. I used the default id="posts"
})
})
Creating a new section/page
Once we have the data, we now need to put the data into a new page. There's many ways on doing this but here's how I did it. First of all, I had a template for the new section. I put it in a script tag like so. I kind of like the semantics of doing it like this.
<script type="text/x-template" id="section-template">
<div class="section">
<div class="posts"></div>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>Back</li>
<li>Next</li>
</ul>
</div>
</script>
With that done, whenever the data is loaded we can get the raw HTML from this, and create a the new elements by feeding it to jQuery again. We then append the posts to the div with class posts. We also get the next page link from the data to attach to the next-page link so that the earlier ajax call will work. If we can't find the next-page link, that means there's no more posts. So we can hide the next-page link. We'll also stop the existing link to load data through ajax and do the normal slidey thing. Finally we'll append the new section to the parent div of the sections, fix it's width and then transition to the new section.
$(document.body).on('click',".static",function(e){ //deferred
e.preventDefault();
var that=this //to refer inside $.get callback
var xhr=$.get($(this).attr("href"),function(a){
$(that).removeClass('static') //stop this link from loading again
var $loaded=$(a)
var next_section=$($("#section-template").html()); //make the new section
var num_sections=$(".section").length + 1 //number of sections
next_section.addClass(num_sections%2 ? "white" : "black") //consistency
//find .posts in the new section and put the tumblr data in it
next_section.find(".posts").html($loaded.find("#posts").html())
//tumblr next page link. change according to template
var next_link=$loaded.find(".static")
if(next_link.length){ //if next link exists
//attach href to next page link in new section
next_section.find(".static").attr("href",next_link.attr("href"))
} else { //no next
//hide the next page link in new section
next_section.find(".static").hide()
}
$("#horizontal-scroller").append(next_section); //append to body
$("#horizontal-scroller").width(4000*num_sections); //resize body
$('html, body').stop().animate({ //to the new section
scrollLeft: $(next_section).offset().left
}, 1000);
}) //$.get
}) //click
Getting the navigation to work
I probably should append new links to the nav, but I guess to make it easier (and imagine how it look like with 40 pages) I decided to just use a "next page" and "last page" for the loaded content. The code is simple. For next page, if it's not .static, move to the next section and ditto last page. we'll delegate (technically, I'm using .on() but the docs on .delegate seemed easier to understand) it to the document body so that it works for all the new links.
So as a whole javascript/jquery will look something like
$(document.body)
.on('click','ul.nav a:not(.next-page):not(.last-page)',function(e){
var $anchor = $(this);
$('html, body').stop().animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, 1000);
e.preventDefault();
})
.on('click',".next-page:not(.static)",function(e){ //next page not static
e.preventDefault()
$('html, body').stop().animate({
scrollLeft: $(this).closest(".section").nextAll(".section").offset().left
}, 1000);
})
.on('click',".last-page",function(e){ //last page
e.preventDefault()
$('html, body').stop().animate({
scrollLeft: $(this).closest(".section").prevAll(".section").offset().left
}, 1000);
})
.on('click',".static",function(e){
e.preventDefault();
var that=this
var xhr=$.get($(this).attr("href"),function(a){
$(that).removeClass('static')
var $loaded=$(a)
var next_section=$($("#section-template").html());
var num_sections=$(".section").length + 1
next_section.addClass(num_sections%2 ? "white" : "black")
next_section.find(".posts").html($loaded.find("#posts").html())
var next_link=$loaded.find(".static")
if(next_link.length){
next_section.find(".static").attr("href",next_link.attr("href"))
} else {
next_section.find(".static").hide()
}
$("#horizontal-scroller").append(next_section); //append to body
$("#horizontal-scroller").width(4000*num_sections); //resize body
$('html, body').stop().animate({
scrollLeft: $(next_section).offset().left
}, 1000);
}) //$.get
}) //click
Here's a live demo of it working. Didn't really bother with making the slides look nice but hopefully you found this helpful.

Of course, everything has to happen on one page, or you can't exactly have the transition. So, either you load everything at run time, or you 'cheat' using AJAX.
alter the in-page javascript to the following:
function bindAnimation(event) {
var $anchor = $(this);
/*
if you want to use one of the easing effects:
$('html, body').stop().animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, 1500,'easeInOutExpo');
*/
$('html, body').stop().animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, 1000);
event.preventDefault();
}
$(function() {
$('ul.nav').on('click','.getNew',getNewSection);
$('ul.nav').on('click','a',bindAnimation);
});
This allows you to add a elements dynamically to the navs, and will attach an event listener to a new element we will use to get new content.
Modify the nav menu so that the last element is something like:
<li class="getNew">New</li>
There. now clicking on that will load the new content.
add this javascript code to your site above the previous javascript code:
window.newSectionBlack = false;
window.SectionID = 4;
function displaySection(data,textStatus, jqXHR) {
$('#section3').after(data.html); //add the new section
$('#'+data.id).addClass(newSectionBlack ? 'black' : 'white');
newSectionBlack = !newSectionBlack; //style it consistently
$('.getNew').before('<li><a href="#'+data.id+'">'+data.name+'</li>'); //attach a link to the new section to the menu
$('body').css({width:4000*SectionID});
$('#'+data.id+' ul.nav').on('click','a',bindAnimation); //bind scripts
$('#'+data.id+' ul.nav').on('click','.getNew',getNewSection);
$('#section1 > ul li:nth-last-child(2) > a').trigger('click'); //go to new
SectionID++;
}
function getNewSection() {
$.ajax({
type: "POST",
url: 'LoadSection.php',
data: {section:SectionID},
success: displaySection,
dataType: 'json'
});
}
This javascript will POST a number corresponding to which section to load to a new file, LoadSection.php, which needs to respond with the HTML of the new section, the ID and name it should be called.
loadSection.php can look like this:
<?php
header('Content-Type: application/json');
$send = array();
switch($_POST['section']) {
default:
$send['html'] = '<div class="section" id="section'.$_POST['section'] .'"><h2>Section ' . $_POST['section'] . '</h2>
<p>
This is a new section loaded via AJAX, cool huh?
</p>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li class="getNew">New</li>
</ul>
</div>';
$send['id'] = 'section'.$_POST['section'];
$send['name'] = $_POST['section'];
}
echo json_encode($send);
Now, your page can load content dynamically!
Note, the nav bar should probably be restructured to be an absolute element that there's only one of instead of repeated on every page, and there's other stuff you can clean up but that's to be expected if you're taking a codrops example.
EDIT:
tumblr doesn't let you run server-side scripts on their server (makes sense), which are required for the AJAX method described above to work. However, there are a number of options available to you.
1) redirect the tumblr page to a site you control, and use the method described above.
2) use an iframe.
The iframe method could be done directly, which requires you to specify the urls of all the pages in advance (or at least they'll need to follow a predictable pattern), or indirectly using a AJAX script similar to the one above. I will demonstrate loading a direct iframe, I'm sure you can figure out the rest.
window.newSectionBlack = false;
window.newSectionID = 4;
function getNewSection() {
$('#section3').after('<div class="section" id="section'+newSectionID+'"><h2>New Section</h2>
<iframe src="yourtumbrsite.com></iframe>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li class="getNew">New</li>
</ul>
</div>
'); //add the new section
$('#section'+newSectionID).addClass(newSectionBlack ? 'black' : 'white');
newSectionBlack = !newSectionBlack; //style it consistently
$('.getNew').before('<li><a href="#section'+newSectionID+'">'+newSectionID+</li>'); //attach a link to the new section to the menu
$('body').css({width:4000*newSectionID});
$('#'+data.id+' ul.nav').on('click','a',bindAnimation); //bind scripts
$('#'+data.id+' ul.nav').on('click','.getNew',getNewSection);
$('#section1 > ul li:nth-last-child(2) > a').trigger('click'); //go to new
newSectionID++;
}

Related

One-Page Scroll: Trying to redirect to home page and scroll to the div - Not Working?

Right, I've been at it for a while now. One page scroll works on home page (where the div ids are defined).
Problem: FROM blog page, if a user clicks 'contact', I want them to be redirected to the home page THEN animated scroll to the #contact-View div.
Attempt: I've tried to check if user clicks a tag, then check if there are now blog page using if statement, then redirect them back to home page (and to the div) using
window.location.href = home +sectionID;
Not working.
header.php (only the nav bit..)
<nav class="header-nav">
<!-- Create a navigation called primary in the header (front-end) -->
<?php $args = array('theme_location' => 'primary'); ?>
<?php wp_nav_menu( $args) ?>
</nav>
front-page.php (home)
<div id="about-View" class="bg-1-wrapper"> #content </div>
<div id="contact-View"> #content </div>
Javascript
jQuery(document).ready(function() {
// add a click listener to each <a> tags
setBindings();
// burger nav
jQuery(".burger-nav").on("click", function() {
jQuery(".header-nav").toggleClass("open");
});
});
function redirectToHome() {
}
/* ONE PAGE NAVIGATION FUNCTION */
function setBindings() {
jQuery('a[href^="#"]').on('click', function(e) {
e.preventDefault();
var home = "http://localhost/wordpress/";
// Get the href attribute, which includes '#' already
var sectionID = jQuery(this).attr('href') + "-View";
// if you're on blog page, first redirect to home -> div: #contact-View
if(document.URL.indexOf("http://localhost/wordpress/blog") >= 0){
window.location.href = home +sectionID;
console.log(location.href);
}
// Animate the scroll
jQuery("html, body").animate({
// Find target element
scrollTop: jQuery(sectionID).offset().top
}, 1000)
});
}
Any ideas how to fix the problem?
Two things can happen when updating the value of window.location.href:
If the new value is located at the current page (by using an anchor), it will jump to that point without reloading the page
If the new value is not located at the current page, JavaScript execution will stop and the new page will be requested and loaded
The problem with the animate function not executing is the latter in this case.
A solution would be to request the new page appended by an extra non-existent anchor (#contact-View-scroll, for example). On the new page, you could use JavaScript to check for this particular anchor value in the URL and execute the scroll functionality if necessary.
Hope this helps in understanding and solving your problem.
update: added some example code below
Step 1:
On the blog page, update the links that refer to the home page by prepending the following content to the hashtag: #scroll:(Such that http://localhost/wordpress/home#contact-View becomes http://localhost/wordpress/home#scroll:contact-View)
Step 2:
Add the following code snippet to the home page. This will search for the #scroll: tag and activate the animate function if present.
jQuery(document).ready(function() {
// Get the hash from the URL
var hash = window.location.hash;
// If a hash exists && starts with "#scroll:"
if (hash.length and hash.indexOf('#scroll:') === 0) {
// Get the anchor name we are scrolling to
var selectionID = hash.substr('#scroll:'.length);
// Call the jQuery scroll function
jQuery("html, body").animate({
scrollTop: jQuery('#'+selectionID).offset().top
}, 1000);
}
});
Step 3: Enjoy!
Also, see https://jsfiddle.net/qcarmk2w for a demo.

jQuery smooth scrolling on a different webpage

I have managed to get the smooth scrolling working on a single page using the following code.
Note the HTML link is stored in a header.php and used across multiple pages below is a code snippet:
HTML Script:
<a class="item" href="index.php#contact">
<a name="contact"></a>
JS Script:
$('a[href="index.php#contact"]').click(function (e) { // user clicks on html link
e.preventDefault(); // prevent the default behaviour that occurs in the browser
var targetOffset = $('a[name="contact"]').offset().top; // define a variable to point at a particular section & offset from the top of browser
$('body').animate( // create animation
{ scrollTop: targetOffset }, 1000); // scrollTop property = target variable
});
Problem:
When I go to a different webpage and click the contact link it does not link back to the index.php#contact and scroll down to the contact anchor point.
Any assistance or advice is much appreciated I'm sure its a simple tweak in the code somewhere.
Check your href it's supposed to be: index.php/#contact

How to scroll to a specifc element when there is already an # anchor on the url

I have a web site on based on SkelJS that currently loads a different part of the webpage by appending an #anchor to the url like this:
Note that #blog loads the blog page, the scroll is at the top. Inside the Blog page I need to scroll to a certain article. How can I use two anchors so that something like #blog#article_x would work? I suppose I have to look for a workaround since anchoring 2 ids makes no sense, is there a work around?
Additional notes:
Note that if a change #blog to #article_x it actually goes to the desired article however if someone shares the link it won't go to the article because it will look for #article_x on the homepage, where it does not exists.
Here is a demo of the template I'm using (http://html5up.net/uploads/demos/astral/#) note how the #anchor loads the desired page.
You can use a hash that contains both page and element. Then split and then do your page load then scroll, i.e. #blog,someelement
//on page load or wherever you detect the hash
$(function(){
var hash = window.location.hash;
var ele = null;
//Detect if there is a splitable hash
if(hash.indexOf(",") != -1){
var parts = hash.split(",");
hash = parts[0];
ele = jQuery("#"+parts[1]);
}
//whatever function you do to load the blog page
loadPage(hash,ele);
});
function loadPage(page,ele){
//do page loading
$("#page").load("http://someurl.com",function(){
//if there was no second part to the hash
//this will be skipped
if(ele){
$("html,body").animate({
scrollTop: ele.offset().top
},1000);
}
});
}
JSfiddle Demo
Considering the ID of the element that you want to scroll to is myelement you can use below jquery code to smoothly scroll to it.
$("html,body").animate({scrollTop : $("#myelement").offset().top},1000);
We can scroll to specific div when it has id or class
var $id=window.location.href.split('#')[1];
$('html, body').scrollTop($("#"+$id).offset().top)

How can I make this jQuery div scroller work on multiple divs with the same class?

I've been using this jQuery div scroll script (How to make a scrolable div scroll on click and mouseover using jQuery) to good effect, but now my client wants me to use it within a Wordpress blog page where there are multiple areas on the page that need scrolling.
Is it possible to use this script on multiple instances with the same class (Ie; 'scroll')?
This is my script;
$(function() {
var ele = $('.scroll');
var speed = 25, scroll = 5, scrolling;
$('#scroll-up').mouseenter(function() {
// Scroll the element up
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() - scroll );
}, speed);
});
$('#scroll-down').mouseenter(function() {
// Scroll the element down
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() + scroll );
}, speed);
});
$('#scroll-up, #scroll-down').bind({
click: function(e) {
// Prevent the default click action
e.preventDefault();
},
mouseleave: function() {
if (scrolling) {
window.clearInterval(scrolling);
scrolling = false;
}
}
});
});
and this is the markup (Both the Main "feed" wrapper and the individual "single" divs need to be scrollable);
<div class="feed scroll">
<div class="single scroll">
<!-- single blog post content -->
</div>
<div class="single scroll">
<!-- single blog post content -->
</div>
<div class="single scroll">
<!-- single blog post content -->
</div>
</div>
<a id="scroll-up" href="#">Scroll Up</a>
<a id="scroll-down" href="#">Scroll Down</a>
So basically I need to be able to scroll everything individually.
If you want multiple sections, you'll have to use classes, rather than ids for identifying the sections, then you'll have to traverse the DOM from your link to the content to scroll in order to find the right div. Also, you'll have to store the 'scrolling' status individually for each element that you're scrolling.
That's a lot of stuff to explain verbally. Here's an example, modified from the question you referenced: http://jsfiddle.net/Qp8bB/
Note:
$(this).siblings(".content")
This is how we navigate from the link element to the content
element.attr('data-scrolling', 'true');
This is how we store the scrolling status of each element (via a temporary attribute)
Not the cleanest code, but I hope it gets the point across.

How can I get all my links to scroll to the top of the page by placing one function in a coldfusion code

This is the function that I currently have.
Instead of one link I want all my links to scroll to the top of the page. The function is to be placed within a coldfusion code.
<script>
function ScrollClick() {
// Scroll to top
document.body.scrollTop = document.documentElement.scrollTop = 0;
// Open up a link in my iframe
document.getElementById('MainWindow').src="DocDisplayCategory.cfm?categoryID=89"
}
</script>
</li>
Here's how you'd do it with jQuery, in case that's an option for you:
$("body").on("click", "a", function(){
$("html, body").animate({ scrollTop: 0 }, "slow");
});
http://jsfiddle.net/sL2vA/2/
UPDATE: To help clear up confusion regarding ColdFusion, you'd simply add this to the head of your template (assuming jQuery isn't already available):
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
And put the above code wherever appropriate in your application (in the template footer, in an external JS file, whatever). Wrap it in a script tag if it's in the template.

Categories

Resources