nav/template stuff

This commit is contained in:
Adam Bradley
2013-08-25 22:54:18 -05:00
parent ae871c1613
commit a0ceba83d5
12 changed files with 254 additions and 246 deletions

View File

@ -12,13 +12,12 @@ Framework!
Page events happen in the order shown and described below:
1. __pageinit__: The user clicked an internal webapp link, which triggers this event before the next page is either requested from the server or retrieved from the cache. The event's detail data contains the URL to request.
1. __pageinit__: The user clicked an internal webapp link, which triggers this event before the next page is either requested from the server or retrieved from the cache. The event's detail data contains the URL of the request.
- __pageinitfailed__: This event is triggered when something has gone wrong while trying to receive data for the next page to show.
2. __pagecreate__: This event is triggered after the new page has been added to the DOM. However, the new page has not started the transition to be in view yet, and the old page is still in view for the user.
3. __pageload__: The new page the user will view has already been received from the server or cache, and has been placed into the DOM. However, it has not started or ended the page transition, it is not in view for the user, and the old page it's replacing is still in view.
4. __pagetransition__: Right before a page transition is about to begin. The new page is in the DOM, but the old page is still being viewed, so its time to transition between the two. The event's detail data contains the `newActivePageId`.
5. __pageview__: The new page the user is viewing has already been received from the server or cache, it has been placed into the DOM, the page transition has completed. This is primarily the event you'll want to listen to to know when a new page is being viewed. Note that while the the old page is not showing, the old page has not been removed from the DOM yet.
6. __pageremove__: The new page is already being viewed by the user and the old page has transitioned out of view. This event is triggered before the old page is about to be removed from the DOM.
2. __pageload__: The new page the user will view has already been successfully received from the server or cache. However, it has not been placed into the DOM, it has not started or ended the page transition, it is not in view for the user, and the old page it's replacing is still in view.
3. __pagecreate__: This event is triggered after the new page has been added to the DOM. However, the new page has not started the transition to be in view yet, and the old page is still in view for the user.
4. __pageview__: The new page the user is viewing has already been received from the server or cache, it has been placed into the DOM, the page transition has completed. This is primarily the event you'll want to listen to to know when a new page is being viewed. Note that while the the old page is not showing, the old page has not been removed from the DOM yet.
5. __pageremove__: The new page is already being viewed by the user and the old page has transitioned out of view. This event is triggered before the old page is about to be removed from the DOM.
### WebApp Events

View File

@ -1,4 +1,3 @@
@charset "UTF-8";
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%; }
@ -37,6 +36,12 @@ main > * {
.content-padded {
padding: 10px; }
.hide {
display: none; }
.show {
display: block; }
.button {
position: relative;
display: inline-block;

View File

@ -28,6 +28,7 @@
</head>
<body>
<section>
<header data-template="primary-header"></header>
@ -52,9 +53,9 @@
</p>
</main>
<footer class="bar-footer"></footer>
</section>
<script src="../js/jquery/jquery-1.10.2.js"></script>
<script src="../js/framework/framework-events.js"></script>

View File

@ -6,6 +6,8 @@
</head>
<body>
<section>
<header data-template="primary-header"></header>
<main>
@ -22,6 +24,8 @@
<footer class="bar-footer"></footer>
</section>
<script src="../js/jquery/jquery-1.10.2.js"></script>
<script src="../js/framework/framework-events.js"></script>
<script src="../js/framework/framework-transition.js"></script>

View File

@ -26,14 +26,16 @@
<script src="app.js"></script>
</head>
<body ontouchstart="">
<body>
<section>
<header class="bar bar-header bar-secondary" data-template="primary-header">
<a class="button button-previous" href="#">
<a class="button button-previous" data-history-go="-1" href="#">
<i class="icon-arrow-left"></i>
</a>
<h1 class="title">Willkommen!</h1>
<a class="button button-next" href="#">
<a class="button button-next" data-history-go="1" href="#">
<i class="icon-arrow-right"></i>
</a>
</header>
@ -54,6 +56,8 @@
<h1 class="title">Auf Wiedersehen</h1>
</footer>
</section>
<script src="../js/jquery/jquery-1.10.2.js"></script>
<script src="../js/framework/framework-events.js"></script>
<script src="../js/framework/framework-transition.js"></script>

View File

@ -28,10 +28,10 @@
</head>
<body>
<section>
<header data-template="primary-header"></header>
<main>
<ul class="list">
<a href="#" class="list-item">
@ -90,14 +90,9 @@
</ul>
</main>
<footer class="bar-footer"></footer>
<script id="framework-globals" type="text/globals">
asdfasf
</script>
</section>
<script src="../js/jquery/jquery-1.10.2.js"></script>
<script src="../js/framework/framework-events.js"></script>

View File

@ -8,23 +8,9 @@
// trigger that the DOM is ready
framework.trigger("ready");
// ensure that the start page has an id
var mainElement = document.querySelector("main");
if(mainElement) {
if(!mainElement.id || mainElement.id === "") {
mainElement.id = "pg" + Math.floor( Math.random() * 999999 );
}
// remember what the active page's id is
framework.activePageId = mainElement.id;
// inform the framework that the start page has been added to the DOM
framework.trigger("pagecreate", {id: mainElement.id, url: location.href});
// trigger that the start page is in view
framework.trigger("pageview");
}
}
// When the DOM is ready, initalize the webapp
if ( document.readyState === "complete" ) {

View File

@ -2,7 +2,9 @@
var
x,
link;
y,
link,
element;
// Add listeners to each link in the document
function addNavListeners() {
@ -17,14 +19,32 @@
}
// Remove listeners from the links in the inactive page element
function removeInactivePageNavListeners(e) {
var element = document.getElementById(e.detail.id);
if(element) {
function removePages(e) {
var removeElements = document.body.getElementsByClassName("remove-element");
for(x = 0; x < removeElements.length; x++) {
element = removeElements[x];
links = element.querySelectorAll("a");
for(x = 0; x < links.length; x++) {
links[x].removeEventListener('click', linkClick, false);
for(y = 0; y < links.length; y++) {
links[y].removeEventListener('click', linkClick, false);
}
element.parentNode.removeChild(element);
}
}
var _init = false;
function locationChange(e) {
if(!_init) {
_init = true;
return;
}
requestData({
url: location.href,
success: successPageLoad,
fail: failedPageLoad
});
}
// A link has been clicked
@ -36,32 +56,32 @@
return false;
}
var
target = e.target;
// data-history-go="-1"
// shortcut if they just want to use window.history.go()
if(target.dataset.historyGo) {
window.history.go( parseInt(target.dataset.historyGo, 10) );
if(e.currentTarget.dataset.historyGo) {
window.history.go( parseInt(e.currentTarget.dataset.historyGo, 10) );
e.preventDefault();
return false;
}
// only intercept the nav click if they're going to the same domain or page
if (location.protocol === target.protocol && location.host === target.host) {
if (location.protocol === e.currentTarget.protocol && location.host === e.currentTarget.host) {
// trigger the event that a new page should be shown
framework.trigger("pageinit", target.href);
framework.trigger("pageinit", e.currentTarget.href);
// decide how to handle this click depending on the href
if(target.getAttribute("href").indexOf("#") === 0) {
if(e.currentTarget.getAttribute("href").indexOf("#") === 0) {
// this click is going to another element within this same page
hashLinkClick(target);
} else {
// this click is going to another page in the same domain
pageLinkClick(target);
requestData({
url: e.currentTarget.href,
success: successPageLoad,
fail: failedPageLoad
});
}
// stop the browser itself from continuing on with this click
@ -71,29 +91,16 @@
}
}
// they are navigating to another URL within the same domain
function pageLinkClick(target) {
push({
url: target.href
});
}
// they are navigation to an anchor within the same page
function hashLinkClick(target) {
console.log("hashLinkClick, get:", target.href);
}
function push(options) {
function requestData(options) {
framework.isRequesting = true;
var xhr = new XMLHttpRequest();
xhr.open('GET', options.url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if(xhr.status === 200) {
successPageLoad(xhr, options);
options.success(xhr, options);
} else {
failedPageLoad(options.url);
options.fail(xhr, options);
}
}
};
@ -102,21 +109,17 @@
function successPageLoad(xhr, options) {
framework.isRequesting = false;
var data = parseXHR(xhr, options);
insertPageIntoDom(data);
framework.trigger("pagetransition", {
newActivePageId: data.id,
url: data.url,
title: data.title
framework.trigger("pageloaded", {
data: parseXHR(xhr, options)
});
}
function failedPageLoad(options) {
framework.trigger("pageinitfailed");
function failedPageLoad(xhr, options) {
framework.isRequesting = false;
framework.trigger("pageinitfailed", {
responseText: xhr.responseText,
responseStatus: xhr.status
});
}
function parseXHR(xhr, options) {
@ -143,51 +146,24 @@
// get the main content of the page
tmp = container.querySelector("main");
if(tmp) {
// get an id for this element
if(!tmp.id || tmp.id === "") {
// it doesn't already have an id, so build a random one for it
data.id = "pg" + Math.floor( Math.random() * 999999 );
} else {
// use their existing id
data.id = tmp.id;
}
data.main = tmp.innerHTML;
} else {
// something is wrong with the data, trigger that the page init failed
framework.trigger("pageinitfailed");
}
return data;
}
function insertPageIntoDom(data) {
if(data && data.main) {
// get the first main element
var oldMainElement = document.querySelector("main");
// build a new main element to hold the new data
var newMainElement = document.createElement("main");
newMainElement.id = data.id;
newMainElement.innerHTML = data.main;
// insert the new main element before the old main element
oldMainElement.parentNode.insertBefore(newMainElement, oldMainElement);
// inform the framework that a new page has been added to the DOM
framework.trigger("pagecreate", {
id: data.id,
url: data.url,
title: data.title
});
} else {
// something is wrong with the data, trigger that the page init failed
framework.trigger("pageinitfailed");
}
}
// after a page has been added to the DOM
framework.on("ready", addNavListeners);
framework.on("pagecreate", addNavListeners);
// before a page is about to be removed from the DOM
framework.on("pageremove", removeInactivePageNavListeners);
framework.on("pageremove", removePages);
// listen to when the location changes
framework.on("popstate", locationChange);
})(this, document, location, FM = this.FM || {});

View File

@ -9,13 +9,15 @@
var
x,
el,
emptyTemplates = [];
tmp,
emptyTemplates = [],
container;
// collect up all the templates currently in the DOM
for(x=0; x<document.all.length; x++) {
el = document.all[x];
if(el.dataset.template && !el._templateSet) {
if(el.dataset.template && !el.tSet) {
// this element is either supplying template
// data or it needs to be filled with template data
@ -34,26 +36,32 @@
// lasts for as long as the browser is open and survives over page
// reloads and restores. Opening a page in a new tab or window will
// cause a new session to be initiated.
sessionStorage.setItem(el.dataset.template, el.innerHTML);
sessionStorage.setItem("t:" + el.dataset.template, el.outerHTML);
}
// remember that this is set so we don't bother doing all this
// code again for the same element in the future
el._templateIsSet = true;
el.tSet = true;
}
}
// go through each empty template and build it up with existing template data
for(x=0; x<emptyTemplates.length; x++) {
el = emptyTemplates[x];
tmp = sessionStorage.getItem("t:" + el.dataset.template);
if(tmp) {
// we've got template data, plug it into this element's innerHTML
emptyTemplates[x].innerHTML = tmp;
container = document.createElement("div");
container.innerHTML = tmp;
el.parentNode.replaceChild(container.children[0], el);
}
}
}
framework.on("ready", initTemplates);
framework.on("pagecreate", initTemplates);
})(this, document, FM = this.FM || {});

View File

@ -1,18 +1,41 @@
(function(window, document, framework) {
function transitionBegin(e) {
var activePageElement = document.getElementById(framework.activePageId);
if(activePageElement) {
activePageElement.parentNode.removeChild(activePageElement);
function initTransition(e) {
var data = e.detail.data;
displayTransition(data);
}
// No animation. Nothing fancy here, just display none to block
function displayTransition(data) {
// build a new main element to hold the new data
var newMainElement = document.createElement("main");
newMainElement.innerHTML = data.main;
var oldMainElement = document.querySelector("main");
oldMainElement.className += " hide remove-element";
insertPageIntoDom(newMainElement, oldMainElement, data);
history.pushState({}, data.title, data.url);
framework.trigger("pageview");
framework.trigger("pageremove");
}
// insert the new main element before the old main element
function insertPageIntoDom(newMainElement, oldMainElement, data) {
oldMainElement.parentNode.insertBefore(newMainElement, oldMainElement);
// inform the framework that a new page has been added to the DOM
framework.trigger("pagecreate", {
id: data.id,
url: data.url,
title: data.title
});
}
framework.on("pagetransition", transitionBegin);
framework.on("pageloaded", initTransition);
})(this, document, FM = this.FM || {});

View File

@ -22,18 +22,18 @@
console.log('pageinitfailed');
});
framework.on('pageloaded', function(e){
console.log('pageloaded,', e.detail.data.url, ", Title:", e.detail.data.title);
});
framework.on('pagecreate', function(e){
console.log('pagecreate, id:', e.detail.id, ", URL:", e.detail.url);
console.log('pagecreate,', e.detail.url);
});
framework.on('pagetransition', function(e){
console.log('pagetransition, newActivePageId:', e.detail.newActivePageId);
});
framework.on('pageload', function(){
console.log('pageload');
});
framework.on('pageview', function(){
console.log('pageview');
});

View File

@ -43,3 +43,10 @@ main > * {
.content-padded {
padding: $contentPadding;
}
.hide {
display: none;
}
.show {
display: block;
}