5

为了使我的 Javascript 不引人注目,我正在使用onLoads 向<input>s 等添加功能。使用 Dojo,这看起来像:

var coolInput = dojo.byId('cool_input');
if(coolInput) {
  dojo.addOnLoad(function() {
    coolInput.onkeyup = function() { ... };
  });
}

或者,大致等价:

dojo.addOnLoad(function() {
  dojo.forEach(dojo.query('#cool_input'), function(elt) {
    elt.onkeyup = function() { ... };
  });
});

有没有人编写了 Ruby 的andand的实现,以便我可以执行以下操作?

dojo.addOnLoad(function() {
  // the input's onkeyup is set iff the input exists
  dojo.byId('cool_input').andand().onkeyup = function() { ... };
});

或者

dojo.byId('cool_input').andand(function(elt) {
  // this function gets called with elt = the input iff it exists
  dojo.addOnLoad(function() {
    elt.onkeyup = function() { ... };
  });
});
4

7 回答 7

3

我不知道 Dojo,但你的第一个例子不应该读

dojo.addOnLoad(function() {
    var coolInput = dojo.byId('cool_input');
    if(coolInput)
        coolInput.onkeyup = function() { ... };
});

否则,您最终可能会在 DOM 构建之前尝试访问该元素。

回到您的问题:在 JavaScript 中,我将实现andand()

function andand(obj, func, args) {
    return obj && func.apply(obj, args || []);
}

你的例子可以写成

dojo.addOnLoad(function() {
    andand(dojo.byId('cool_input'), function() {
        this.onkeyup = function() { ... };
    });
});

这实际上并没有比使用显式if语句短得多——那何必呢?

于 2009-01-07T23:12:06.260 回答
2

您想要的确切语法在 JavaScript 中是不可能的。JavaScript 的执行方式需要以一种非常基本的方式改变。例如:

var name = getUserById(id).andand().name;
//                        ^
//                        |-------------------------------
// if getUserById returns null, execution MUST stop here |
// otherwise, you'll get a "null is not an object" exception

然而,JavaScript 不是这样工作的。它根本没有。

以下行几乎完全符合您的要求。

var name = (var user = getUserById(id)) ? user.name : null;

但是可读性不会扩展到更大的示例。例如:

// this is what you want to see
var initial = getUserById(id).andand().name.andand()[0];
// this is the best that JavaScript can do
var initial = (var name = (var user = getUserById(id)) ? user.name : null) ? name[0] : null;

还有那些不必要的变量的副作用。我使用这些变量来避免双重查找。变量正在混淆上下文,如果这很重要,您可以使用匿名函数:

var name = (function() {return (var user = getUserById(id)) ? user.name : null;})();

现在,用户变量已正确清理,每个人都很高兴。但是哇!多打字啊!:)

于 2009-04-14T21:04:18.093 回答
2

你想要dojo.behavior

dojo.behavior.add({
    '#cool_input': {
        onKeyUp: function(evt) { ... }
    }
});
于 2009-04-14T21:25:55.310 回答
1

像这样的东西怎么样:

function andand(elt, f) {
  if (elt)
    return f(elt);
  return null;
}

像这样调用:

andand(dojo.byId('cool_input'), function(elt) {
  // this function gets called with elt = the input iff it exists
  dojo.addOnLoad(function() {
    elt.onkeyup = function() { ... };
  });
});
于 2009-01-07T22:40:15.513 回答
0

据我所知,没有具有相同功能的内置 JavaScript 函数。我认为最好的解决方案是按类而不是 id 查询并使用 dojo.forEach(...) ,因为您将保证在 forEach 闭包中有一个非空元素。

您总是可以使用 JavaScript 等价物:

dojo.byId('cool_input') && dojo.byId('cool_input').whateverYouWantToDo(...);
于 2009-01-07T22:19:24.993 回答
0

我从未使用过 dojo,但大多数 javascript 框架(在处理 DOM 时)在从元素对象调用方法时返回调用元素(措辞不佳,抱歉)。所以 andand() 是隐含的。

dojo.addOnLoad(function() {
  dojo.byId('cool_input').onkeyup(function(evt) { /*event handler code*/
  });
});
于 2009-01-07T22:25:42.407 回答
0

对于列表:

Array.prototype.andand = function(property, fn) {

    if (this.filter(property).length > 0) this.map(fn);
}
于 2009-04-14T20:38:13.040 回答