在我自己的班级

时间:2016-08-05 19:03:22

标签: javascript

我正在尝试从JQuery创建一个类似于delay()的方法。 我正在创建一个名为$的方法。请记住我没有使用JQuery 并且不想解决此问题。

function $(element) {
  if(!(this instanceof $)) {
    return new $(element);
  }
  this.element = document.querySelector(element);
}

$.prototype.color = function color(color) {
  this.element.style.color = color;
}

我可以像这样使用这种方法:

$('#foo').color('red);

它会将#foo的颜色更改为红色

我要做的是在更改颜色之前设置延迟。一种方法是:

$.prototype.delay(time, fn) {
  setTimeout(function() {
    fn();
  }, time);
}

然后像这样调用它:

$('#foo').delay(1000, function() {
  $('#foo').color('red');
});

但那不是很有用,我想做的就是这样使用它:

$('#foo').delay(1000).color('red);

我找到了this,但无法弄清楚。

提前致谢, I.L

这样做的一种方式(@georg)



// create a new instance if it doesn't already exists when $ is called
function $(element) {
  if(!(this instanceof $)) {
    return new $(element);
  }
  this.element = document.querySelector(element);
  this.promise = Promise.resolve(this);
  this.css = this.element.style;
}

// wrapper for the promise
$.prototype.method = function(name, fn) {
  $.prototype[name] = function(...args) {
    this.promise.then(self => fn.apply(self, args));
    return this;
  };
}

// delay method, 
$.prototype.delay = function(time) {
  this.promise = new Promise(
    resolve => setTimeout(() => resolve(this), time));
  return this;
}

// example of a method to change the color
$.prototype.method('color', function (color) {
  this.css.color = color;
});

// used like so
$('#foo').delay(2000).color('green');

<div id="foo">Hi there!</div>
&#13;
&#13;
&#13;

我找到了另一个很好的解决方案,允许多次使用延迟查看我的答案以获取更多详细信息。

3 个答案:

答案 0 :(得分:2)

这是一个承诺的例子。需要更多的工作才能实用,但应该给你一个想法。基本上,像color这样的所有方法都应该在“解决这个问题”而不仅仅是“这个”上运行:

function $(element) {
  if(!(this instanceof $)) {
    return new $(element);
  }
  this.element = document.querySelector(element);
  this.promise = Promise.resolve(this)
}

$.prototype.color = function color(color) {
  this.promise.then(function(self) {
    self.element.style.color = color;
  });
}

$.prototype.delay = function(n) {
  this.promise = new Promise(
    resolve => setTimeout(() => resolve(this), n));
  return this;
}

$('#foo').color('red');
$('#foo').delay(1000).color('blue');
<div id="foo">foo</div>

对于自动宣传,您可以使用这样的包装:

$.prototype.method = function(name, fn) {
  $.prototype[name] = function(...args) {
    this.promise.then(self => fn.apply(self, args));
    return this;
  };
}

然后,例如,

$.prototype.method('color', function (color) {
  this.element.style.color = color;
});

答案 1 :(得分:0)

以下是jQuery如何实现它:

    function (time, type) {
        time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
        type = type || "fx";

        return this.queue(type, function () {
            var elem = this;
            setTimeout(function () {
                jQuery.dequeue(elem, type);
            },
            time);
        });
    }

仅使用*队列:

    function (type, data) {
        if (typeof type !== "string") {
            data = type;
            type = "fx";
        }

        if (data === undefined) {
            return jQuery.queue(this[0], type);
        }
        return this.each(function () {
            var queue = jQuery.queue(this, type, data);

            if (type === "fx" && queue[0] !== "inprogress") {
                jQuery.dequeue(this, type);
            }
        });
    }

And Dequeue:

function (type) {
    return this.each(function () {
        jQuery.dequeue(this, type);
    });
}
  • 这些函数中唯一的外部jQuery调用是“jQuery.fx”,可以避免。

从那里,在您自己的模型中实现这三个功能将很容易。

答案 2 :(得分:0)

使用可链接方法并设置延迟方法:

&#13;
&#13;
function $(element) {
  if(!(this instanceof $)) {
    return new $(element);
  }

  // select all elements with this identifier
  this.elements = document.querySelectorAll(element);

  // by default select the first element of querySelectorAll
  this.element = this.elements[0];
  this.css = this.element.style;

  // first method applied will be exectuted directly
  this.delayTime = 0;
}


$.prototype.$ = function position(pos) {

  if(pos == 'first') {
    pos = 0;
  } else if(pos == 'last') {
    pos = this.elements.length-1;
  }

  var that = this;
  setTimeout(function() {
    that.element = that.elements[pos] || that.elements[0];
    that.css = that.element.style;
  }, this.delayTime);

  return this;
}

$.prototype.delay = function(delayTime) {
  // set a delay for the following method applied
  this.delayTime += delayTime;

  return this;
}

// wraps the method into a setTimeout
$.prototype.method = function(name, fn) {
  $.prototype[name] = function(...args) {
    var that = this;
    setTimeout(function() {
      // method will only take one relevant parameter
      fn(that, args[0]);
    }, this.delayTime);
    return this;
  };
}

// CSS methods
$.prototype.method('backgroundColor', function(self, color) {
  self.css.backgroundColor = color;
})

$('#foo').delay(1000).backgroundColor('blue').delay(1000).backgroundColor('white').delay(1000).backgroundColor('red');
&#13;
#foo {
  background-color: lightgrey;
}
&#13;
<div id="foo">Hey there!</div>
&#13;
&#13;
&#13;