如何创建个人JavaScript库和框架

How to create personal JavaScript library and framework?

本文关键字:JavaScript 框架 何创建 创建      更新时间:2023-09-26

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

首先,你需要知道你想要你的库做什么。从那时起,你需要能够知道如何做你试图构建的东西。例如,如果你想制作一个游戏库,你最好了解你的方程式,并擅长Canvas和WebGL等东西。我以前为String、Array、Objects等创建过一个方法库。我完成了,但遗憾的是,我从未完成文档。

无论如何,我基本上是从创建一个"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);
    });
});

示例(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方面的专家,可能有更好的库架构,但我希望这会有所帮助。