jquery意大利面!清洁代码的提示和技巧

经过 2012年3月7日 No Comments

上周我在 Confoo. 介绍我的谈话,jquery spagetthi。这次谈话是jQuery的最佳实践的集合,因为它有点受欢迎,为什么不把它放在博客文章中。你自己,它’很久了读(你也可以下载 法语 幻灯片 这里)。

Custom.js文化问题

这似乎很多网络机构带着jquery mantra有点太远了, “less code, do more”。当您作为其中一个代理商中的前端开发人员工作时,您可以在恐惧中始终打开JS文件夹。

可能不是您在代码中要做的事情。

一般来说,您发现了几个插件和一个名为Custom.js的文件。当你打开它时,有时你很幸运,它只有几条线。即使代码看起来像废话,那么,你也可以在几个小时内重新介入所有这些。

但…有时你不太幸运,你有一个2000线弄乱,你不仅可以获得100个事件到处都是绑定的,你还可以获得一个从不停止的.parent()遍历选择器的鼻塞。

在您在那些混乱的一天结束时,您希望成为酗酒和改变工作,如下所示。

那么我们要看什么就是你如何改善乱七八糟。

活动

jQuery为您提供3种类型的事件处理程序,您可以获得

  1. 绑定(), 直接绑定在HTML元素上,并在加载BIND()时需要存在
  2. 居住(), 使用事件委派并直接绑定文件
  3. 代表(),像Live()使用事件委派但具有上下文,可以绑定在DOM中的任何元素上

活动代表团(冒泡)– what is this?


基本上,可以在DOM中的任何元素上触发的任何事件都可以在该元素的任何父级上缓存。 jQuery使用该功能,例如,您可以在表单上使用委托来将事件绑定到输入,因此事件不会泄漏该特定形式。有关事件代表团的更多信息 可以在这里找到.

虐待代表

您可能总是总是使用委托,因为它具有绑定()和live()的大量优势。

  1. 在HTML对象的集合上使用时,绑定()很慢,例如,将内容绑定到20个输入,它必须实际解析所有HTML文档并为每个元素绑定事件20次。委托不遭受此问题,您只在表单上绑定一次,并让事件委派魔法休息。
  2. Live()没有上下文,这意味着它因为它直接绑定在文档上有一个更改事件泄漏。想象一下,你在拥有班级的按钮上使用 .btndelete.,有可能使用其他开发人员使用该类的可能性,委托防止事件泄漏到全局空间,如闭合为变量。

自定义事件

该jQuery特征通常在一般的遮罩中被用来。有几个案例可以更好地使您的代码更好,但首先让’看看下面的例子。

// Pour ouvrir un lightbox en script en utilisant le plugin colorbox
// Ce script n'est la qu'une fois au travers de notre application
$(document)。 bind('lightbox.open', function(event, config) {
  $.colorbox(config)
});

// Dans notre script, on ouvre un lightbox
  $(document)。 trigger('lightbox.open', [{"href":"/popup", "height":400}]);

自定义事件的第一个大用例是从第三方插件解码代码。最好的例子是灯箱。这是几个灯箱插件,它不是因为你现在使用其中一个更好的可能会弹出,或者可能会与IE10打破。使用自定义事件您可以创建您在代码中决定和使用它们的事件,并且仅在一个地方将这些事件绑定到第三方。

由于您只绑定一次,更改插件非常简单,并且不包含30个查找和替换操作。此外,您为贵公司构建标准,并使员工更容易拿起标准。

第二个用例是用于解耦您的JS模块。想象一下,如果您直接从另一个模块调用函数,并且从应用程序中删除该模块的情况会发生什么?好吧,你在你的脚本中得到了js错误,但如果使用自定义事件将执行此操作’s no problem.

请参阅下面的示例:

您希望修改用户的名称,但也有另一个模块在其中打印名称。在这种情况下,您有2个选择。

,您将直接修改HTML从该模块中,但是’不是很方便。其他开发人员都没有办法知道你 ’完成此操作,因为其他页面上的任何内容都没有显示,以通知它们您的Save Button修改此HTML。

,您使用自定义事件“change:name”你让左模块处理它。如果你这样做,从来没有其他方法可以改变你的名字–您只需调用该更改:名称事件,左侧模块将处理其余部分。

选择器遍历

当您从jQuery开头时,跨越的大障碍之一是选择器遍历,大多数人在第一个选项中停止.parent()。不幸的是,使用它不远的是反模式。如果另一个DEV在按钮和容器之间添加DIV会发生什么?你的代码坏了,更糟糕的是,没有人甚至知道它。

幸运的是,有一个简单的解决方案:使用最近的(),它’s喜欢类动物的父母()。最接近,您可以像这样传递您的目标SELCTOR类 最近(“.container”) jquery将在您的DOM树中神奇地向上移动,直到它击中选择器。

简单!

Ajax请求

自jQuery 1.5以来,我们在街区有一个新的孩子,推迟。在1.5 $之前.Ajax不是可包裹的,这并不酷!如果您想要相同的Ajax请求,但使用不同的成功功能怎么办?幸运的是,延期了改变了这一切。看下面的例子:

 

它还添加了 很多功能 思考会花费太多时间,但我想谈论的是 $ ...

$ ..

想象一下,您有2个Ajax请求同时,您希望在执行这两个AJAX请求后执行某些内容。在1.5之前,它真的很奇怪;您必须检查是否在成功函数和保存状态下执行了两个请求。这么多开销。以$。当你刚刚通过你的请求ajax到它和jquery做到了其余的,一个例子解释得多:

代码结构

我知道谈论代码结构是一种挑剔的主题。每个人都做了自己的事情,我不想进入那个。但对于上帝的爱,不要将无休止的一系列活动直接放入DOM准备好!请至少使用对象来构建所有这些。如果有一件事骨干确实很好’s处理事件,所以让我们看一下典型的backbone.js视图:

我们怎样才能将其带入并将其转换为vanilla javascript?好吧,它看起来像这样:

var mailapp.events.users = {
  initialize: function(){
    this.$usersWrapper = $("#usersWrapper");
      if(!this.$usersWrapper.length) this.loadEvents();
  },
  loadEvents: function(){
    var _this = this;
    // launch our modal events
    $.subscribe("modal.Complete.", function(){ _this.loadPopupEvents(); });

      // Delegate give a context to our events
      this.$usersWrapper
        .delegate("#btnDelete","click", function() { _this.deleteItem(); return false; });
        .delegate("#btnsave","click",   function() { _this.save(); return false;));
        .delegate("#btnModify","click", function() { _this.modify(); return false;));
  },
  loadPopupEvents : function() {
    $(".myPopupForm")。 validationEngine();
  },
  deleteItem: function(){
    $(this)。 closest('.item')。 remove();
  },
  modify: function(){
    var jQitem = $(this)。 closest('.item');
    jQitem.find("input")。 css("display"," block");
    jQitem.find(".name")。 css("display"," none");
  },
  save : function(){
    var jQitem = $(this)。 closest('.item');
    jQitem.find(".printNom")。 html($(this)。 parent().find("input")。 val());
    jQitem.find("input")。 css("display"," none");
    jQitem.find(".printNom")。 css("display"," block");
  }
}

所以这是很多代码。让’s take it apart.

初始化()

 initialize: function(){
    this.$usersWrapper = $("#usersWrapper");
      if(!this.$usersWrapper.length) this.loadEvents();
  },

我始终将JS模块绑定到HTML文档的一部分,在INIT中,检查我的HTML容器是否位于DOM中。如果不是那里,完全停止。该模块的其余部分将不会加载,这减少了如果模块在应用程序的另一部分中加载的情况下可以获得的开销和泄漏(或者所有JS集中在一个大JS文件中)。

如果我们有我们的HTML容器,请允许’s移动到loadevents()。

loadevents()

 loadEvents: function(){
    var _this = this;
    // launch our modal events
    $.subscribe("modal.Complete.", function(){ _this.loadPopupEvents(); });

      // Delegate gives a context to our events
      this.$usersWrapper
        .delegate("#btnDelete","click", function() { _this.deleteItem(); return false; });
        .delegate("#btnsave","click",   function() { _this.save(); return false;));
        .delegate("#btnModify","click", function() { _this.modify(); return false;));
  },

我们在这里的所有活动都使用在Init中提前保存的HTML容器加载了委托。我们还有一个自定义事件 modal.Complete. 当灯箱打开时被解雇,因此它现在很容易将事件绑定到我们的灯箱中而没有任何疼痛。

那’几乎是模式的有趣部分。

其他模式

上面的模式是您可以使用的最简单和最简单的模式。当然还有其他解决方案,您可以获得私人和伪保护的空间。我最喜欢的是揭示模式,另一个缺少的模式是jQuery插件模式。

在大多数情况下,每个公司都有自己的选项卡,滑块,灯箱和其他插件。问题是,大部分时间都是一堆代码,没有任何设置,这些代码没有从项目中粘贴到项目,直接应用于核心代码。

那’不幸的是,它真的没有帮助公司发展他们的JS代码库。一世’不将展示jQuery插件模式如何工作,因为它是 已经很好地解释了, 但它’很酷,很容易看看!

如果您想与JavaScript模式深入了解我推荐Stefan Stefanov Book,正确地命名 JavaScript模式.

结论

这是我这里的演示文稿的好块–我希望它对你们的一些人有用。正如我在谈话中所说的那样,这个想法是给予一堆建议,所以你们可以为你的公司和你的风格应用最好的工作,并在垃圾箱里养成剩下的休息

Please wait...