A lightweight single page bone for mobile web App
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
build
examples
src
.gitignore
LICENSE
README.md
README_zh-CN.md
gulpfile.js
package.json

README.md

mobile-router.js — A lightweight single page bone for mobile web App

NPM Version NPM Downloads

Online docs

DEMO - source code

require.js DEMO - source code

The mobile-router.js-demo is a simple mobile web app demo for mobile-router.js.

mobile-router.js-sample - A mobile-router.js demo like ui-router sample

中文 README

Less than 9k when gzipped

How can i install it?

Download a latest build from https://github.com/dolymood/mobile-router.js/releases it contains development and minified production files in build/ folder.

or use npm

npm install mobile-router.js

or use git clone

git clone https://github.com/dolymood/mobile-router.js.git

How can i use it?

M.router.init([
	{
		path: '/', // route path
		cacheTemplate: false, // cacheTemplate option for current route
		animation: true, // animation option for current route
		aniClass: 'slideup', // switching effects option for current route
		getTemplate: function() { // sync
			return '/index template content';
		},
		onActive: function() { // 1.5.5+ // called when the route is actived, even before create `page-view` element

		},
		callback: function() { // called after the page has been shown
			if (this.cached) return; // the page was cached in document.
			// do something ...
		},
		onDestroy: function() {
			// destroy
		},
		onEnter: function(paramName) { // 1.5.3+ // called when the page will show

		},
		onLeave: function() { // 1.5.3+ // called when the page will hide

		}
	},
	{
		path: '/m/:paramName',
		getTemplate: function(cb) { // async
			var that = this;
			// that.params - params info
			// that.query - query info
			setTimeout(function() {
				cb('/m/' + that.params.paramName + ' template content');
			}, 200);
		},
		callback: function(paramName) {
			if (this.cached) return;
			// do something ...
		},
		onDestroy: function() {
			// destroy
		}
	},
	{ // support redirectTo , string url or function (1.5.5+)
		path: '/redirectTo/:rtPath',
		redirectPushState: false, // default true, enable `pushState` when redirectTo is actived
		redirectTo: function(rtPath) {
			console.log('redirectTo', arguments, this);
			return '/' + rtPath;
		}
	},
	{ // support redirectTo , string url or function (1.5.5+)
		// if redirectTo route have getTemplate then the `page-view` will
		// be created, looks like a normal route. The redirectTo will be actived
		// after the route's callback is called
		path: '/contacts',
		getTemplate: contacts.getTemplate,
		onEnter: contacts.onEnter,
		onLeave: contacts.onLeave,
		callback: contacts.controller,
		onDestroy: contacts.onDestroy,

		redirectTo: '/contacts/list',
		redirectPushState: false,

		children: { // Nested routes & views! (1.5.0+)
			viewsSelector: '.content',
			cacheViewsNum: 1,
			routes: [
				{
					// all contacts
					path: '/list',
					getTemplate: list.getTemplate,
					onEnter: list.onEnter,
					onLeave: list.onLeave,
					callback: list.controller,
					onDestroy: list.onDestroy
				}
			]
		}
	},
	{
		path: '/d',
		getTemplate: def.getTemplate,
		onEnter: def.onEnter,
		onLeave: def.onLeave,
		callback: def.controller,
		onDestroy: def.onDestroy,

		children: {
			viewsSelector: '.content',
			cacheViewsNum: 1,
			routes: [
				{
					// sub default route
					path: '/',
					getTemplate: defSub.getTemplate,
					onEnter: defSub.onEnter,
					onLeave: defSub.onLeave,
					callback: defSub.controller,
					onDestroy: defSub.onDestroy
				}
			]
		}
	},
	{ // Nested routes & views! (1.5.0+)
		path: '/b/:bid',
		getTemplate: function(cb) {
			var path = this.path.substr(1);
			setTimeout(function() {
				var lis = '';
				var t;
				// build sub view link
				for (var i = 1; i <= 4; i++) {
					t = path + '/s' + i;
					lis += '<li><a href="' + t + '">/' + t + '</a></li>';
					// or: (looks like set `enablePushState:false`, do not change `location`)
					// lis += '<li><a href="#" data-href="' + t + '">/' + t + '</a></li>';
				}
				cb(
					'<ul class="nav">' + lis + '</ul>'
				);
			}, 200);
		},
		callback: function() {
			console.log('callback:/b', this, arguments);
		},
		onDestroy: function() {
			console.log('destroy:/b', this, arguments);
		},

		children: { // config for nested routes & views! (1.5.0+)
			/* these configs, default inherit form parent config */
			viewsSelector: '',
			viewClass: 'sub-view-b',
			maskClass: 'mask',
			showLoading: true,
			cacheViewsNum: 3,
			cacheTemplate: true,
			animation: true,
			aniClass: 'slide',

			routes: [
				{
					path: '/:subB', // '/b/:bid/:subB'
					/* config for current sub route */
					cacheTemplate: false,
					animation: true,
					aniClass: 'slideup',
					getTemplate: function(cb) {
						var that = this;
						setTimeout(function() {
							cb('<div>' + that.path + '<p>sub content</p></div>');
						}, 200);
					},
					callback: function() {
						console.log('sub callback b', this, arguments);
					},
					onDestroy: function() {
						console.log('sub destroy b', this, arguments);
					}
				}
			]
			
		}
	}
], {
	/** Global configs  */
	/*cache tempaltes or not*/
	cacheTemplate: true,

	/*views container's selector. Default document.body*/
	viewsSelector: '',

	/*view class. Each page view will have a default class `page-view`, the `viewClass` option's value will be appended to the page view element's class */
	viewClass: 'page-view',

	/*use animation or not*/
	animation: true,
	/*switching effects*/
	aniClass: 'slide',

	/*mask class for loading*/
	maskClass: 'mask',
	/*show loading or not*/
	showLoading: true,

	/*cache views number. Default 3*/
	cacheViewsNum: 3
});

// Or like this
M.router.add('/ddd/{dddID:int}', function(dddID) {
	// callback
}, { // options
	cacheTemplate: true,
	getTemplate: function() {
		return '/ddd/' + this.params.dddID;
	},
	onDestroy: function() {
		// destroy
	}
});

/* global route change events */
/* `routeChangeStart` event, trigged before a route change. */
M.router.on('routeChangeStart', function(currentRouteState) {
	
});
/*`routeChangeEnd` event, trigged after a route changed and the page has been shown.*/
M.router.on('routeChangeEnd', function(currentRouteState) {
	
});

//  start history
M.history.start({
	base: '/', // base path of history. Default the url base in the head of your main html file (<base href="/my-base">) or '/'
	enablePushState: true, // enable pushstate or not (less that 2.x)
	// (2.0.0+)
	// set `history`, `hashbang` or `abstract`
	// default `hashbang` 
	history: true,
	// or
	hashbang: true,
	// or
	abstract: true
});

Advantages?

  • Lightweight, Easy.

  • Nested routes & views (1.5.0+).

  • No Dependencies. You can use it with jquery, zepto, iscroll or others.

  • Cache templates automatically.

  • Good for SEO. You can render pages on server.

  • Cache pages automatically. Default cache pages number is 3.

  • Switching pages use CSS animation.

  • History mode: history, hashbang or abstract

About some configs

The priority of get animation, aniClass or cacheTemplate config's value is:

`data-xxx` -> route config -> global config

About examples/

  • index.html: basic usage, getTemplate config, and data-rel=back attribute config on link element for reverse animation direction.

  • index1.html: link element's data-href attribute config (as same as abstract=true) , and disable one route animation.

  • index2.html: disable animation.

  • index3.html: disable cacheTemplate.

  • index4.html: set global aniClass.

  • index5.html: set aniClass in two ways.

  • index6.html: set cacheTemplate of one route.

  • index7.html: set M.history config abstract=true.

  • index8.html: nested routes and views.

  • requirejs/: use require.js

About SEO

The server can response HTML with cpmplete content

<div class="page-view"><h2>content rendered by the server</h2></div>

License

The MIT License