如何创建个人JavaScript库和框架?

时间:2013-07-18 02:00:35

标签: javascript

作为开发人员,我想创建自己的JavaScript库和框架。在架构和功能方面,我应该考虑哪些方面?

1 个答案:

答案 0 :(得分:10)

首先,你需要知道你希望你的图书馆做什么。从那以后,你需要知道如何做你想要建立的东西。例如,如果您正在尝试制作游戏库,那么您最好了解自己的方程式,并熟悉Canvas和WebGL等内容。我之前为字符串,数组,对象等方法创建了一个库。我完成了它,但遗憾的是我从未完成过文档。

无论如何,我基本上开始创建一个“JavaScript类”。这看起来像(做一个类似jQuery的库示例):

var DOM = function (selector) {
  if (typeof selector == "string") {
        selector = document.querySelectorAll(selector);
  }
  this.animate = function (prop, times, callbacks) {
      var el = selector;
      var animate = function (element, props, time, callback) {
          callback = callback || function () {};
          time = time || 1000;
          var timers = {}, // store the different interval timers so that they can be cancelled
          calls = 0, // numbers of times the call would have been called
          nprops = 0; // number of properties
          for (var prop in props) {
              (function (prop) {
                  var edit = prop == "scrollTop" ? element : element.style;
                  var stepCounter = [],
                      customStep = props[prop],
                      curr = edit[prop],
                      lastStepPercent = curr == "" ? (prop == "opacity" ? 1 : 0) : curr,
                      measure = prop == "scrollTop" || prop == "opacity" ? "" : "px",
                      stepper = function () {
                          edit[prop] = stepCounter[0] + measure;
                          stepCounter.shift();
                      };
                  if (props[prop].constructor == Number) customStep = [props[prop]];
                  for (var step = 0, len = customStep.length; step < len; step++) {
                      var from = parseInt(lastStepPercent),
                          to = parseInt(customStep[step]),
                          small = to < from,
                          numOfSteps = small ? from - to : to - from, // get current number of frames
                          multi = 30 * Math.round(parseInt(time) / 1000),
                          by = numOfSteps / (25 + multi) * len; // the stepper number

                      if (from == to) {
                          break;
                      }
                      for (var i = from; small ? i >= to : i <= to; i += small ? -by : by) {
                          stepCounter.push(i);
                      }
                      stepCounter.push(to);
                      lastStepPercent = customStep[step];
                  }
                  stepper();
                  timers[element + prop] = setInterval(function () {
                      stepper();
                      if (stepCounter.length == 0) {
                          clearInterval(timers[element + prop]);

                          calls++;
                          if (calls == nprops) {
                              callback.call(element);
                          }
                      }
                  }, time / stepCounter.length);
                  nprops++;
              })(prop);
          }
      };
      for (var i = 0; i < el.length; i++) {
          animate(el[i], prop, times, callbacks);
      };
      return new DOM(selector); // re-initiate "JavaScript class" for chaining
  }
  this.click = function (fun) {
      var el = selector;
      for (var i = 0, len = el.length; i < len; i++) {
        el[i].onclick = fun.bind(el);
      }
  }
};

为您的库设置变量:

var $ = function (selector) {
    return new DOM(selector);
};

注意我使用了一个单独的函数来执行“类”,因为我认为$应该保持基本功能而只是init函数。

您可以使用以下设置:

$("#click-me").click(function(){
    $(this).animate({
            "opacity": 0
        }, 1000);
    });
});

EXAMPLE (JSFiddle)

这应该对jQuery的语法如何工作有所了解。当然,图书馆不一定非常复杂。库只是一系列功能,使您的开发人员生活更轻松。一旦你有完整的函数集合,即使像下面这样的设置最终也可以被认为是一个库:

$ = {};
$.animate = function (selector, prop, times, callbacks) {
   var el = document.querySelectorAll(selector);
   var animate = function (element, props, time, callback) {
       callback = callback || function () {};
       time = time || 1000;
       var timers = {}, // store the different interval timers so that they can be cancelled
       calls = 0, // numbers of times the call would have been called
       nprops = 0; // number of properties
       for (var prop in props) {
           (function (prop) {
               var edit = prop == "scrollTop" ? element : element.style;
               var stepCounter = [],
                   customStep = props[prop],
                   curr = edit[prop],
                   lastStepPercent = curr == "" ? (prop == "opacity" ? 1 : 0) : curr,
                   measure = prop == "scrollTop" || prop == "opacity" ? "" : "px",
                   stepper = function () {
                       edit[prop] = stepCounter[0] + measure;
                       stepCounter.shift();
                   };
               if (props[prop].constructor == Number) customStep = [props[prop]];
               for (var step = 0, len = customStep.length; step < len; step++) {
                   var from = parseInt(lastStepPercent),
                       to = parseInt(customStep[step]),
                       small = to < from,
                       numOfSteps = small ? from - to : to - from, // get current number of frames
                       multi = 30 * Math.round(parseInt(time) / 1000),
                       by = numOfSteps / (25 + multi) * len; // the stepper number

                   if (from == to) {
                       break;
                   }
                   for (var i = from; small ? i >= to : i <= to; i += small ? -by : by) {
                       stepCounter.push(i);
                   }
                   stepCounter.push(to);
                   lastStepPercent = customStep[step];
               }
               stepper();
               timers[element + prop] = setInterval(function () {
                   stepper();
                   if (stepCounter.length == 0) {
                       clearInterval(timers[element + prop]);

                       calls++;
                       if (calls == nprops) {
                           callback.call(element);
                       }
                   }
               }, time / stepCounter.length);
               nprops++;
           })(prop);
       }
   };
   for (var i = 0; i < el.length; i++) {
       animate(el[i], prop, times, callbacks)
   };
}
$.animate("#id", {
    width: 0
}, 1000);

我使用这个相对复杂的函数只是为了注意如果你正在尝试开发一些困难的东西,那么库可以做很多工作。无论如何,您需要能够体验JavaScript中的高级编程。最后,只要您知道自己要做什么并且在JavaScript中有一些逻辑经验,这并不难。当然,我不是JavaScript的专家,可能有更好的图书馆架构,但我希望这有所帮助。