开发模块化的JavaScript组件

现如今,虽然多数的web应用都使用了大量的JavaScript,但如何保持客户端功能的专注性、健壮性和可维护性依然是一个很大的挑战。

尽管其它编程语言和系统都已经将关注分离和DRY这样的基本原则视为理所当然的宗旨,但往往在进行浏览器端应用开发的时候,这些原则就被忽视了。

造成这一现象的部分原因是JavaScript语言本身就在不断挣扎的历史,在很长的一段时间内,它都难以获得开发者的认真关注和对待。

而更重要的原因或许是源于服务端与客户端的差异造成的。虽然在这方面已经有大量的架构风格方面的概念,例如ROCA,阐述了如何管理这种差异的方式。但还是缺乏如何实现这些概念的具体步骤的指南1。

这些原因经常导致前端代码的高度过程化并且相对缺乏结构性,这种直接的代码调用方式减少了调用的开销,从而简化了代码调用的复杂性,JavaScript和浏览器也是因为这一点原因而允许这种调用方式的存在。但很快,通过这种方式实现的代码就会变得得难以维护。

本文将通过一个示例为你展示某个简单的组件(widget)的演化过程,看看它是如何从一个庞大的、缺乏结构性的代码库进化为一个可重用的组件的。

对联系人进行过滤

这个示例组件的作用是对一个联系人列表通过名称进行过滤。它的最新成果以及它的全部演化过程都可以在这个GitHub代码库中找到。我们鼓励读者们对提交的代码进行审阅,并且留下宝贵意见。

按照渐进式增强的原则,我们首先从一个基础的HTML结构开始以描述所用到的数据。这里用到了h-card这个微格式(microformat),它能够起到语义化的作用,使得联系人的各种信息显得具有意义:

<!-- index.html --> 

 <ul>
    <li class="h-card">
        <img src="png/jake.png" alt="avatar" class="u-photo">
        <a href="http://jakearchibald.com" class="p-name u-url">Jake Archibald</a>
        (<a href="mailto:jake@example.com" class="u-email">e-mail</a>)
   </li>
   <li class="h-card">
        <img src="png/christian.png" alt="avatar" class="u-photo">
        <a href="http://christianheilmann.com" class="p-name u-url">Christian Heilmann</a>
        (<a href="mailto:christian@example.com" class="u-email">e-mail</a>)
   </li>
   <li class="h-card">
        <img src="png/john.png" alt="avatar" class="u-photo">
        <a href="http://ejohn.org" class="p-name u-url">John Resig</a>
        (<a href="mailto:john@example.com" class="u-email">e-mail</a>)
   </li>
   <li class="h-card">
        <img src="png/nicholas.png" alt="avatar" class="u-photo">
        <a href="http://www.nczonline.net" class="p-name u-url">Nicholas Zakas</a>
        (<a href="mailto:nicholas@example.com" class="u-email">e-mail</a>)
   </li>
</ul>

有一点请注意,在这里我们并不关心这个DOM结构是基于server端生成的HTML代码,或是由其它组件生成的,只要保证在初始化时,我们的组件能够依赖于这个基础结构就够了。这一结构实际上为表单项构成了一个基于DOM的数据结构 [{ photo, website, name, e-mail }]。

有了这个基础结构之后,我们就可以开始实现我们的组件了。第一步是为用户提供一个输入字段,以输入联系人名称。虽然它并不属于DOM结构的契约,但我们的组件仍然要负责创建它并动态地加入到DOM结构中去(毕竟,如果没有我们的组件,那么添加这个字段就完全没有任何意义了)。

// main.js     

 var contacts = jQuery("ul.contacts");
 jQuery('<input type="search"  />').insertBefore(contacts);

(我们在这里仅是出于便利性而使用了jQuery,同时也考虑到它的广泛使用性。如果使用其它的DOM操作类库,也是出于同样的原因。)

这个JavaScript文件本身以及它所依赖的jQuery文件都会在HTML文件的底部进行引用。

接下来开始加入所需的功能,对于那些不符合这个新建的字段中的输入名称的联系人,这个组件会将它们隐藏起来:

// main.js     

 var contacts = jQuery("ul.contacts");
 jQuery('<input type="search"  />').insertBefore(contacts).
on("keyup", onFilter);     

 function onFilter(ev) {
     var filterField = jQuery(this);
     var contacts = filterField.next();
     var input = filterField.val();     

     var names = contacts.find("li .p-name");
     names.each(function(i, node) {
         var el = jQuery(node);
         var name = el.text();     

         var match = name.indexOf(input) === 0;
         var contact = el.closest(".h-card");
         if(match) {
             contact.show();
         } else {
             contact.hide();
         }
    });
 }

(引用一个分离的、具名的函数,比起定义一个匿名函数来说,通常会使得回调函数更便于管理。)

请注意,这个事件处理函数依赖于特定的DOM环境,它取决于触发这个事件的元素(它的执行上下文会映射到this指针上)。我们将从这个元素开始遍历DOM结构,以访问联系人列表,并找出所有包含名称的元素(这是由微格式的语义所定义的)。如果某个名称的开头部分与当前输入的内容不匹配,我们就再次向上遍历,将相应的容器元素隐藏起来,否则的话,就要保证该元素依然可见。

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/webkf/script/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索jquery
, 结构
, 代码
, 组件
, contacts
一个
前端模块化组件化开发、js模块化开发的组件、javascript模块化开发、javascript组件开发、javascript组件化开发,以便于您获取更多的相关知识。

时间: 2024-11-03 16:12:00

开发模块化的JavaScript组件的相关文章

分析模块化的JavaScript开发的优势在哪里?

如今模块化的 JavaScript 的开发越来越火热,无论是模块加载器还是优秀的 JavaScript 模块,都是层出不穷.既然这么火,肯定是有存在的理由,肯定是解决了某些实际问题.很多没接触过模块化 JavaScript 开发者不禁要问,我真的需要模块化吗,模块化相比于传统的模式有什么优势? JavaScript 本身是没有模块化支持的,很多语言多有,就连CSS都有这样的加载方式. @import "fed.css"; 虽然因为性能问题不推荐CSS这样来进行加载,但这是一种模块化的思

怎样在不使用框架的基础上开发一个 Javascript 组件

本文讲的是怎样在不使用框架的基础上开发一个 Javascript 组件, 许多开发者(包括我)犯的一个错误是当遇到问题时他们总是自上而下地考虑问题.他们想问题的时候,总是从考虑框架(Framework),插件(Plugin),预处理器(Pre-processors),后处理器(Post-processors),面向对象模式(objected-oriented patterns)等等这些方面出发,他们也可能会从他们以前看过的一篇文章来考虑.而这时如果有一个生成器(Generator)的话,他们当然

全程记录开发一个完整的JavaScript组件教程

在浏览器中存在一些内置的控件 Alert,Confirm等,但是这些控件通常根据浏览器产商的不同而形态各异,视觉效果往往达不到UI设计师的要求.更重要的是,这类内置控件的风格很难与形形色色的各种风格迥异的互联网产品的设计风格统一. 因此,优秀的前端开发者们各自开发自己的个性化控件来替代浏览器内置的这些控件.当然,这类组件在网络上已经有不计其数相当优秀的,写这篇文章的目的是为了通过这种方式,与更多的开发者互相交流,互相学习,共同进步. 功能介绍     取代浏览器自带的Alert.Confirm控

如何开发一个完整的JavaScript组件

作为一名开发者,大家应该都知道在浏览器中存在一些内置的控件:Alert,Confirm等,但是这些控件通常根据浏览器产商的不同而形态各异,视觉效果往往达不到UI设计师的要求.更重要的是,这类内置控件的风格很难与形形色色的各种风格迥异的互联网产品的设计风格统一.因此,优秀的前端开发者们各自开发自己的个性化控件来替代浏览器内置的这些控件.当然,这类组件在网络上已经有不计其数相当优秀的,写这篇文章的目的不是为了说明我开发的这个组件有多优秀,也不是为了炫耀什么,只是希望通过这种方式,与更多的开发者互相交

JavaScript组件开发完整示例_javascript技巧

本文实例讲述了JavaScript组件开发的技巧.分享给大家供大家参考,具体如下: 使用JavaScript,按照面向对象的思想来构建组件. 现以构建一个TAB组件为例. 从功能上讲,组件包括可视部分和逻辑控制部分:从代码结构上讲,组件包括代码部分和资源部分(样式.图片等). 组件的特点:高内聚,低耦合(不与其他代码逻辑交叉,可以继承,包含):封装性(隐藏私有方法和变量):可重用性(可反复多次使用,用来组装更复杂的应用). <html> <head> <meta http-e

Android App开发中创建Fragment组件的教程_Android

你可以认为Fragment作为Activity的一个模块部分,有它自己的生命周期,获取它自己的事件,并且你可以在Activity运行的时候添加或者移除它(有点像你可以在不同的Activity中重用的一个"子Activity").这节课程讲述如何使用Support Library继承Fragment类,所以你的应用程序仍然是兼容运行的系统版本低于Android1.6的设备. 注意:如果你决定你的应用要求的最低的API级别是11或者更高,你不需要使用Support Library,反而能使

九个用于移动APP开发的顶级JavaScript框架

从技术上讲,iOS.Android和Windows Phone上的移动app使用了不同的编程语言进行编码.iOS app使用Objective-C,Android app使用Java,而Windows Phone app使用.NET.但是,掌握一定量的JavaScript.CSS和HTML知识,你就可以构建超棒的移动app.因此,在本博客中,我们将讨论用于开发移动app的顶级JavaScript框架. 对于Web开发而言,JavaScript是一个有前途的编程语言,并且在不久的将来它将依然在这个

推荐用于移动APP开发的顶级JavaScript框架

从技术上讲,iOS.Android和Windows Phone上的移动app使用了不同的编程语言进行编码.iOS app使用Objective-C,Android app使用Java,而Windows Phone app使用.NET.但是,掌握一定量的JavaScript.CSS和HTML知识,你就可以构建超棒的移动app.因此,在本博客中,我们将讨论用于开发移动app的顶级JavaScript框架. 对于Web开发而言,JavaScript是一个有前途的编程语言,并且在不久的将来它将依然在这个

《移动网页设计与开发 HTML5+CSS3+JavaScript》—— 导读

前言 移动网页设计与开发 HTML5+CSS3+JavaScript 我们正处于一个史无前例的网络创新时代.不久前,一家叫微软的公司主宰着网络世界,例如,2003年全球约95%的电脑使用IE浏览器.这种高度统治的优势是:为开发人员提供了一个稳定的市场:但同时也存在严重的缺陷:微软选择了结束IE浏览器的非核心工作,使得网络创新停滞不前--这就是一个缺乏竞争的封闭环境导致的结果. 现在的情形完全不同了,将近四五个主要浏览器厂商,大约相同数量的主要操作系统商,以及更多的团队一直参与其中.Adobe已经