JavaScript常用函数库详解

2009年05月22日 由 Bgser 回复 »

在WEB开发中,javascript提供了许多函数供开发人员使用,这些函数在Ajax流行前足够了,但要构建一个交互性强些的应用恐怕就麻烦了,为此,收集了自己平时常用到一些JavaScript函数,它们在其它的JS库也常见,现在整理并附上注释,方便查阅,希望对大家有所帮助。
注:假设以下所有函数都放在一个CC对象中,方便引用。

  //这个方法相信是最常用的了,
  //它虽然没有选择器那么强大,但也有个小增强版,可查指定结点下ID所在的子元素
  function $(id, p) {
     //id是否是字符串,还是一个HTML结点
     var iss = id instanceof String || typeof id == "string";
     if (iss && !p)
         return document.getElementById(id);
     //如果是结点的话就直接返回该结点
     if(!iss)
        return id;
     //如果id与p是同一个元素,直接返回
     if(p.id == id)
        return p;
     //往父结点搜索
     var child = p.firstChild;
     while (child) {
        if (child.id == id)
            return child;
        //递归搜索
        var v = this.$(id, child);
        if (v)
           return v;
        child = child.nextSibling;
       }
    //的确找不到就返回null
    return null;
}
  //Prototype.js里经典的一个函数,将一个可枚举对象数据组成一个数组返回。
  //如arguments参数数组这对象,返回后就可用数组的方法操纵这些数据。
  function $A(iterable){
     if (!iterable) return [];
     if (iterable.toArray) {
        return iterable.toArray();
     } else {
        var results = [];
        for (var i = 0, length = iterable.length; i < length; i++)
            results.push(iterable[i]);
         return results;
     }
  }
each: function(object, callback, args) {
 
  if (!object) {
    return object;
  }
 
  if (args) {
    if (object.length === undefined) {
      for (var name in object)
      if (callback.apply(object[name], args) === false) break;
    } else for (var i = 0, length = object.length; i < length; i++) 
                if (callback.apply(object[i], args) === false) break;
  } else {
    if (object.length == undefined) {
      for (var name in object)
      if (callback.call(object[name], name, object[name]) === false) break;
    } else for (var i = 0, length = object.length, value = object[0];
                    i < length && callback.call(value, i, value) !== false; 
                    value = object[++i]) {}
  }
 
  return object;
}
//数组
function isArray(obj) {
  return (typeof obj === "array" || obj instanceof Array);
},
//字符串
function isString(obj) {
  return (typeof obj === "string" || obj instanceof String);
},
//函数
function isFunction(obj) {
  return (typeof obj === "function" || obj instanceof Function);
},
//数字类型
function isNumber(ob) {
  return (typeof ob === "number" || ob instanceof Number );
}
// 返回表单可提交元素的提交字符串.
// 例如 
//  <form>
//  <input type="text" name="user" value="rock" />
//  <input type="text" name="password" value="123" />
//  </form>
// 调用后就返回 user=rock&password=123
// 这些数据已经过encodeURIComponent处理,对非英文字符友好.
// form元素中如果没有name,则以id作为提供字符名.
function formQuery(f){
  // f,一个Form表单.
  var formData = "", elem = "", f = CC.$(f);
  var elements = f.elements;
  var length = elements.length;
  for (var s = 0; s < length; ++s) {
     elem = elements[s];
     if (elem.tagName == 'INPUT') {
         if ( (elem.type == 'radio' || elem.type == 'checkbox') && !elem.checked) {
              continue;
         }
     }
     if (formData != "") {
        formData += "&";
     }
     formData += encodeURIComponent(elem.name||elem.id) + "=" 
                  + encodeURIComponent(elem.value);
   }
    return formData;
 }
/**
 * 移除数组指定元素.
 * 参数既可传递一个整形下标,也可传递一个数组数据.
 */
Array.prototype.remove = (function(p) {
  //参数为下标
  if (CC.isNumber(p)) {
    if (p < 0 || p >= this.length) {
      throw "Index Of Bounds:" + this.length + "," + p;
    }
    this.splice(p, 1)[0];
    return this.length;
  }
  //参数为数组数据,最终要找到下标来操作
  if (this.length > 0 && this[this.length - 1] == p) {
    this.pop();
  } else {
    var pos = this.indexOf(p);
    if (pos != -1) {
      this.splice(pos, 1)[0];
    }
  }
  return this.length;
});
Array.prototype.indexOf = (function(obj) {
  for (var i = 0, length = this.length; i < length; i++) {
    if (this[i] == obj) return i;
  }
  return - 1;
});
/**
 * 万能而简单的表单验证函数,这个函数利用了JS动态语言特性,看上去很神秘,
 * 实际是很形象的,查看个例子就清楚了.
 */
validate: function() {
  var args = CC.$A(arguments),
  form = null;
  //form如果不为空元素,应置于第一个参数中.
  if (!CC.isArray(args[0])) {
    form = CC.$(args[0]);
    args.remove(0);
  }
  //如果存在设置项,应置于最后一个参数中.
  //cfg.queryString = true|false;
  //cfg.callback = function
  //cfg.ignoreNull
  //nofocus:true|false
  var b = CC.isArray(b) ? {}: args.pop(),
  d;
  var queryStr = b.queryString,
  ignoreNull = b.ignoreNull,
  cb = b.callback;
  var result = queryStr ? '': {};
  CC.each(args,
  function(i, v) {
    //如果在fomr中不存在该name元素,就当id来获得
    var obj = v[0].tagName ? v[0] : form ? form[v[0]] : CC.$(v[0]);
    //console.debug('checking field:',v, 'current value:'+obj.value);
    var value = obj.value,
    msg = v[1],
    d = CC.isFunction(v[2]) ? v[3] : v[2];
    //选项
    if (!d || typeof d != 'object') d = b;
 
    //是否忽略空
    if (!d.ignoreNull && (value == '' || value == null)) {
      //如果不存在回调函数,就调用alert来显示错误信息
      if (!d.callback) CC.alert(msg, obj, form);
      //如果存在回调,注意传递的三个参数
      //msg:消息,obj:该结点,form:对应的表单,如果存在的话
      else d.callback(msg, obj, form);
      //出错后是否聚集
      if (!d.nofocus) obj.focus();
      result = false;
      return false;
    }
    //自定义验证方法
    if (CC.isFunction(v[2])) {
      var ret = v[2](value, obj, form);
      var pass = (ret !== false);
      if (CC.isString(ret)) {
        msg = ret;
        pass = false;
      }
 
      if (!pass) {
        if (!d.callback) CC.alert(msg, obj, form);
        //同上
        else d.callback(msg, obj, form);
 
        if (!d.nofocus) obj.focus();
        result = false;
        return false;
      }
    }
    //如果不设置queryString并通过验证,不存在form,就返回一个对象,
    //该对象包含形如{elementName|elementId:value}的数据.
    if (queryStr && !form) {
      result += (result == '') ? 
         ((typeof obj.name == 'undefined' || obj.name == '') ? obj.id: obj.name) +
                  '=' + value: '&' + v[0] + '=' + value;
    } else if (!form) {
      result[v[0]] = value;
    }
  });
  //如果设置的queryString:true并通过验证,就返回form的提交字符串.
  if (result !== false && form && queryStr) result = CC.formQuery(form);
  return result;
}
/**
 * 应用对象替换模板内容
 * templ({name:'Rock'},'<html><title>{name}</title></html>');
 * st:0,1:未找到属性是是否保留
 */
templ: function(obj, str, st) {
  return str.replace(/\{([\w_$]+)\}/g, function(c, $1) {
    var a = obj[$1];
    if (a === undefined || a === null) {
      if (st === undefined) return '';
      switch (st) {
      case 0:
        return '';
      case 1:
        return $1;
      default:
        return c;
      }
    }
    return a;
  });
}

2009年06月16日已作微调

声明: 转载请注明转自 背光脚本 - www.bgscript.com

4 评论

  1. 侦探 说:

    这个方法多了那个p参数,似乎用处不大,要找p直接document.getelementbyid就好了

  2. Bgser 说:

    P其实可以提高性能,如果知道父结点,子结点ID,那么就可以直接传个P,而不用在全局范围内用getElementById来查找。
    其实在做控件的过程中作用比较大的,同一控件可由不同的HTML模板构成,但一些元素的ID在控件的HTML范围内是唯一的,以便索引到以被绑定一些功能,因为在控件范围内,顶层结点是个P,经常要查找子结点的,这些子结点ID在P范围内是唯一的,但在BODY范围内是可允许多个,这时候就这个P就很有用处了.^-^

  3. topcss 说:

    //数组
    function isArray(obj) {
    return (obj instanceof Array || typeof obj == “array”);
    }
    //字符串
    function isString(obj) {
    return (obj instanceof String || typeof obj == “string”);
    }
    //函数
    function isFunction(obj) {
    return (obj instanceof Function || typeof obj == “function”);
    }
    //数字类型
    function isNumber(ob) {
    return (ob instanceof Number || typeof ob == “number”);
    }

    /*
    看上面的代码:
    楼主严谨的态度值得赞扬。
    其实要判断类型并不需要这么多代码,简单的obj.constructor就轻松搞定,看例子:
    */

    function isNumber(ob) {
    return ob.constructor == Number;
    }

    alert(isNumber(1+’8′));

  4. Rock 说:

    呵呵,我这样也有原因的,参见
    http://www.bgscript.com/archives/647

回复