您是否了解HTML和CSS,并能够创建简单(并非如此)的静态网页,但希望为它们带来更多的“生命”和交互性? 您有想要与世界分享的作品(绘画,照片,诗歌,邮票集等),但是您无法创建投资组合网站或博客,而无需额外的努力即可发布和更新它们。 ? 还是您梦想保留旅行者的日记,收集不寻常的烹饪食谱,跟踪健身活动并在自己的网站上在线进行所有这些操作? 也许您有喜欢的宠物,需要特殊的护理程序,并且必须对其进行跟踪和快速记录?
但是,提到JavaScript会使您陷入轻松(有时不是这样)的动荡之中,而为了实现自己的想法而需要掌握的许多技术和概念会使您感到困惑和绝望? 结果,你问自己:“为什么网络编程如此困难? 真的不可能想出些什么来简化它吗?”
然后您来对地方了。 阅读本文之后,您将获得一个借助该工具的工具,我敢肯定,即使不是全部,您也可以意识到您的许多想法,与上面列出的想法类似。
原始图片的作者:Mart Virkus(toggl.com)经验丰富且经验丰富的前端开发人员,不要急着结束这篇文章,因为现在这里将有一些东西可以“吸引”新来者,而您在这里无所事事。 我相信您也可以学到一些对自己有用的东西。 要记住的主要事情:如果对于初学者来说简单的事情变得简单,那么对所有人来说都会变得简单! 因此,在某种程度上,它将简化您的生活。 这还不错,同意吗?
所以到了重点! 本文将专门讨论
Mavo 。
Mavo是
仅通过编写HTML和CSS即可开发交互式Web应用程序的新方法,而无需编写JavaScript代码和部署您自己的服务器。
Mavo由麻省理工学院(
MIT CSAIL )计算机科学和人工智能实验室的
Haystack小组的科学家开发,由
Leah Veru领导。
跟随白兔子!
想更多地了解什么是Mavo的基础,他吸收了Mavo的前辈的哪些特征,他发展了哪些,他不得不放弃了哪些以及为什么? 然后,我强烈建议您阅读这两份出版物,这些出版物是为专门讨论人机交互领域的年度论坛而专门准备的-ACM用户界面软件和技术研讨会(UIST) :
- Mavo:通过编写HTML创建交互式数据驱动的Web应用程序 。
- 通过数据更新操作扩展反应性表达语言,以进行最终用户应用程序创作 。
俄罗斯读者的一个小题外话!
Mavo网站托管在Netlify服务器上,由于与Telegram Messenger发生“战争”,其地址被列入黑名单。 这意味着托管在这些服务器上的资源以及所有相关服务在俄罗斯已被阻止 (至少在撰写本文时)。
但是,有个好消息: Lea Verou和我正在积极努力解决这个问题。 我希望我们也能尽快解决。 在此之前,请例如使用VPN与Mavo配合使用(在访问Mavo网站,研究Codepen上的演示以及创建自己的Web应用程序时都是如此)。
(更新)那些尚未准备就绪和/或不想连接到VPN的用户可以在Stackblitz上玩Mavo或通过cdnjs将其连接到他们的项目。
我坚信(而且我并不孤单),“感受”一项新技术并评估其功能的最佳方法是在其帮助下构建有用的东西。 不是很困难,否则我们可能只是看不到树后的森林,而是必要的。 剩下的只是选择什么。 喔! 有一个主意。
我认为你们中的许多人正在学习外语(也许对于某人这是一门编程语言)。 而且,很可能您会使用某种应用程序进行研究。 通常使用抽认卡学习这些应用程序中的新单词。 顺便说一句,这种学习外语的技术在离线时也很有效。 但是,现在还不行。
那么,为什么我们不一起开发这样的应用程序呢? 让我们称之为...(鼓!)
“卡” 。 这将是一个成熟的
CRUD应用程序,用于借助卡片来学习外语,这将允许:
- 创建,删除,修改卡片,以及使用拖放操作组织卡片;
- 从文件将卡导入应用程序并将其导出到文件;
- 跟踪进度(自我评估功能)。
该应用程序的最终版本将如下所示:
好吗 我希望如此。 那就走!
在整篇文章中,我将指导您完成应用程序开发的所有阶段。 在阅读时,您会遇到标有特殊标签的片段。
跟随白兔子!
以这种方式标记的片段包含有关Mavo的重要但附加的信息。 初读时,可以跳过这些片段而不会害怕错过主要思想。
实践是通往卓越的道路!
在某些部分的结尾,我将为您提供一些小型的独立练习,通过执行这些练习,您可以更好地了解Mavo的功能,同时改善正在开发的应用程序。 这样的练习将适合这些片段。
用手记住!
您准备好按照我的阐述思路,立即将新知识应用到实践中吗? 太好了! 毕竟,正如您所知, 我们最好记住我们的双手 。 您可以通过从头到尾阅读文章来逐步开发应用程序,或者可以从您感兴趣的任何阶段开始。
此类片段将提供指向Codepen上应用程序相应版本的链接。
现在就全部了。 让我们开始吧!
静态网页
为了说明Mavo如何扩展HTML的功能,我们将创建一个静态HTML页面,然后将使用Mavo将其转换为功能全面的Web应用程序。
假设我们在
<body>元素中包含以下HTML:
<header> <h1></h1> </header> <main> <article> <p> </div> <p></div> </article> </main>
在上面的代码段中,
<article>元素对应于一张卡。
我们将添加一些样式,使我们的页面更像将来的应用程序:
想完整地查看源代码吗? 你可以在
这里做。
我们连接Mavo
到目前为止,我们只有静态布局。 现在是时候将其转变为成熟的Web应用程序了。 这就是Mavo发挥作用的地方!
要使用Mavo,我们需要将其JavaScript和CSS文件连接到我们的页面。 为此,将以下两行添加到
<head>元素:
<head> ... <script src="https://get.mavo.io/mavo.min.js"></script> <link rel="stylesheet" href="https://get.mavo.io/mavo.css"> ... </head>
俄罗斯读者的一个小题外话!
您可以从Mavo存储库下载相应的文件,并以相同的方式将它们连接到页面。
(更新)您还可以通过cdnjs将Mavo连接到您的项目。
跟随白兔子!
也许您的应用程序应该可以在旧版浏览器中正常运行? 还是您希望能够窥探Mavo源代码并期望它具有可读性? 一切都在您手中。 您可以通过回答一些简单的问题来微调您要使用的Mavo的内部版本和/或版本 。
连接了Mavo之后,我们需要指定哪个页面元素将包含我们将来的应用程序。 这样的元素可以是任何HTML元素,甚至
<body>或
<html> ! 我们需要将
mv-app属性添加到此元素,并指定应用程序
名称作为其值-整个HTML页面中的唯一标识符。 具有
mv-app属性的
元素称为
应用程序的
根元素 。
跟随白兔子!
如果您没有为mv-app属性分配值,并且同一元素中没有任何属性: id或name ,-Mavo将自动为应用程序分配名称mavo1 , mavo2等。
但是,我强烈建议您显式指定应用程序的名称,因为它在应用程序的其他位置(显式和隐式)使用。
用手记住!
https://codepen.io/dsharabin/pen/PoYxNjN
因此,在我们的案例中,
<main>元素将包含将来的应用程序。 向其中添加
mv-app属性,并指定应用程序的名称-
闪卡作为其值:
<main mv-app="flashcards"> ... </main>
属性属性
现在是时候告诉Mavo应用程序的哪些元素很
重要了 ,也就是说,它们将被编辑和/或保存,也可以在
表达式中使用 (但稍后会介绍-请耐心等待)。
到目前为止,在我们的应用程序中,有两个这样的元素-这些是
<p>元素。 将
property属性添加到这些元素,通知Mavo这些元素包含您需要使用的数据。 具有
property属性的元素称为
properties 。
跟随白兔子!
可以将property属性添加到任何 HTML5元素中-Mavo知道如何使其可编辑 。 例如,您可以使用键盘手动编辑<span>元素的内容,并可以使用相应的小部件设置<time>元素的值(日期或时间)。
Mavo使元素可编辑的规则集可以使用插件轻松扩展。 用户是否有必要使用类似于Microsoft®Wordpad或Microsoft®Word之类的程序的工具栏来格式化文本,也就是说,像在任何WYSIWYG编辑器中一样使用文本? 还是要允许用户使用Markdown语言命令输入? 没有任何限制。 只需激活相应的插件即可。 没有合适的插件? 没问题 自己写。 Mavo开箱即用地支持相应的功能。
请记住,
属性属性的值必须描述元素的用途,这通常由
id或
class属性的值来描述。
将我们的
<p>元素变成属性:
... <p property="source"> </p> <p property="translation"></p> ...
跟随白兔子!
如果元素已经具有可以准确描述其目的的id , class或itemprop属性 ,则可以将property属性保持不变 。 例如,我们的应用程序的属性之一可以描述如下: <p property class="source">
。
向其添加属性后,您是否注意到我们的应用程序有任何更改? 我肯定是的。 在应用程序的顶部,带有“
编辑”按钮的Mavo工具栏(
Mavo栏 )出现了。 使用此按钮可以在两种应用程序模式之间切换:
读取 模式和
编辑模式 。 现在我们的应用程序处于读取模式。 这意味着我们不能直接在浏览器窗口中编辑其数据。
跟随白兔子!
Mavo工具栏是完全可定制的 (就像Mavo自动添加到应用程序中的所有界面元素一样):您可以更改其位置,外观,指定一组可用的按钮,甚至可以为其分配自己的HTML元素。
稍后,我们将看到用于自定义Mavo工具栏的选项之一。 同时,如果您想了解有关所描述功能的更多信息,请阅读官方网站上的文档 。
好了,该切换到编辑模式并了解他的时候了。 单击
编辑按钮。
有什么变化? 按钮的名称已更改:现在其名称为
Editing 。 这是对我们的视觉信号:注意,我们处于编辑模式。 尝试将鼠标悬停在带有文字(“单词或短语”或“翻译”)的任何段落上。 Mavo用黄色突出显示告诉我们,您可以单击此片段并进行编辑。
敢! 单击文本并对其进行更改。 那不是很好吗? 我们可以直接在浏览器窗口中编辑页面内容!
实践是通往卓越的道路!
假设除了要研究的单词(或短语)及其翻译之外,我们还希望卡片中包含一个在句子中使用该单词(短语)的示例。 但是我们知道这就是应该教外语的方式-在上下文中,对吗?
通过向其添加缺少的元素并为其命名,例如example来改进应用程序。
Mv-multiple属性
目前,我们的应用程序中只有一张卡。 坦白说,这不是很有用! 对于成熟的应用程序,我们缺乏舒适的能力来添加新卡,删除不必要的卡以及重新排列卡。 但是我们怎么能实现所有这些呢?
用手记住!
https://codepen.io/dsharabin/pen/PoYxNmN
作为应用程序开发人员,我们可以通过在HTML代码中添加更多
<article>元素来为其添加新卡。 但是,用户如何才能自己添加和删除卡呢?
幸运的是,在Mavo中,有一些东西可以让我们向应用程序添加适当的功能一次或两次
-mv-multiple属性。 使用此属性,我们告诉Mavo可以
传播应用程序的哪些元素。
mv-multiple属性将添加了元素的元素转换
为元素的可编辑
集合 (
collection )。 同时,Mavo将为此类集合的元素添加控件,您可以使用它们向集合中添加新元素,删除现有元素以及通过拖放来排列集合中的元素。 是的,这些控件的样式也可以完全自定义!
跟随白兔子!
如果将mv-multiple属性添加到不具有property属性的元素,则Mavo将自动纠正这种情况:使用value 集合 (或collection2 , collection3来保留名称的唯一性)添加属性 。
但是,与应用程序名称一样,我建议您将属性属性与集合一起使用:这样可以保证在更改应用程序数据的HTML结构时的安全性。
好吧,让我们在应用程序的
<article>元素中添加
mv-multiple属性,以将我们唯一的抽认
卡变成完全可编辑的卡片集合(请注意,我们还添加了
property属性):
<article property="flashcard" mv-multiple> ... </article>
跟随白兔子!
Mavo允许您将属性名称指定为mv-multiple属性的值。 因此,我们可以将卡片的收集描述得更短一些: <article mv-multiple="flashcard">
。
请注意,必须将mv-multiple属性添加到要传播的项目中,而不是添加到该集合所在的容器中。 一个非常常见的错误是开发人员编写<ul mv-multiple>
而不是<li mv-multiple>
。 首先,这种错误很难被发现。 直到,例如,应用程序中使用的样式使其变得显而易见为止。
现在随时切换到编辑模式。 是否注意到
卡下方显示了
添加抽认
卡按钮? 让我们为她安排一次试驾:在她的帮助下添加几张新卡片。 这真是令人难以置信:我们可以动态地向应用程序添加新卡,即使其源代码中没有相应的元素也是如此!
跟随白兔子!
注意,将属性属性添加到<article>元素后,其内容是否可编辑? Mavo将此元素视为一个组 。 当将属性属性添加到本身内部包含其他属性的元素(即具有属性属性的元素)时,就会发生这种情况。
但这还不是全部! 将鼠标悬停在任何卡上。 您会看到在卡的右上角,Mavo添加了
三个新按钮 (从左到右):删除卡,添加新卡并移动现有卡。 将鼠标悬停在这些按钮上的任何一个上,您都可以从Mavo产生的背光中轻松猜测它们所指的是哪张卡。
方便吧?
跟随白兔子!
Mavo生成的用于处理收集项目的按钮是完全可定制的 。 例如,您可以通过将mv-drag-handle类添加到相应的HTML元素来创建自己的按钮来移动集合项。
另外请记住,您可以使用键盘与所有按钮进行交互 ,以使用收集项。 例如,将输入焦点放在卡的移动按钮上,然后使用光标键更改卡在集合中的位置。
MV存储属性
用手记住!
https://codepen.io/dsharabin/pen/WNeYwpj
现在已经开发了未来应用程序的主界面,我建议执行以下操作:
- 切换到编辑模式(如果您之前没有这样做)。
- 添加几张卡片,在每张卡片上标明单词及其翻译。
- 返回阅读模式。
- 然后...刷新页面。
! 我们刚刚输入的所有数据都去了哪里? Mavo难道不应该拯救他们吗? 怎么了? 我们哪里出错了?
才冷静! 实际上,我们从未告诉过Mavo
他应该保存可编辑的数据。 而且,我们没有指出他应该
在哪里保存他们。
现在开始吧。 为此,Mavo具有特殊的属性-mv
-storage 。 剩下的只是找出它可以采用的值。 事实证明,Mavo为我们提供了
最广泛的可能性 。 和
插件 -更大!
让我们的应用程序将数据保存在浏览器的本地存储
-localStorage中 。 这是Mavo中最简单的选项,非常适合我们的第一个应用程序。 我们需要做的就是简单地将具有
本地值的
mv-storage属性添加到应用程序的根元素(这是具有
mv-app属性的元素的名称,还记得吗?):
<main mv-app="flashcards" mv-storage="local"> ... </main>
现在看一下Mavo工具栏。 注意到一个新的“
保存”按钮? 除了直接目的-将更改保存到应用程序之外-它还有另一个有用的功能。 尝试再次编辑数据。 请注意,“
保存”按钮现在已
突出显示 。 将鼠标悬停在其上,Mavo将突出显示您已编辑但未保存的数据!
很好,是吗?
单击
保存按钮并刷新页面(无需切换到阅读模式)。 好了,现在您的数据已保存? 太好了! 我们距离完整的Web应用程序仅一步之遥。
MV自动保存属性
现在,我们的应用程序可以正常工作了,以便用户在需要保存对应用程序所做的更改时必须单击“
保存”按钮。 从保存重要信息的角度来看,这是正确的,但通常用户会忘记这样做。 怎么样 如果只有我们的应用程序可以每隔一定时间自动保存数据! “还有什么,这真的可以在Mavo的帮助下完成吗?” -你问。 我会很高兴和自豪地回答,是的,有可能!
因此,要教导应用程序自动将用户所做的更改保存到数据中,我们可以使用
mv-autosave属性 。 您需要将其添加到应用程序的根元素。 此属性的值是从用户更改数据到应用程序将其保存之间必须经过
的秒数 。 我们将对我们的应用程序进行适当的更改:
<main mv-app="flashcard" mv-storage="local" mv-autosave="3"> ... </main>
跟随白兔子!
mv-autosave="3"
autosave mv-autosave="3"
属性指示Mavo每三秒钟保存一次对这些数据所做的更改。 如果选择保存数据的服务(后端)存储了更改的历史记录 (例如GitHub和Dropbox ),则保存之间这种延迟的存在就变得至关重要。 没有这样的延迟将使变更的历史变得毫无用处。
要强制Mavo立即保存更改,可以设置mv-autosave="0"
属性或仅设置mv-autosave
。 同时,“ 保存”按钮将从Mavo工具栏中删除(不必要)。
要查看和评估对应用程序所做的更改,请再次更新其中一张卡上的数据,并注意“
保存”按钮。 你注意到了吗? 最初它被突出显示,但是三秒钟后熄灭,表明该应用程序中没有未保存的数据。 现在,所有更改将自动保存!
因此,我们的应用程序的主要部分现在看起来像这样:
<main mv-app="flashcards" mv-storage="local" mv-autosave="3"> <article property="flashcard" mv-multiple> <p property="source"> </p> <p property="translation"></p> </article> </main>
实践是通往卓越的道路!
我们的应用程序的Alpha版几乎完成了。 万岁! 现在轮到您做得更好了。 不用担心! 您拥有所有必要的知识,可以完成我将为您提供的任务。
改进应用程序,以便可以将按通用主题组合在一起的卡片分组。 例如,在一组中,所有与服装有关的词都包括在内,在另一组中,包括职业名称,在第三组中,包括食物名称等。
提示!
有几种解决问题的方法。 由您决定选择哪种方式以及选择哪种方式。 但我希望您考虑一些问题的答案,这可能有助于您找到解决方案。
- 您将使用哪个HTML元素作为分组元素(组) ? 如果可以给卡片组指定一个名称( 主题名称 ),并且如果可以根据需要对其名称进行最小化,则对应用程序的用户来说将很方便。
- 您将向所选元素添加什么属性(当然,除非您添加某些内容)。 该商品是物业还是收藏品 ?
- 应用程序的用户是否有机会添加新的卡组, 删除不必要的卡组,将组本身和卡在不同组之间移动 ?
顺便说一句,您可能会决定使用单独的元素将卡组合成组不是您的方法。 这是正常的。 也许您只想向卡片添加与主题相对应的标签 ( hashtags )。 这也是一个不错的决定!
要“把手伸手”并进一步了解Mavo及其功能,请同时实施这两个解决方案。
Mv-bar属性
我们将继续扩展应用程序的功能。 我们对其进行了配置,以便将用户数据存储在浏览器的本地存储中。 但是我们的应用程序仍然是单用户:用户无法与其他用户共享他们的卡。 拥有这样的机会真是太好了! 在公司里学习外语会更有趣,不是吗?
Mavo中是否有一种方法可以允许用户从应用程序中导出他们的卡并将其他人的卡导入其中? 我们很幸运! 正如他们所说的那样,Mavo支持此功能。 当然,就规范而言,这不会使我们的应用程序成为多用户,但是对于这样一个简单的应用程序,这种功能的存在已经很多了,您必须同意。
用手记住!
https://codepen.io/dsharabin/pen/ZEzmWBr
对于此类任务,Mavo具有
mv-bar属性,您可以
使用该属性
指定在Mavo工具栏上出现的按钮(如果完全需要任何按钮)。 通常,将此属性添加到应用程序的根元素。 按钮本身具有非常合乎逻辑的标识符(就其英文名称而言)。 这里只是其中的一些:
编辑,导入,导出 。
由于我们只想向Mavo工具栏上已有的按钮添加按钮,因此我们可以使用所谓的“
相对语法” 。 这种语法使我们可以在默认集中添加和删除按钮,而不必显式列出其中的所有按钮。 , , —
mv-bar with , ( ) :
<main mv-app="flashcards" mv-storage="local" mv-autosave="3" mv-bar="with import export"> ... </main>
— !
- : . , .
. MavoScript
, « », : « ?!» - . ? .
«» , - Mavo.
, (, , ) . , ,
property . — , .
, , , Mavo ( HTML-). . :
[] . . , - , .
!
, Mavo, MavoScript . ( Microsoft® Excel, Apple Numbers Google Sheets) , , . .
Mavo MavoScript , , , : , , , , .
, MavoScript , .
Mavo MavoScript .
!
https://codepen.io/dsharabin/pen/rNBQeMv
. ,
[source] flashcard . ,
source translation :
... <p property="source"> </p> [source] <p property="translation"></p> ...
? , ,
source . ? !
.
source . , , ?
[source] , ,
source , : , . ?!
, , , — . 怎么了
[source] , , —
source . - .
[source] flashcard , ? 像这样:
... [source] <article property="flashcard" mv-multiple> ... </article> ...
? , . ,
source (!) . , , . ?
. ? , ,
source ? , ,
source translation . ? :
[source] [flashcard] . :
... [flashcard] <article property="flashcard" mv-multiple> ... </article> ...
, ? , — . ( (!)).
, , ( , , ), , . , Mavo .
MavoScript count() , .
!
MavoScript — . , .
— . , .
- , , , .
- .
,
count() . , :
... <span>[count(flashcard)] .</span> <article property="flashcard" mv-multiple> ... </article> ...
, , — !
— !
, Mavo … . , , - . , .
, , ( ).
!
, , . where filter() .
, , . : , ? , .
( , ) — .
!
https://codepen.io/dsharabin/pen/WNeYwxR
, :
. , ? , :
« , JavaScript?» — . 是的 , Mavo — ?!
, , , :
... <article property="flashcard" mv-multiple> ... <section> <h2> </h2> <button> </button> <button> </button> </section> </article> ...
mv-action
Mavo , , —
(
custom actions ).
,
mv-action .
, . , —
.
!
mv-action <form> , .
mv-action . ,
MavoScript , :
add(), set(), move() delete() .
, , , , .
: Mavo
mv-action . , . ,
mv-action=""
,
mv-action="[]"
. , , , , .
, .
: .
move() . , — () . ,
,
0 .
, :
, . . . :
... <article property="flashcard" mv-multiple> ... <button mv-action="move(flashcard, 0)"> </button> ... </article> ...
,
mv-action flashcard . .
, . , , , ?
,
: , . , , (). , , , . ?
, . : , —
flashcard — .
flashcard . - :
... <article property="flashcard" mv-multiple> ... <button mv-action="move(flashcard, count(flashcard))"> </button> ... </article> ...
! .
?
. <meta>
, , ,
[count(flashcard)] ,
flashcard . ,
flashcard . , !
,
[count(flashcard)] flashcard - , . —
flashcard . Mavo , ,
(
computed properties ).
!
https://codepen.io/dsharabin/pen/NWKENNb
, , HTML-. HTML-,
<meta> :
<meta property="" content="[]">
. :
<meta> , .
!
, , , .
flashcardCount . ,
flashcard ( ):
... <meta property="flashcardCount" content="[count(flashcard)]"> <article property="flashcard" mv-multiple> ... </article> ...
:
, . :
... <meta property="flashcardCount" content="[count(flashcard)]"> <article property="flashcard" mv-multiple> ... <button mv-action="move(flashcard, flashcardCount)"> </button> </article> ...
! . 恭喜你!
— !
— $all .
$all , , . , . $all flashcardCount . ? 怎么了
, . , , ( ) . .
结论
, -. JavaScript. , , -. , « ». .
, — , , , . , , , . , HTML- Mavo, :
- ( <head> ) JavaScript- CSS- Mavo.
- mv-app .
- , ( / , / ) , property .
- mv-multiple , .
- Mavo, , mv-storage .
- , . , mv-autosave .
, : - Mavo ( Mavo ). mv-bar , , , .
- (expressions) ( ) (property) . ( ) , . Mavo , MavoScript .
- (custom actions) . mv-action .
- (computed properties) — , . , <meta> .
. ? , . . , , , (,
). , . ! . - — !
? 17 — (
« » )!
, Mavo, — , . Mavo . :
Mavo -,
.
Mavo . -, . 怎么了 :
- Mavo, , — Mavo ;
- , , , ;
- Mavo, , , , — ;
- , Mavo Twitter , , , , «» (, Gitter Mavo);
- , Mavo — !
Mavo!.
,
(
Lea Verou ),
( ), : , - . , !
(
James Moore ). ,
« JavaScript » Udemy , ,
«» . !