One-pager: how to make subpage URLs scroll to section content?

Forgive me if this was asked before… but I couldn’t find or think of a solution for this.

I’d like the sub-page URLs of a one-pager website to make the page scroll to the content (anchor links?) of those specific sections in the page.

Example:
website.com/my-sub-page would show the content with the id #my_sub_page or something like that.

It’d be a plus if the URLs didn’t change like website.com/my-sub-page redirecting to website.com/#my-sub-page

I’ve found this thread about sub-pages as sections… but the conversations were more “philosophical”:

Add Explicit Support for Multi-Section Pages

Any advice?

One option would be sending the UID data to the homepage using routes.

This (untested) option would let you use your subpages to populate your one-pager, as well as have actual subpages (maybe you want mysite.com/about to link to an actual page, not an anchor on the main page).

The pages that will be used to populate the homepage should not have an associated template.
Additional subpages (like the example above) should have their own templates.

config.php:

<?php 
c::set('routes', array(
  array(
    'pattern' => '(:any)',
    'action'  => function($uid) {
    	// see if a page with this UID actually exists
    	$page = page($uid);

    	// if yes, AND if that page has an associated template, go to it.
    	if ($page && (string)$page->template() == (string)$page->intendedtemplate()) {
    		return site()->visit($page);

    	// if not, go to the homepage, and send the UID along as a variable named 'scroll'
    	} else {
	      $data = array(
	        'scroll' => $uid,
	      );
	      return array('/home', $data);    		
    	}
     }
  )
));

place the variable $scroll in your template somewhere that you can grab it with javascript:

<body data-scroll="<?= isset($scroll) ? $scroll : null; ?>">

This PHP is shorthand for:

if (isset($scroll) {
  echo $scroll;
} else {
  echo null;
}

Then, for example, using jQuery, find the name of the div you want to scroll to, its position, and then scroll to it:

$(window).load(function() {
	var targetDiv = $('body').attr('data-scroll');
	var position = $("#" + targetDiv).offset().top;
	$('body').scrollTop(position);
})

2 Likes

Loved your solution’s flexibility… being able to choose between treating as a one-pager section and link to an actual page (if a template exists) is something I haven’t even thought of… just great.

I’ll try to implement this and report back my discoveries.

Thanks a lot @SQBiz

1 Like

Thanks, yeah let me know if this works!