TableGrid






4.80/5 (2投票s)
Google+ 帖子标题和标签列表。
引言
在 Google+ 上发帖后,我发现没有简单的方法来搜索包含特定标签的帖子。我的想法是列出 Google+ 帖子的标题和标签。
通过此界面,用户可以看到我所有帖子的标题以及标签,因此可以相对容易地通过列表关注某个主题。
该项目包含一个简单的 HTML UI,使用 JavaScript 构建和填充;JSON 数据用于保存标题和标签;将来可以开发它以使用 Google+ API 动态获取一些数据。[但对 Google+ API 的快速查看让我相信无法以简单的格式生成我所需的数据。因此,对于这个项目,我计划首先手动输入数据,但其格式可以通过自动化从合适的来源复制,因此使用了 JSON。]
核心任务是创建一个可以为表格或网格生成 HTML 的行构建器。因此,主类名为 TableGrid
。但是,其中包含了一些辅助函数。
当前项目使用此类别构建 UI,并使用 CCS 样式。
git 仓库在 GitHub 上,以下标签对应于本文
背景
[如果您只对代码感兴趣,可以跳过此部分。]
CodeProject 有很多很棒的文章,参与其中似乎是巩固知识的好方法。但是,在撰写自己的文章时,似乎很难直接将其发展到符合 Codeproject 要求。我需要一个循序渐进的过程。
偶尔,我可能会找到一个关于我收集了一些信息的 Stackoverflow 问题,然后我可以将我的笔记作为答案发布。[尽管问答流通常就像走进风洞。]
然后我开始在 Google+ g+ 上发帖,在那里你可以随意发布琐碎或复杂的帖子,并根据需要多次重新编辑。因此,这些想法并没有因为不适合写文章而被放弃,而是开始填满 g+。
我现在已经绕了一圈,因为我将描述一个从小项目,这个项目源于我试图控制我的 g+ 帖子。
文章内容
该项目包含以下文件
- HtmlTools.js - 包含一个用于构建表格和网格并从数据填充它们的类
TableGrid
- googlePostsList.html - 这是一个简单的网页,用于演示此项目中的 UI
- googlePostsList.css - 附带的 CSS
- codeBehind.js - 在此演示中使用
TableGrid
类 - Data.js - 包含此示例的 JSON 数据
尽管这不是一个困难的项目,但它涉及多个主题。为了在这篇文章中单独考虑这些主题,将首先描述前端 UI 和样式。然后讨论数据需求,接着是 TableGrid
类及其开发。
用户界面和样式
图 1a 展示了 HTML 和 CSS 的最终渲染。HTML 结构是交替的 div
,因此它们可以形成两列或一堆交替的标签和标题。
清单 1a:单个帖子的 html
<div class="list_container">
<div class="post_tags">
<span class="hashtag_button">hashtag1</span>
<span class="hashtag_button">hashtag2</span>
</div>
<div class="post_title">
<a href="https://...">
Title</a>
</div>
</div>
在 CSS 中,为了获得 div
所需的布局行为,它们的 display
属性设置为 inline-block
,并且通过增加第二个 div
中的 line-height
来实现在两种排列中每个帖子下方的空白区域的位置。
.post_tags {
display: inline-block;
vertical-align: top;
}
.post_title {
display: inline-block;
line-height: 22px;
...
}
标签和标题的外观(在 CSS 类 hashtag_button
和 post_title>a
中设置)被设置为使列表项看起来与 Google+ 相似。
.hashtag_button {
background-color: #EEE;
border-color: #DDD;
...
}
.post_title>a {
color: #404040;
font-style: italic;
...
}
请注意,hashtag_button
完全专注于这种外观,因此与容器类 post_tags
分离。
hashtags
在 div
类 post_tags
内部形成一个水平堆栈,text-align
的值控制堆栈方向。然后在响应式布局更改部分——其中也定义了各种 width
设置——text-align
的行为针对每种布局设置不同。
对于像图 1a 这样的全尺寸,这是默认值。
.post_tags {
text-align: right;
width: 30%
}
对于像图 2a 这样的小尺寸,由媒体规则控制。
@media screen and (min-width:0em) and (max-width:40em){
...
.post_tags {
text-align: left;
width: 100%;
}
...
}
Data
图 1a 中的 UI 示例显示了每个帖子所需的一些数据
标签
title
此外,UI 使用帖子标题作为超链接,帖子的 URL 作为链接。
- Google 帖子网址
在 Google+ 上关注一个标签,它会被添加到基本 URL 中
- plus.google.com/explore/
例如:plus.google.com/explore/hashtag [注意:此链接在当前示例中未实现。] 这不需要为每个帖子提供额外的数据,因此单个帖子的 JSON 数据格式如下。
清单 2a:单个的 JSON 数据
{ tagList: ["tag1", "tag2"],
title: "Title of post",
link:"https:\\ ... "
}
因此,每个帖子的数据都作为数组中的一个元素存储。
TableGrid
正如引言中所述,后台代码的要求是从数据行构建 HTML 列表。这是一项常见的任务,有许多解决方案,本解决方案在浏览器中使用 JavaScript,利用专门用于此任务的 TableGrid
类来完成此操作。
我已经展示了我想要在这里使用的特定数据,但我真的想最大限度地提高我正在开发的代码的可重用性,以及我可以处理的数据。为了确定最佳架构,我们将比较层次结构和简单的二维表。
从最简单的开始,例如动物列表,可以将其渲染为 HTML 表格中的列表,每行都会生成一个如下所示的项
<tr> <td> dog </td> </tr>
此示例中的某些功能可以在一般情况下重复使用。
- 遍历数据行
此外,表格行总是以相同的序列 <tr> ... </tr>
开始和结束。这种行的包装也可以在更复杂的结构中分离。
- 将行的包装与数据格式化分开。
然而,在这种情况下数据的处理是微不足道的,仅仅用 <td>数据</td>
包装数据,但这通常是不够的。我们还希望能够处理各种类型的数据,从单个字符串和数组到更复杂的层次结构,并将它们添加到表格或其他结构中。
接下来考虑一个更复杂的例子。例如前面建议的使用 JSON 数据,它允许分层数据集。那么问题就是找到一个既能满足简单例子又能满足复杂例子的模式。此外,我们需要能够构建比简单表格更复杂的结构。我选择让开发人员定义一个函数,该函数将数据行作为变量接收,然后可以构建任何结构。
- 可自定义函数,将数据行转换为格式化输出。
从上述要求推导出的模式如图 3a 所示。
为了演示这一点,我们将继续这个例子。从清单 1a 中我们可以看到,每一行都以 <div class="list_container">
作为前缀,以 </div>
作为后缀。然后,内部包含数据的元素可以从清单 2a 中的 JSON 数据在自定义行构建器函数中构建,该函数在遍历行时被调用。
function myLineBuilder(data){
s = '\n\t<div class="post_tags">\n\t\t'
s += HtmlBuilder_wrapArray(data.tagList,
' <span class="hashtag_button">', '</span>')
s += '\n\t</div>'
s += '\n\t<div class="post_title">'
s += '\n\t\t<a href="'+data.link+'/">'
s += '\n\t\t'+data.title+'</a>'
s += '\n\t</div>'
return s
}
请注意,HtmlBuilder_wrapArray
函数是 HtmlTools.js 中包含的一个辅助函数,此处用于为 hashtags
数组 data.tagList
生成 span
标签。
现在我们可以将这些插入到 TableGrid
中
tg = new TableGrid()
tg.setLineBuilder( myLineBuilder,
'\n<div class="list_container">', '\n</div>')
然后进行构建并请求结果
tg.buildRows(myPostList)
htmlString = tg.getBlock()
其中 myPostList
是每个帖子的数据行数组。
实现 TableGrid
的代码是
function TableGrid(){
this.linebuilder
this.linePrefix
this.lineSuffix
this.block=""
this.setLineBuilder=function(lb,pre,suf){
this.linebuilder=lb
this.linePrefix=pre
this.lineSuffix=suf
this.block = ""
}
this.buildRows=function(table){
//will loop over the top layer and pass each item to line builder
for(var i=0; i<table.length; i++){
tg.buildLine(table[i])
}
}
this.buildLine=function(data){
//prefix line
s = this.linePrefix
//run the line builder callback
s += this.linebuilder(data)
//suffix line
s += this.lineSuffix
this.block += s
}
this.getBlock=function(){ return this.block; }
}
用法回顾
- 构建数据结构
- 设计数据的 HTML 视图
- 将 HTML 结构分解为行包装器、行内容和表格包装器
- 编写行构建器
- 初始化
TableGrid
- 完成此操作后,数据即可发送到
TableGrid.buildRows
TableGrid
的实例本身可以通过发送新的数据集来重复使用。
显然,对于构建简单的表格,这导致了一个相对复杂的方法。为了保持简单性,为简单表格提供了创建函数。这还有一个额外的好处,即这些预定义的类实例也可以用于测试。本文不再赘述,但已在上传的项目中。
摘要
此项目涉及少量 HTML、JavaScript、JSON、CCS。
感谢阅读,请留下评论。
历史
- 版本 1