Fork me on GitHub
单页应用

【单页应用】关于博客园的补发(高清有码)。。。

前言

上周的时候,做了一点单页应用的研究,但是给断了,本来说最近继续的,但是最近有点其它事情给耽搁了,就给忘了。

PS:其实是师傅(http://www.cnblogs.com/aaronjs/)叫我读jquery源码,我给读跪了。。。

最近两天又朋友问怎么还没写,所以有了今天的东西。

这个单页应用的框架问题很多,就是个简单的demo,喜欢的朋友就看看吧,需要源码的可以下载,但是里面的图片资源文件我给删除了,需要的就留言吧。

这次代码增加了本地存储的应用,将model搞出来了,但是不太完善,过段时间再更新吧。

关于博客园

我想说博客园的接口很难用吗???而且全部是xml的,我这里还写了一个后端程序作为转换呢:

复制代码
复制代码
  1 <%@ WebHandler Language="C#" Class="Handler" %>
  2 
  3 using System;
  4 using System.Web;
  5 using System.Net;
  6 using System.IO;
  7 using System.Text;
  8 using System.Collections;
  9 using System.Xml;
 10 
 11 
 12 
 13 public class Handler : IHttpHandler {
 14     
 15     public void ProcessRequest (HttpContext context) {
 16         context.Response.ContentType = "text/plain";
 17         string url = context.Request["url"] != null ?  context.Request["url"].ToString() : ""; 
 18         string sException = null;
 19         string sRslt = null;
 20         WebResponse oWebRps = null;
 21         WebRequest oWebRqst = WebRequest.Create(url);
 22         oWebRqst.Timeout = 50000;
 23         try
 24         {
 25             oWebRps = oWebRqst.GetResponse();
 26         }
 27         catch (WebException ex)
 28         {
 29             sException = ex.Message.ToString();
 30             context.Response.Write(sException);
 31         }
 32         finally
 33         {
 34             if (oWebRps != null)
 35             {
 36                 StreamReader oStreamRd = new StreamReader(oWebRps.GetResponseStream(), Encoding.GetEncoding("utf-8"));
 37                 sRslt = oStreamRd.ReadToEnd();
 38                 oStreamRd.Close();
 39                 oWebRps.Close();
 40             }
 41         }
 42 
 43         XmlDocument doc = new XmlDocument();
 44      
 45         doc.InnerXml = sRslt;
 46         // Convert XML to a JSON string
 47         string JSON = XmlToJSON(doc);
 48 
 49         // Replace \ with \\ because string is being decoded twice
 50         //JSON = JSON.Replace(@"\", @"\\");
 51 
 52         context.Response.Write(JSON);
 53         
 54     }
 55     private static string XmlToJSON(XmlDocument xmlDoc)
 56     {
 57         StringBuilder sbJSON = new StringBuilder();
 58         sbJSON.Append("{ ");
 59         XmlToJSONnode(sbJSON, xmlDoc.DocumentElement, true);
 60         sbJSON.Append("}");
 61         return sbJSON.ToString();
 62     }
 63 
 64     //  XmlToJSONnode:  Output an XmlElement, possibly as part of a higher array
 65     private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName)
 66     {
 67         if (showNodeName)
 68             sbJSON.Append("\"" + SafeJSON(node.Name) + "\": ");
 69         sbJSON.Append("{");
 70         // Build a sorted list of key-value pairs
 71         //  where   key is case-sensitive nodeName
 72         //          value is an ArrayList of string or XmlElement
 73         //  so that we know whether the nodeName is an array or not.
 74         SortedList childNodeNames = new SortedList();
 75 
 76         //  Add in all node attributes
 77         if (node.Attributes != null)
 78             foreach (XmlAttribute attr in node.Attributes)
 79                 StoreChildNode(childNodeNames, attr.Name, attr.InnerText);
 80 
 81         //  Add in all nodes
 82         foreach (XmlNode cnode in node.ChildNodes)
 83         {
 84             if (cnode is XmlText)
 85                 StoreChildNode(childNodeNames, "value", cnode.InnerText);
 86             else if (cnode is XmlElement)
 87                 StoreChildNode(childNodeNames, cnode.Name, cnode);
 88         }
 89 
 90         // Now output all stored info
 91         foreach (string childname in childNodeNames.Keys)
 92         {
 93             ArrayList alChild = (ArrayList)childNodeNames[childname];
 94             if (alChild.Count == 1)
 95                 OutputNode(childname, alChild[0], sbJSON, true);
 96             else
 97             {
 98                 sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
 99                 foreach (object Child in alChild)
100                     OutputNode(childname, Child, sbJSON, false);
101                 sbJSON.Remove(sbJSON.Length - 2, 2);
102                 sbJSON.Append(" ], ");
103             }
104         }
105         sbJSON.Remove(sbJSON.Length - 2, 2);
106         sbJSON.Append(" }");
107     }
108 
109     //  StoreChildNode: Store data associated with each nodeName
110     //                  so that we know whether the nodeName is an array or not.
111     private static void StoreChildNode(SortedList childNodeNames, string nodeName, object nodeValue)
112     {
113         // Pre-process contraction of XmlElement-s
114         if (nodeValue is XmlElement)
115         {
116             // Convert  <aa></aa> into "aa":null
117             //          <aa>xx</aa> into "aa":"xx"
118             XmlNode cnode = (XmlNode)nodeValue;
119             if (cnode.Attributes.Count == 0)
120             {
121                 XmlNodeList children = cnode.ChildNodes;
122                 if (children.Count == 0)
123                     nodeValue = null;
124                 else if (children.Count == 1 && (children[0] is XmlText))
125                     nodeValue = ((XmlText)(children[0])).InnerText;
126             }
127         }
128         // Add nodeValue to ArrayList associated with each nodeName
129         // If nodeName doesn't exist then add it
130         object oValuesAL = childNodeNames[nodeName];
131         ArrayList ValuesAL;
132         if (oValuesAL == null)
133         {
134             ValuesAL = new ArrayList();
135             childNodeNames[nodeName] = ValuesAL;
136         }
137         else
138             ValuesAL = (ArrayList)oValuesAL;
139         ValuesAL.Add(nodeValue);
140     }
141 
142     private static void OutputNode(string childname, object alChild, StringBuilder sbJSON, bool showNodeName)
143     {
144         if (alChild == null)
145         {
146             if (showNodeName)
147                 sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
148             sbJSON.Append("null");
149         }
150         else if (alChild is string)
151         {
152             if (showNodeName)
153                 sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
154             string sChild = (string)alChild;
155             sChild = sChild.Trim();
156             sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
157         }
158         else
159             XmlToJSONnode(sbJSON, (XmlElement)alChild, showNodeName);
160         sbJSON.Append(", ");
161     }
162 
163     // Make a string safe for JSON
164     private static string SafeJSON(string sIn)
165     {
166         StringBuilder sbOut = new StringBuilder(sIn.Length);
167         foreach (char ch in sIn)
168         {
169             if (Char.IsControl(ch) || ch == '\'')
170             {
171                 int ich = (int)ch;
172                 sbOut.Append(@"\u" + ich.ToString("x4"));
173                 continue;
174             }
175             else if (ch == '\"' || ch == '\\' || ch == '/')
176             {
177                 sbOut.Append('\\');
178             }
179             sbOut.Append(ch);
180         }
181         return sbOut.ToString();
182     }
183     public bool IsReusable {
184         get {
185             return false;
186         }
187     }
188 
189 }
复制代码
复制代码

因为博客园没有手机端,所以简单做了一个,真的非常简单啊。。。

多上一张图:

 

 

 

 

 

 

 

 

功能一览

其实说白了就只有一个博客页与博客详情页了

博客页

其中滚动会分页:我们来看看我们的数据吧:

核心代码:

复制代码
 View Code
复制代码

对应两个模板页

复制代码
 1 <input class="login" type="button" value="点击登录" />
 2 <header>
 3     <b class="icon_home i_bef" id="js_home"></b>
 4     <h1>
 5         博客园</h1>
 6     <i id="js_return" class="returnico"></i>
 7 </header>
 8 <section class="cont_wrap" style="margin: 17px 0 40px;">
 9     <ul class="pro_list" id="lstbox">
10     </ul>
11 </section>
12 <ul class="tab_search fix_bottom">
13     <li class="tabcrt">博客</li>
14     <li class="tab_hotel ">新闻</li>
15     <li class="tab_hotel ">48小时</li>
16     <li class="tab_hotel ">推荐</li>
17 </ul>
复制代码
复制代码
 1 <li class="arr_r orderItem" data-id="<%=id %>">
 2     <article class="blog_item">
 3         <h3>
 4             <a href="<%=link.href %>" target="_blank"><%=title.value || '无题' %></a>
 5             </h3>
 6             
 7         <div class="author pro_list_rank">
 8             <%if(author.avatar){ %>
 9             <a href="<%=author.uri %>" target="_blank">
10                 <img src="<%=author.avatar %>">
11             </a>
12             <%} %>
13             JavaScript 是根据 "ECMAScript"标准制定的网页脚本语言。这个标准由 ECMA 组织发展和维护。ECMA-262 是正式的 JavaScript标准。JavaScript是目前Web客户端开发的主要编程语言,也是Ajax的核心技术之一。
14         </div>
15         <div class="item_footer">
16             <a href="<%=author.uri %>" class="lightblue">Scut</a> <%=published %> <a href="<%=link.href %>" title="2013-08-21 15:21" class="gray">评论(<%=comments %>)</a>
17             <a href="<%=link.href %>" class="gray">阅读(<%=views %>)</a> <span class="price1">推荐(<%=diggs %>)</span></div>
18     </article>
19 </li>
复制代码

然后就是详情页了

详情页

复制代码
 1 define(['$', '_', 'cBase', 'cView', getViewPath('detail'), getViewPath('detail_article'), 'blogModel', 'blogStore'], function ($, _, b, v, html, itemTpt, model, store) {
 2 
 3     var model = model.blog.getInstance();
 4     var blogStore = store.blog.getInstance();
 5     var tpl = _.template(itemTpt);
 6 
 7     var View = b.Class(v.PageView, {
 8         _propertys_: function () {
 9         },
10         init: function (superInit, request, interface) {
11             superInit(request, interface);
12             console.log('init');
13         },
14         createHtml: function () {
15             return html;
16         },
17         attrs: {
18         },
19         events: {
20             '#js_return,click': function () {
21                 this.forward('index');
22             }
23         },
24         onCreate: function () {
25             console.log('onCreate');
26 
27         },
28         _loadData: function () {
29             var box = this.find('.cont_wrap');
30             box.html('');
31             var param = { url: 'http://wcf.open.cnblogs.com/blog/post/body/' + blogStore.get().id }
32             $.get('Handler.ashx', param, function (data) {
33                 (typeof data === 'string') && (data = $.parseJSON(data));
34                 data && data.string && (blogStore.setAttr('value', data.string.value));
35                 var d = blogStore.get();
36                 box.append(tpl(d));
37                 var ss = '';
38             });
39         },
40         //dom创建后数据加载时执行,用于加载后执行我们的逻辑
41         onLoad: function () {
42             console.log('onLoad');
43         },
44         //dom创建后,未显示
45         onShow: function () {
46             console.log('onShow');
47             this._loadData();
48 
49         },
50         //dom隐藏前
51         onHide: function () {
52             console.log('onHide');
53         }
54     });
55 
56     return View;
57 });
复制代码

其中模板各位自己下载看吧。

结语

之前已经详细描述了整个代码逻辑这次就不说了,各位觉得不错可以下载下来看看,后面点还会更新。

源码

https://files.cnblogs.com/yexiaochai/page.zip(page.zip

 

 
 
标签: 单页应用
posted on 2013-08-22 21:50  HackerVirus  阅读(246)  评论(0编辑  收藏  举报