Just some sharing about java open source and life

prototype.js 源码之Prototype

日期:2010-09-06 21:00 | 作者:JavaChen | 分类目录:JavaScript
221 views

Prototype is a JavaScript Framework that aims to ease development of dynamic web applications.
Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.
Prototype是一个致力于动态Web应用的开发的JavaScript框架。之前学校jquery源码,无意之中看到了Prototype,于是想看看Prototype是怎样实现的,顺便熟悉javascript的Prototype的概念。

Prototype(1.61版本)源码第一部分就是Prototype的定义:

var Prototype = {
  Version: '1.6.1',

  Browser: (function(){
    var ua = navigator.userAgent;
	//opera浏览器为window定义了一个window.opera的属性,可以通过它来判断浏览器是否为opera。
    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
    return {
   //而ie浏览器是通过对attachEvent这个私有的事件绑定方法的判断来实现的,由于opera也支持attachEvent,
    //所以又进行了!isOpera的判断
      IE:             !!window.attachEvent && !isOpera,
      Opera:          isOpera,
      WebKit:         ua.indexOf('AppleWebKit/') > -1,
      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
      MobileSafari:   /Apple.*Mobile.*Safari/.test(ua)
    }
  })(),

  BrowserFeatures: {
  	//判断浏览器是否支持w3c提供的元素选择器
    XPath: !!document.evaluate,
	//是否支持w3c提供的元素css模式查找功能
    SelectorsAPI: !!document.querySelector,
	//元素是否可以扩展
     ElementExtensions: (function() {
	 //构造函数为element和HTMLElement,ie隐藏了HTMLElement这个类,不能通过代码访问
      var constructor = window.Element || window.HTMLElement;
	  //检查当前浏览器是否支持对元素的原型的扩展
      return !!(constructor && constructor.prototype);
    })(),
    //是否支持特定的元素扩展
    SpecificElementExtensions: (function() {
     //ie6和ie7不可访问HTMLDivElement,ie8和标准浏览器可以对这个类进行扩展,它继承自HTMLElement
      if (typeof window.HTMLDivElement !== 'undefined')
        return true;

      var div = document.createElement('div');
      var form = document.createElement('form');
      var isSupported = false;

	  //检查是否支持__proto__属性,firefox,safari,chrome提供了对prototype对象的访问
      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
        isSupported = true;
      }

	  //释放创建出来的临时元素
      div = form = null;

      return isSupported;
    })()
  },

  //匹配script标签的内容的正则字符串
  ScriptFragment: ']*>([\\S\\s]*?)<\/script>',
  //json过滤
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
  //空函数
  emptyFunction: function() { },
  K: function(x) { return x }
};

关于源码的分析网上有很多,上面代码的分析就基本上来自于这篇文章【prototype.js 源码学习笔记(一)
这一部分内容主要应该就是浏览器判断和prototype版本号的体现。关于浏览器的判断可以参考我之前写过的一篇文章:【JavaScript判断浏览器类型及版本】,这篇文章里列出了各种浏览器的特征及其userAgent,根据userAgent就可以区分出不同的浏览器。
CSS最佳实践就有一点说用特性判断而非浏览器判断,以下就一些特性来区分不同的浏览器。在Prototype的源码中,是通过浏览器各自具有的特性来判断浏览器的类型的。

  • opera浏览器为window定义了一个window.opera的属性,可以通过它来判断浏览器是否为opera。
  • ie浏览器是通过对attachEvent这个私有的事件绑定方法的判断来实现的,由于opera也支持attachEvent,所以又进行了!isOpera的判断。
  • 后面的几个浏览器判断是根据各个浏览器的userAgent来判断的,firefox用的是gecko,safari用的是webkit,chrome则是在webkit和gecko基础上开发的。safari和 chrome可以通过浏览器信息查找到字符串”KHTML”,firefox和chrome可以查找到字符串”gecko”,所以可以通过”gecko”,”KHTML”这几个字符串来区分它们。

Object.prototype.toString.call(window.opera) == ‘[object Opera]‘
该代码的意思是把Object的toString放到window.opera对象上使用,看其toString方法的结果是否等于’[object Opera]‘,关于call 方法的使用,可以参考这篇文章:【JavaScript 中的 call与apply

XPath: !!document.evaluate
!!用来判断某对象是否有某一方法,上例子中如果浏览器不支持document.evaluate方法,那么document.evaluate就会为undefined,而对undefine取反就为false,再一次取反从其结果就知道该对象是否支持某一方法。这样的判断方式比起if else语句,真是要精简巧妙许多!

window.Element || window.HTMLElement
Element除了ie6和ie7其他浏览器都支持(包括ie8),但一个诡异的问题就出了,因为HTMLElement是继承自Element(参考这里:http://www.cnblogs.com/LongWay/archive/2008/10/08/1305952.html),按常理来说支持访问Element就应该也支持对HTMLElement的访问,但是ie8访问HTMLElement却返回”undefined”。我在ie8下alert window.Element 和window.HTMLElement,其结果都为undefined

在DOM标准中,每个HTML元素都是继承自HTMLElement。在IE中将HTMLElement这个类隐藏了,咱们不能直接访问到这个类。除了ie而外的浏览器都能够访问到HTMLElement这个类。

参考文档:
document.evaluate方法的参考见这里http://liudaoru.javaeye.com/blog/129748
SelectorsAPI属性参考资料http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/04/16/document-queryselector-in-ie8.aspx
ElementExtensions是检查浏览器是否可以访问Element或者HTMLElement类,参考这里:http://www.cnblogs.com/LongWay/archive/2008/10/08/1305952.html

作者:JavaChen | 分类目录:JavaScript | 标签:
回到顶部

无觅相关文章插件,快速提升流量