About

parkrun Event Results Navigation adds a sticky bar to single-event results pages so you can step to the previous or next event at the same location without editing the URL.

Where it works

The bar appears on event-number URLs (for example /coburg/results/400/), date URLs (/coburg/results/2024-06-15/), and latestresults pages. It does not appear on event history or other aggregate views.

Junior locations (for example westerfolds-juniors) are supported. Navigation always stays within the current location slug.

Controls

  • Previous event (#n−1) and Next event (#n+1) links in the sticky bar
  • Keyboard shortcuts: [ for previous, ] for next (suppressed while focus is in a text field)
  • Previous is unavailable on event #1; Next is always available

Navigation always uses event-number URLs. The centre of the bar shows the current event number, formatted date, and shortcut hints.

Version 0.1.5 Updated

Screenshot

parkrun Event Results Navigation Screenshot

Install

Recommended: userscript. Bookmarklet works where a userscript manager isn’t available.

Userscript (recommended)

Install parkrun Event Results Navigation

First time? Userscript basics and installation steps

What is a userscript?

A userscript is a small piece of JavaScript that runs in your browser and enhances specific websites. These scripts work with parkrun event pages, parkrunner profile pages, and results pages, and can be used with any userscript manager including Userscripts, Tampermonkey, Violentmonkey, or any compatible browser extension.

Installation steps

  1. Install a userscript manager for your browser:
  2. Click the Install button above for this script.
  3. Click “Install” when prompted by your userscript manager.

Bookmarklet

A bookmarklet is a bookmark whose URL is JavaScript. Use it on browsers that support bookmarks but not userscript managers.

Drag this link to your bookmarks bar:

parkrun Event Results Navigation bookmarklet

Mobile bookmarklet setup and full code

Mobile bookmarklet

On mobile browsers that let you edit bookmark URLs:

  1. Copy the JavaScript code below to your clipboard.
  2. Create a new bookmark for any page.
  3. Edit the bookmark and replace its URL with the code you copied.
  4. Navigate to the relevant parkrun page.
  5. Select the bookmark to run the script.
javascript:function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){var n;if(e)return"string"==typeof e?_arrayLikeToArray(e,t):"Map"===(n="Object"===(n={}.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function _iterableToArrayLimit(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,o,l,i=[],s=!0,u=!1;try{if(o=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;s=!1}else for(;!(s=(r=o.call(n)).done)&&(i.push(r.value),i.length!==t);s=!0);}catch(e){u=!0,a=e}finally{try{if(!s&&null!=n.return&&(l=n.return(),Object(l)!==l))return}finally{if(u)throw a}}return i}}function _arrayWithHoles(e){if(Array.isArray(e))return e}(()=>{var d="parkrun-event-results-navigation",l="data-parkrun-event-nav-padding",y={backgroundColor:"#2b223d",accentColor:"#FFA300",textColor:"#EEE",disabledColor:"#9a8fb3"},a=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],n=new Set(["eventhistory"]),r=/^\/([^/]+)\/results\/([^/]+)\/?$/;function i(e){var t,e=e.match(r);return!e||(t=(e=_slicedToArray(e,3))[1],n.has(e=e[2]))?null:/^\d+$/.test(e)?{location:t,segmentType:"number",eventNumber:parseInt(e,10)}:/^\d{4}-\d{2}-\d{2}$/.test(e)?{location:t,segmentType:"date"}:"latestresults"===e?{location:t,segmentType:"latest"}:null}function s(e){return null!==i(e)}function u(e){var t,n,e=e.querySelector("h3");return e&&(t=e.textContent.match(/#(\d+)/))?((n=(n=e.querySelector(".format-date"))?n.textContent.trim():"")||(e=e.textContent.match(/(\d{1,2}\/\d{1,2}\/\d{2,4})/))&&(n=e[1]),{eventNumber:parseInt(t[1],10),rawDate:n}):null}function c(e){var t,n,r;return e?3!==(r=e.split("/")).length||(t=parseInt(r[0],10),n=parseInt(r[1],10),(r=parseInt(r[2],10))<100&&(r+=2e3),!t)||!n||n<1||12<n?e:"".concat(t," ").concat(a[n-1]," ").concat(r):""}function b(e,t,n){return"".concat(e,"/").concat(t,"/results/").concat(n,"/")}function p(e){return!!e.querySelector(".Results-table")&&null!==u(e)}function v(e){var t;return!(!(e&&e instanceof Element)||"INPUT"!==(t=e.tagName)&&"TEXTAREA"!==t&&"SELECT"!==t&&!e.isContentEditable)}function m(e){e.style.display="inline-block",e.style.padding="0.4rem 0.8rem",e.style.backgroundColor=y.accentColor,e.style.color=y.backgroundColor,e.style.textDecoration="none",e.style.borderRadius="4px",e.style.fontWeight="bold",e.style.lineHeight="1.4"}function f(e){e.style.display="inline-block",e.style.padding="0.1rem 0.35rem",e.style.border="1px solid #5a4f73",e.style.borderRadius="3px",e.style.backgroundColor="#3a3250",e.style.fontFamily="inherit",e.style.fontSize="0.85em",e.style.cursor="help"}function g(e,t,n){var n=n?" · ".concat(n):"",r=e.createElement("div"),a=(r.style.flex="1",r.style.textAlign="center",r.style.fontWeight="bold",r.setAttribute("aria-live","polite"),e.createElement("kbd")),o=(a.textContent="[",a.title="Go to previous event",a.setAttribute("aria-label","Go to previous event (keyboard shortcut [)"),f(a),e.createElement("span")),t=(o.textContent="#".concat(t).concat(n),e.createElement("kbd"));return t.textContent="]",t.title="Go to next event",t.setAttribute("aria-label","Go to next event (keyboard shortcut ])"),f(t),r.append(a,e.createTextNode(" "),o,e.createTextNode(" "),t),r}function h(e){var t=e.origin,n=e.location,r=e.eventNumber,a=e.formattedDate,e=e.doc,o=r-1,l=r+1,i="Previous event (#".concat(o,")"),s="Next event (#".concat(l,")"),u=e.createElement("nav"),c=(u.id=d,u.setAttribute("role","navigation"),u.setAttribute("aria-label","Event results navigation"),u.style.position="fixed",u.style.top="0",u.style.left="0",u.style.right="0",u.style.zIndex="10000",u.style.display="flex",u.style.alignItems="center",u.style.justifyContent="space-between",u.style.gap="1rem",u.style.padding="0.5rem 1rem",u.style.backgroundColor=y.backgroundColor,u.style.color=y.textColor,u.style.boxShadow="0 2px 4px rgba(0, 0, 0, 0.3)",u.style.fontFamily="Arial, Helvetica, sans-serif",u.style.fontSize="0.95rem",e.createElement(1<r?"a":"span")),o=(1<r?(c.href=b(t,n,o),c.setAttribute("aria-label",i),m(c)):(c.setAttribute("aria-disabled","true"),c.setAttribute("tabindex","-1"),(o=c).style.display="inline-block",o.style.padding="0.4rem 0.8rem",o.style.backgroundColor="#3a3250",o.style.color=y.disabledColor,o.style.borderRadius="4px",o.style.fontWeight="bold",o.style.lineHeight="1.4",o.style.cursor="not-allowed"),c.textContent=i,c.className="parkrun-event-nav-previous",g(e,r,a)),i=e.createElement("a");return i.href=b(t,n,l),i.textContent=s,i.setAttribute("aria-label",s),i.className="parkrun-event-nav-next",m(i),u.appendChild(c),u.appendChild(o),u.appendChild(i),u}var x=null;function o(){var e,t,n,r=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},a=null!=(a=r.document)?a:document,o=null!=(o=r.pathname)?o:window.location.pathname,r=null!=(r=r.origin)?r:window.location.origin;return s(o)&&p(a)?a.getElementById(d)?a.getElementById(d):(o=i(o),e=u(a),o&&e?(t=c(e.rawDate),r=h({origin:r,location:o.location,eventNumber:e.eventNumber,formattedDate:t,doc:a}),a.body.insertBefore(r,a.body.firstChild),o=a,e="".concat((e=r).offsetHeight,"px"),o.body.style.paddingTop=e,o.body.setAttribute(l,e),t=a,n=r,x&&t.removeEventListener("keydown",x),x=function(e){var t;v(e.target)||("["===e.key&&(t=n.querySelector(".parkrun-event-nav-previous"))instanceof HTMLAnchorElement&&(e.preventDefault(),t.click()),"]"===e.key&&(t=n.querySelector(".parkrun-event-nav-next"))instanceof HTMLAnchorElement&&(e.preventDefault(),t.click()))},t.addEventListener("keydown",x),r):null):null}function e(){var e,t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},n=null!=(n=t.document)?n:document;return s(null!=(e=t.pathname)?e:window.location.pathname)?(e=function(){return o(t)},p(n)?e():function(e,t){var n,r=null!=(t=(1<arguments.length&&void 0!==t?t:{}).document)?t:document;return p(r)?(e(),null):((n=new MutationObserver(function(){p(r)&&(n.disconnect(),e())})).observe(r.body,{childList:!0,subtree:!0}),n)}(e,t)):null}"undefined"!=typeof module&&module.exports?module.exports={BAR_ID:d,parseResultsPath:i,isSingleEventResultsPath:s,extractEventMetadata:u,formatEventDateAustralian:c,buildEventResultsUrl:b,isPageReady:p,shouldSuppressKeyboardShortcut:v,createCentreLabel:g,createNavigationBar:h,renderNavigationBar:o,init:e}:e()})();

Support

Issues and support on GitHub