10

描述

通过设计,大多数 jquery 代码会导致很多紧密耦合,例如选择器假定 html 的特定结构

var mySubnav = $("#navigation a.sub-menu");

如果相应的 html 发生变化,无论出于何种原因,

<a class="subMenu" .... </a>

功能被破坏。

问题

  • 处理紧密耦合的最佳方法是什么?
  • 有什么方法可以放松它?

答案,方法

  • 使用 html 自定义数据属性将 css 与 js 逻辑分开。例如data-submenu="true"在 html 上添加并var mySubnav = $("[data-submenu]");在 js 端使用。
  • 实施可靠的测试环境
  • 尽可能松散地耦合,使用最不具体的选择器,例如$("a.sub-menu'). 也可以看看
  • 通过 (1) 预先检索对静态 DOM 元素的引用,以及 (2) 将选择器字符串存储在一个位置(在代码的顶部),从 jQuery 代码的主体中消除表示 CSS 选择器的实际字符串文字。
  • 使用 javascript 框架,例如Backbone,它通过视图将 javascript 与 DOM 分离
  • 由于事件管理,使用委托实时耦合
4

7 回答 7

6

这可能不是一个流行的答案,但是......测试,测试,测试。JQuery 和 Javascript 通常是紧密耦合的,这是有充分理由的;它们是在浏览器中运行的代码,因此您希望保持性能相对快速。因此,注入允许松散耦合的间接层会降低性能;同样,这可能有点矫枉过正,因为在编写的 JQuery / Javascript 代码和编写它们的页面之间通常存在紧密的配对;这同样是 Javascript 历史发展的产物,但事实就是如此。因此,紧密耦合是非常“正常的”。

处理这种紧密耦合的方法,就像任何紧密耦合一样,是确保您已经进行了良好的测试以涵盖任何耦合故障。测试可以确保耦合是正确的,而且它确实是确保您所期望的功能的最佳方式。

于 2011-07-25T18:29:08.133 回答
3

一种选择是使用 Javascript 框架,例如Backbone。它为您提供了有助于将 Javascript 与 DOM 结构分离的视图概念。例如,您可以创建 Comment 视图,并将其分配给以下 div:

<div class="comment">
    <span class="title"></span>
    <p class="body"></p>
</div>

然后您可以访问相对于commentdiv 的视图中的元素:

var title = this.$(".title");

这使得在 div 外部更改 DOM 结构变得很容易,comment只要 div 的内部comment保持不变。

于 2011-07-25T18:36:51.727 回答
2

为 UI 挂钩使用自定义前缀类ui-specificGuy

提供的 HTML

<div class="container grid8">
    <ul class="ul1 horizontal">
        <li>List Item 1</li>
        <li>List Item 2</li>
    </ul>
</div>

不好- 使用风格目的的类/钩子

$('.container.grid8').stuff();
$('.ul1.horizontal').moreStuff();

调整 HTML

<div class="container grid8 ui-specificContainer">
    <ul class="ul1 horizontal ui-specificList">
        <li>List Item 1</li>
        <li>List Item 2</li>
    </ul>
</div>

- 使用你自己有目的的类/钩子

$('.ui-specificContainer').stuff();
$('.ui-specificList').moreStuff();

仅在必要时具体

如果这将实现您的目标。

$('.ui-targetedElement')

那为什么会有一个看起来像这样的选择器呢?

$('ul > li a.ui-targetedElement')

这只是将不必要的 DOM 结构依赖项引入到您正在构建的功能中,并且您应该能够在这方面积极主动,因为此时您应该提供自己的钩子(带前缀的类),对吧?

最后,尽管我会说 DOM 和脚本之间的紧密耦合有时是不可避免的,因为它们是如何协同工作的。

全文

于 2011-07-25T18:28:59.490 回答
2

如果您谈论的是事件管理,那么尽可能多地使用与 dom 结构不紧密耦合的委托和直播。看看下面的网址

直播 - http://api.jquery.com/live/

代表 - http://api.jquery.com/delegate/

于 2011-07-25T18:31:01.627 回答
2

我的建议是:

  1. 在准备好的 DOM 上检索静态 DOM 元素的引用,并将它们放入对象的变量或属性中。

  2. 将类名存储在一个对象(或多个对象或其他任何东西,只要这些名称(字符串)在一个地方)

然后你可以这样做:

var mySubnav = $('a.' + C.submenu, navigation);

wherenavigation是对#navigation元素的引用,C是 class-names 对象,其submenu属性是 string "sub-menu"

现在,当您在 HTML 代码中更改类名时,您只需更新C对象。

这个想法是通过(1)预先检索对静态 DOM 元素的引用,以及(2)将选择器字符串存储在一个地方(在你的顶部代码)。

于 2011-07-25T18:35:39.920 回答
1

如果您的 html 发生更改,则所有赌注都将取消。

你所拥有的不是紧耦合。您的代码必须正常运行。

例如,这就是我认为的紧密耦合:

<a class="subMenu" onclick="doSomething()"> .... </a>

松散的版本是:

$("#navigation a.sub-menu').click(function(){
   //do something
});
于 2011-07-25T18:27:04.887 回答
1

使用 html5 数据属性来做 javascript 选择器怎么样?

<a data-submenu="true" .... </a>

var mySubnav = $("[data-submenu]");

非常清楚 javascript 是在 html 上运行的。

于 2011-08-26T17:12:35.863 回答