我可以使用不依赖于选择器的自定义jQuery函数进行链接吗?

时间:2014-01-11 18:40:43

标签: javascript jquery

我想我可能在这里做了一个jQuery失礼。或者就此而言的JavaScript。如果我是的话,请阻止我! :)

情景:

我想创建一个函数,它接受一个字符串和一些其他参数,然后将它们包装在一个settimeout中。简单的事情,但它比我的代码中的settimeouts更清晰。

它看起来像这样:

function myFunction(text,interval) {
    setTimeout(function(){
        // do a bunch of stuff with the text var
    },interval)
}

够容易。然后我意识到我可能想要多次一起改变它并且这样做,然后我必须将我的调用包装在他们自己的嵌套setTimeouts中,然后我又回到了看起来很乱的代码。

所以我想知道我是否可以利用jQuery使我的代码更好,更实用。

我试过这个,首先制作我自己的自定义jQuery函数:

$.fn.myFunction = function(text,interval) {
    setTimeout(function(){
        // do a bunch of stuff with the text var
    },interval)
}

以为我可以用这样的东西来称呼它:

$('body')
    .myFunction('string1',1000).delay(500)
    .myFunction('string2',1000).delay(500)
    .myFunction('string3',1000)

这看起来好多了,重复使用了很多。但是......这根本不起作用。我的问题:

  • 我是否在正确的道路上认为这是jQuery和自定义函数的可行用途?
  • 如果 我在哪里弄乱我的逻辑?
  • 最后,在调用链式jQuery函数之前,是否需要始终选择一个选择器? (我选择'body'只是为了让jQuery链变得典型,但我显然没有特别对jQuery对象做任何事情)

更新

感谢cookie怪物的回答,我现在有一个更新的例子:

  $.fn.myFunction = function(text,interval) {
    return this.queue(function(next) {
         setTimeout(function(){
            console.log(text);
        },interval)
    })
  };

然后我试图这样称呼它:

$。myFunction的( 'MSG1',500).delay(500).myFunction( 'MSG2',500).delay(500).myFunction( 'Msg3的',500)

这样做会给我这个错误:

TypeError: 'undefined' is not a function (evaluating '$.myFunction()')

所以我想也许它仍然需要一个选择器:

$('body').myFunction('msg1',500).delay(500).myFunction('msg2',500).delay(500).myFunction('msg3',500)

有效!......但只有一次。它执行一次该功能,但不再对链中的其他两次执行​​。所以,更进一步,但我仍然认为我缺少一些重要的概念或语法。

更新2

我的 的JSBin几乎 工作代码:http://jsbin.com/exAyuCUp/1/

2 个答案:

答案 0 :(得分:3)

使用.queue()使代码与.delay()一起使用。

start = Date.now()
$.fn.myFunction = function(text,interval) {
    return this.queue(function(next) {
        setTimeout(function(){
            console.log(text, start - Date.now())
            next() // This is mandatory!
        },interval)
    })
}

http://jsfiddle.net/FkR2D/

  
      
  • 我是否在正确的道路上认为这是jQuery和自定义函数的可行用途?
  •   

是的,只要有一个工具来管理时间延迟代码的有序执行,jQuery确实有。

  
      
  • 如果我在哪里弄乱我的逻辑?
  •   

唯一缺少的是排队代码,重新调整jQuery对象

  
      
  • 最后,在调用链式jQuery函数之前,是否需要始终选择一个选择器? (我选择'body'只是为了使jQuery链成为典型的,但我显然没有对jQuery对象做任何特别的事情)
  •   

不,选择器只是执行DOM选择。如果你的jQuery对象中已经有一组元素,那么就不需要选择DOM。

答案 1 :(得分:1)

当你只能使用setTimeout时,我不明白为什么你会费心去做$.fn.delay

我只使用没有任何延迟的函数:

$.fn.myFunction = function(text) {
    return this.queue(function(next) {
        // do a bunch of stuff with the text var
        console.log(text);
        next();
    });
}

并在需要的地方添加.delay

$('body')
      .delay(500).myFunction('msg1')
      .delay(500).myFunction('msg2')
      .delay(500).myFunction('msg3');

如果您不需要选择任何元素,您仍然可以围绕其他内容构建jQuery对象,例如虚拟对象:

$({}).delay(500).myFunction('msg1');

(您不能只使用$.delay(500).myFunction('msg1'),因为$对象不是继承$.fn原型的jQuery对象。)

Here's a fiddle.