Skip to content

Commit 11ec16e

Browse files
committed
Merge pull request #2 from zhangxinxu/develop
Develop
2 parents 401e07b + ba4e87a commit 11ec16e

File tree

8 files changed

+180
-27
lines changed

8 files changed

+180
-27
lines changed

ReadMe.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ mobilebone.js
4949
类原生APP的过场体验,适用于这些场景:<br>
5050
1. Phonegap等类似跨移动开发平台,其静态页面都是index.html, 单页面,因此,需要跟原生一样的过场体验。<br>
5151
2. Hybird app开发,原生APP内嵌web APP, 为了两者体验一致,不至于交互太唐突,也需要无刷新过场效果。<br>
52-
3. 就算是纯粹的移动web APP, 使用无刷新模式也不失为一种不错的选项策略
52+
3. 就算是纯粹的移动web APP, 使用无刷新模式也不失为一种不错的选型策略
5353

5454

5555
如何使用?

plugins/ppt/index.html

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
6+
<title>ajax请求HTML</title>
7+
<link rel="stylesheet" href="../../src/mobilebone.css">
8+
<link rel="stylesheet" href="ppt.css">
9+
</head>
10+
11+
<body>
12+
<div id="page1" class="page out">
13+
<div class="content section-header">
14+
<h1>mobilebone.js</h1>
15+
<h2>mobile移动web APP单页切换骨架</h2>
16+
</div>
17+
</div>
18+
<div id="page2" class="page out">
19+
<div class="content only-header">
20+
<h1>为何需要?</h1>
21+
<ol>
22+
<li>Phonegap等类似跨移动开发平台,其静态页面都是index.html, 单页面,因此,需要跟原生一样的过场体验。</li>
23+
<li>Hybird app开发,原生APP内嵌web APP, 为了两者体验一致,不至于交互太唐突,也需要无刷新过场效果。</li>
24+
<li>就算是纯粹的移动web APP, 使用无刷新模式也不失为一种不错的选型策略。</li>
25+
</ol>
26+
</div>
27+
</div>
28+
<div id="page3" class="page out">
29+
<div class="content only-header">
30+
<h1>如何使用?</h1>
31+
<pre>&lt;link rel="stylesheet" href="mobilebone.css"></pre>
32+
<pre>&lt;script src="mobilebone.js">&lt;/script></pre>
33+
<pre>body
34+
page
35+
page
36+
page</pre>
37+
</div>
38+
</div>
39+
<div id="page4" class="page out">
40+
<div class="content only-header">
41+
<h1>优势?</h1>
42+
<p>mobilebone.js只做了一件事情,切换。所以,JS文件很小,gzip后3~4K, 而且很灵活,几乎没有任何UI的限制,适用于各个项目各个场景。</p>
43+
</div>
44+
</div>
45+
<div id="page5" class="page out">
46+
<div class="content section-header">
47+
<h1>Q&amp;A</h1>
48+
<h2>by zhangxinxu 2014-10</h2>
49+
</div>
50+
</div>
51+
<script src="../../src/mobilebone.js"></script>
52+
<script src="mobilebone.ppt.js"></script>
53+
</body>
54+
</html>

plugins/ppt/mobilebone.ppt.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
if (window.Mobilebone && Mobilebone.support) {
2+
(function(window, document, undefined) {
3+
var pages = document.querySelectorAll("." + Mobilebone.classPage),
4+
length_page = pages.length;
5+
index_page = 0,
6+
hash = location.hash.replace("#&", "");
7+
8+
if (hash != "" && hash != "#") [].slice.call(pages).forEach(function(page, index) {
9+
if (page.id == hash) {
10+
index_page = index;
11+
}
12+
});
13+
14+
var prev = function() {
15+
if (index_page > 0) {
16+
index_page--;
17+
Mobilebone.transition(pages[index_page], pages[index_page + 1], true);
18+
}
19+
}, next = function() {
20+
if (index_page < length_page - 1) {
21+
index_page++;
22+
Mobilebone.transition(pages[index_page], pages[index_page - 1]);
23+
}
24+
};
25+
26+
document.addEventListener("click", function(event) {
27+
var target = event.target;
28+
if (target.tagName.toLowerCase() == "a" || target.getParentElementByTag("a")) return;
29+
next();
30+
});
31+
32+
document.addEventListener("keyup", function(event) {
33+
console.log(event.keyCode);
34+
switch (event.keyCode) {
35+
case 38: case 37: {
36+
prev();
37+
break;
38+
}
39+
case 39: case 40: {
40+
next();
41+
break;
42+
}
43+
}
44+
});
45+
46+
document.addEventListener("mousewheel", function(event) {
47+
if (event.wheelDelta > 0) {
48+
prev();
49+
} else {
50+
next();
51+
}
52+
});
53+
document.addEventListener("DOMMouseScroll", function(event) {
54+
if (event.detail > 0) {
55+
next();
56+
} else {
57+
prev();
58+
}
59+
});
60+
})(window, document);
61+
}

plugins/ppt/ppt.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.content { width: 1024px; height: 768px; max-height: 100%; max-width: 100%; line-height: 1.5; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; box-sizing: border-box; padding-left: 50px; padding-right: 50px; font-size: 20px; font-family: 'microsoft yahei'; box-shadow: 0 0 10px rgba(0,0,0,.25); overflow: hidden; }
2+
.section-header { text-align: center; }
3+
.section-header > h1 { position: absolute; top: 50%; left: 0; right: 0; margin: -72px 0 0; font-size: 48px; }
4+
.section-header > h2 { position: absolute; top: 50%; left: 0; right: 0; margin: 42px 0 0; font-size: 28px; color: #666; }
5+
6+
.only-header > h1 { font-size: 36px; margin: 1em 0; }
7+
.only-header > pre { background-color: #eee; font-family: "Lucida Console", Monaco, monospace; padding: .5em; white-space: pre-wrap; word-wrap: break-word; }

src/mobilebone.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ html, body, .page {
3939
.mask {
4040
height: 100%; width: 100%;
4141
background-color: rgba(255,255,255,.35);
42-
overflow: hidden;
4342
position: absolute;
4443
}
4544
.loading { /* more info: http://www.zhangxinxu.com/wordpress/?p=3357 */

src/mobilebone.js

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
// When running inside a FF iframe, calling replaceState causes an error
2929
!( window.navigator.userAgent.indexOf( "Firefox" ) >= 0 && window.top !== window ) &&
3030
( window.navigator.userAgent.search(/CriOS/) === -1 );
31+
32+
Mobilebone.support = supportHistory;
33+
34+
if (supportHistory == false) return Mobilebone;
3135

3236
// similar to $().prop() method, but with a diff rule
3337
var prop = function(element, attribute) {
@@ -84,7 +88,12 @@
8488
* @type string
8589
**/
8690
Mobilebone.classPage = "page";
87-
91+
/**
92+
* className for mark mask element
93+
*
94+
* @type string
95+
**/
96+
Mobilebone.classMask = "mask";
8897
/**
8998
* Whether url changes when history changes
9099
* If this value is false, the url will be no change.
@@ -443,10 +452,10 @@
443452
complete: function() {}
444453
};
445454

446-
var params = {};
455+
var params = {}, ele_mask = null;
447456

448457
// if 'trigger_or_options' is a element, we should turn it to options-object
449-
var params_from_trigger = {};
458+
var params_from_trigger = {}, attr_mask;
450459
if (trigger_or_options.nodeType == 1) {
451460
params_from_trigger = (trigger_or_options.getAttribute("data-params") || "").queryToObject();
452461
// get params
@@ -460,11 +469,16 @@
460469
params[key] = defaults[key];
461470
}
462471
}
463-
params.target = trigger_or_options;
464472
}
465473

466474
// the ajax url is special, we need special treatment
467-
params.url = this.getCleanUrl(trigger_or_options, params.url);
475+
params.url = this.getCleanUrl(trigger_or_options, params.url);
476+
477+
// get mask element
478+
attr_mask = trigger_or_options.getAttribute("data-mask");
479+
if (attr_mask == "true" || attr_mask == "") {
480+
ele_mask = trigger_or_options.querySelector("." + this.classMask);
481+
}
468482
}
469483
// if 'trigger_or_options' is a object
470484
else if (trigger_or_options.url) {
@@ -479,16 +493,20 @@
479493
}
480494

481495
// do ajax
482-
// show loading
483-
var ele_mask = document.querySelector("#ajaxMask");
484-
if (ele_mask) {
485-
ele_mask.style.display = "block";
486-
} else {
487-
document.body.insertAdjacentHTML('beforeend', '\
488-
<div id="ajaxMask" class="mask"><i class="loading"></i></div>\
489-
');
490-
ele_mask = document.querySelector("#ajaxMask");
496+
// get mask and loading element
497+
ele_mask = ele_mask || document.querySelector("body > ." + this.classMask);
498+
if (ele_mask == null) {
499+
ele_mask = document.createElement("div");
500+
ele_mask.className = this.classMask;
501+
ele_mask.innerHTML = '<i class="loading"></i>';
502+
if (typeof attr_mask == "string") {
503+
trigger_or_options.appendChild(ele_mask);
504+
} else {
505+
document.body.appendChild(ele_mask);
506+
}
491507
}
508+
// show loading
509+
ele_mask.style.visibility = "visible";
492510

493511
// ajax request
494512
var xhr = new XMLHttpRequest();
@@ -534,15 +552,23 @@
534552
params.complete.call(params, xhr, xhr.status);
535553

536554
// hide loading
537-
ele_mask.style.display = "none";
555+
ele_mask.style.visibility = "hidden";
538556
}
539557

540558
xhr.onerror = function(e) {
541-
params.message = "Illegal request!";
559+
params.message = "Illegal request address or an unexpected network error!";
542560
params.error.call(params, xhr, xhr.status);
543561
// hide loading
544-
ele_mask.style.display = "none";
562+
ele_mask.style.visibility = "hidden";
545563
}
564+
565+
xhr.ontimeout = function() {
566+
params.message = "The request timeout!";
567+
params.error.call(params, xhr, xhr.status);
568+
// hide loading
569+
ele_mask.style.visibility = "hidden";
570+
};
571+
546572
xhr.send(null);
547573
};
548574

@@ -596,17 +622,17 @@
596622
*
597623
**/
598624
Mobilebone.jsonHandle = function(json) {
599-
return '<p style="text-align:center;">主人,如果你看到我了,说明JSON解析函数未定义!</p>';
625+
return '<p style="text-align:center;">Dear master, if you see me, show that JSON parsing function is undefined!</p>';
600626
},
601627

602628
/**
603629
* Initialization. Load page according to location.hash. And bind link-catch events.
604630
**/
605-
Mobilebone.init = function() {
631+
Mobilebone.init = function() {
606632
var hash = location.hash.replace("#&", "#"), ele_in = null;
607633
if (hash == "" || hash == "#") {
608634
this.transition(document.querySelector("." + this.classPage));
609-
} else if ((ele_in = document.querySelector(hash)) && ele_in.classList.contains(this.classPage)) { // 'ele_in' must be a page element
635+
} else if (/&/.test(hash) == false && (ele_in = document.querySelector(hash)) && ele_in.classList.contains(this.classPage)) { // 'ele_in' must be a page element
610636
this.transition(ele_in);
611637
} else {
612638
// as a ajax
@@ -634,7 +660,7 @@
634660
Mobilebone.handleTapEvent = function(event) {
635661
// get target and href
636662
var target = event.target || event.touches[0], href = target.href;
637-
663+
638664
if (!href && (target = target.getParentElementByTag("a"))) {
639665
href = target.href;
640666
}
@@ -643,6 +669,10 @@
643669

644670
if (self_page == null || !target) return;
645671

672+
// if mask element exist and displaying, prevent double trigger
673+
var ele_mask = target.getElementsByClassName(Mobilebone.classMask)[0];
674+
if (ele_mask && ele_mask.style.visibility != "hidden") { return; }
675+
646676
// if captureLink
647677
var capture = (Mobilebone.captureLink == true);
648678
// get rel

test/ajax-html/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
<li><a href="ajax-page.html">点击加载(缓存,若后2项已请求,则无请求)</a></li>
1515
<li><a href="ajax-page.html" data-reload>点击加载(每次都请求, 返回含page结构)</a></li>
1616
<li><a href="ajax-page.html?&&" data-reload>点击加载(同上, url过滤测试)</a></li>
17-
<li><a href="ajax-page.html?a" data-reload data-formdata="?a=1">点击加载(data-formdata测试)</a></li>
18-
<li><a href="ajax-page.html?a=1&" data-reload data-formdata="&c=1">点击加载(data-formdata测试)</a></li>
19-
<li><a href="ajax-page.html?a=1&b=" data-reload data-formdata="c=1&d=1">点击加载(data-formdata测试)</a></li>
17+
<li><a href="ajax-page.html?a" data-reload data-formdata="?a=1">点击加载(data-formdata测试)-全覆盖loading</a></li>
18+
<li><a href="ajax-page.html?a=1&" data-reload data-formdata="&c=1" data-mask="true">点击加载(data-formdata测试)-内覆盖loading</a></li>
19+
<li><a href="ajax-page.html?a=1&b=" class="follow" data-reload data-formdata="c=1&d=1" data-mask="true">点击加载(data-formdata测试)-跟随loading</a></li>
2020
</ul>
2121
<ul>
2222
<li><a href="ajax-without-page.html">点击加载-返回不含page, 自动创建page</a></li>

test/test.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
body { font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif; color: #333; }
22
ul { padding-left: 0; list-style-type: none; }
33
a { text-decoration: none; color: inherit; }
4-
li > a { display: block; line-height: 32px; padding-left: .5em; margin-top: -1px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; box-shadow: inset 0 1px #fbfbfb; background-color: #eee; }
4+
li > a { display: block; line-height: 32px; padding-left: .5em; margin-top: -1px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; box-shadow: inset 0 1px #fbfbfb; background-color: #eee; position: relative; }
5+
a:not(.follow) > .mask { left: 0; top: 0; }
6+
.follow > .mask { display: inline; width: 32px; height: 32px; background-color: transparent; }
57
.page > a[data-rel="back"] { display: inline-block; line-height: 32px; margin: .5em; padding: 0 1em; border: 1px solid #ccc; border-left: 0; border-radius: 0 3px 3px 0; background-color: #eee; position: relative; left: 13px; }
68
.page > a[data-rel="back"]::before { content:''; width: 23px; height: 23px; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-bottom-left-radius: 3px; background-color: #eee; position: absolute; left: -12px; top: 4px; -webkit-transform: rotate(45deg); transform: rotate(45deg); }
79
.page > h2, .page > p { padding-left: .5em; }

0 commit comments

Comments
 (0)