`
foxty
  • 浏览: 137162 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

prototype.js类库的一点缺陷。

阅读更多
   自从项目中使用了prototype的类库以后,省去了不少事情。现在在dotnet 平台下开发,ajax框架用的是ajax.net,同时配合prototype类库,感觉还不错。就是ajax.net和asp.net页面class绑定太死了,无法灵活的控制类。

   这几天用到prototyp的Ajax.Updater()方法来动态更新页面上的div块,发现一个问题。比如我需要在当前页面Index.aspx中id为content的div替换成另外一个页面Content.aspx,那么我可以使用方法new Ajax.Updater("content", "Content.aspx")来实现,很快捷,不过这里就出现问题了,假设Content.aspx页面的内容如下:
Content.aspx
<html>
.....
<script type="text/javascript">
    function myFunc()
    {
    ......
    }
</script>
<body>
    <div  onclick="myFunc()">click me
    </div>
</body>
...........     

   
    Index.aspx的代码如下:
  
Index.aspx
<html>
...
<script type="text/javascript" src="prototype.js"></script>
<body>
    <div id="content">
    </div>
<script language="javascripot">
   new Ajax.Updater("content", "Content.aspx");
</script>
</body>
</html>

 
     页面content.aspx的内容确实能够正确无误的出现在Index.aspx中的div内部,可惜的是我们定义在Content.aspx中的js 函数确实无法被触发了。为啥?因为在Index.aspx的js上下文中根本不存在这样的一个函数。Oh,别急,prototype的这个方法提供了多个参数选项。有一个就是evalScript:true/false 的参数。看来就是是否执行js代码了。加上去再说吧。加上去以后的Index.aspx代码如下:
Index.aspx
<html>
...
<script type="text/javascript" src="prototype.js"></script>
<body>
    <div id="content">
    </div>
<script language="javascripot">
   new Ajax.Updater("content", "Content.aspx", {evalScripts:true});
</script>
</body>
</html>

  
    再试试看?God,照样不行,还是那句话,myFunc还是不在当前Index页面的上下文中。仔细看看代码,myFunc是在Content.aspx页面中定义的,所以咋们需要换一个定义的方式,
Content.aspx
<html>
.....
<script type="text/javascript">
    myFunc = function()
    {
    ......
    }
</script>
<body>
    <div  onclick="myFunc()">click me
    </div>
</body>
...........     
   

     这下可以了吧。为什么?function XX是声名一个函数。但是XX = function 则是隐含的生命了一个函数,这样在Index中就可以访问此函数了。嘿嘿,问题解决了吧?happy了吧?这个时候,发现Content.aspx中就那么一个小小的函数不够我用,咱使还需要使用其他的js类myclass.js。恩。这个时候Content.aspx代码如下,同时附上 myclass.js代码:
  
Content.aspx
<html>
<script type="text/javascript" src="myclass.js"></script>
.....
<script type="text/javascript">
    myFunc = function()
    {
         myclass.func();
    }
</script>
<body>
    <div  onclick="myFunc()">click me
    </div>
</body>
...........    
myclass.js
var myclass = new Object();
myclass.func()
{
    alert("func");
}

   
     这个时候你会发现又不行了,js说找不到myclass的定义。头疼吧。。得了,这回prototype 也没设啥参数再让你来设置了,咱还是去看看它代码吧,看看关键的地方:(提示一下,俺是1.40版本的)
  
先奔主题吧,找到Ajax.Updater()的定义
Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
  initialize: function(container, url, options) {
    this.containers = {
      success: container.success ? $(container.success) : $(container),
      failure: container.failure ? $(container.failure) :
        (container.success ? null : $(container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, object) {
      [b]this.updateContent();[/b]    <------ 这里调用更新div内容。往下看。
      onComplete(transport, object);
    }).bind(this);

    this.request(url);
  },

  updateContent: function() {
    var receiver = this.responseIsSuccess() ?
      this.containers.success : this.containers.failure;
    var response = this.transport.responseText;
 
    [b]if (!this.options.evalScripts) [/b] <----哦,如果没设置evalScripts = true 就清空script代码
    {
        response = response.stripScripts();
    }
   
    if (receiver) {
      if (this.options.insertion) {
        new this.options.insertion(receiver, response);
      } else {
        [b]Element.update(receiver, response); [/b]<----这里调用prototype扩展的Element.update函数,看下面。
      }
    }

    if (this.responseIsSuccess()) {
      if (this.onComplete)
        setTimeout(this.onComplete.bind(this), 10);
    }
  }
});


Element.udpater 函数的定义:
  update: function(element, html) {   
    [b]$(element).innerHTML = html.stripScripts();[/b]      <----先把清除掉js代码的html内容加入到elemtn中。(就是你需要更新的div)
    setTimeout(function() {html.evalScripts()}, 10);  <----然后调用html内容中的js代码。
  },

String.evalScripts 函数的定义:
evalScripts: function() {
    [b]//==========edit by foxty  粗线是我加的,先看它原来的定义,最后一句。
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var scripts = this.match(matchAll);
   
    var headEle = document.getElementsByTagName("head")[0];   
    for(var i = 0; scripts && i < scripts.length; i++)
    {       
        var scriptEle = document.createElement("script");
        scriptEle.type = "text/javascript";
       
        var script = scripts[i];
        var res = script.match(/src=\"(.*)\"/ig);
        if(res)
        {
            scriptEle.src = RegExp.$1;
        }else
        {
            //scriptEle.innerText = script;
        }       
        headEle.appendChild(scriptEle);       
    }
    //alert(headEle.innerHTML);
    //==========end [/b] 
    return this.extractScripts().map(eval);  <----这里可以继续找prototype扩展的String.extractScript函数,
发现里面仅仅是对返回内容的js代码块进行了处理,对于引入的js文件并没有做任何处理,"罪魁祸首"就在这里了。没办法,咱只能
自己动手实现了,所以有了上面一段加粗的代码,把返回的html中关于js文件导入的地方全部重新加入到当前文档中去。记住不能
用简单的innerHTML = "...."来实现,那样没有任何效果,只能在当前文档中createElement("script") 然后append到当前文档中。
  },

  
     好了,现在咱们再重新试试看。终于可以在index .aspx中完好无损的调用本身存在于content.aspx中的js函数了。
     结束语:今天为了这个问题花了2个多小时的时间才解决,prototype确实非常实用非常方便,但是这里的处理确不尽人意。或许你会有更好的解决办法。欢迎讨论哈。
分享到:
评论
6 楼 netfishx 2007-01-18  
才发现几个月前的帖子又被翻出来了,innerHTML根本就不是标准的用法,只不过所有浏览器都支持。可惜的是各家的实现方式不同。

具体到这个问题,感兴趣的去看看这篇文章,谈的比较细了
http://homepage.scau.edu.cn/club/scauunit/lbs/article.asp?id=167
5 楼 foxty 2007-01-17  
fujianhua168 写道
我下载的1.4.0里面怎么找不到上述的代码段:
var headEle = document.getElementsByTagName("head")[0];     
    for(var i = 0; scripts && i < scripts.length; i++)  
    {         
        var scriptEle = document.createElement("script");  
        scriptEle.type = "text/javascript";  
         
        var script = scripts[i];  
        var res = script.match(/src=\"(.*)\"/ig); 
        if(res) 
        { 
            scriptEle.src = RegExp.$1; 
        }else 
        { 
            //scriptEle.innerText = script; 
        }        
        headEle.appendChild(scriptEle);        
    } 
    //alert(headEle.innerHTML); 
    //==========end </b>  
    return this.extractScripts().map(eval);  <----这里可以继续找prototype扩展的String.extractScript函数,
?????
   不知道是你的版本有问题还是我的有问题。希望楼主去下载一份最新的源码,再重新试试。
  我想在项目中使用prototype,但又没时间去做相关方面的测试。如果最新的js源码还存在此问题的话,请通知我一声。
   呵呵,先说谢啦。
这些代码是我修改后加上去的.本身prototype是没有这段代码的.
4 楼 fujianhua168 2007-01-17  
我下载的1.4.0里面怎么找不到上述的代码段:
var headEle = document.getElementsByTagName("head")[0];     
    for(var i = 0; scripts && i < scripts.length; i++)  
    {         
        var scriptEle = document.createElement("script");  
        scriptEle.type = "text/javascript";  
         
        var script = scripts[i];  
        var res = script.match(/src=\"(.*)\"/ig); 
        if(res) 
        { 
            scriptEle.src = RegExp.$1; 
        }else 
        { 
            //scriptEle.innerText = script; 
        }        
        headEle.appendChild(scriptEle);        
    } 
    //alert(headEle.innerHTML); 
    //==========end </b>  
    return this.extractScripts().map(eval);  <----这里可以继续找prototype扩展的String.extractScript函数,
?????
   不知道是你的版本有问题还是我的有问题。希望楼主去下载一份最新的源码,再重新试试。
  我想在项目中使用prototype,但又没时间去做相关方面的测试。如果最新的js源码还存在此问题的话,请通知我一声。
   呵呵,先说谢啦。
3 楼 foxty 2006-09-17  
zelsa 写道
http://ajax.org/space/start/2006-01-31/1

PS: ajax后加一个cn,不知道Robbin为什么要把ajaxcn替换成ajax



我是说怎么打不开 。prototype.js中的Ajax.Updater()方法确实能调用innerHTML中的js,不过如果innerHTML中是引入其他的js文件就不行了。我所说的就是要完全解决这个问题。
2 楼 jack 2006-09-17  
http://www.iteye.com/post/139822
哦 我明白我这个问题出在哪里了。并非我原先猜想的那样,只是新生产的javascript代码没有被调用而言
1 楼 zelsa 2006-09-17  
http://ajax.org/space/start/2006-01-31/1

PS: ajax后加一个cn,不知道Robbin为什么要把ajaxcn替换成ajax

相关推荐

    javascript类库prototype.js

    Prototype.js 是一个强大的JavaScript类库,它为开发者提供了丰富的功能,使得创建具有高度互动性和Web2.0特性的富客户端页面变得更为简单。这个库的设计理念是扩展JavaScript的基础对象,提供一套统一且易于使用的...

    prototype_1.7.3.js 最新版本

    《prototype_1.7.3.js:JavaScript框架的里程碑》 在JavaScript的世界里,Prototype库是一个不可或缺的重要组成部分,尤其在Web开发领域,它为开发者提供了强大的功能和便利性。Prototype_1.7.3.js是这个库的一个...

    prototype.js简介

    **描述:** prototype.js 是一个JavaScript库,主要目的是为了简化JavaScript的开发,提升开发效率。它通过扩展JavaScript的基本对象和类型,提供了丰富的功能,包括类式继承、面向对象编程的支持以及一些实用的DOM...

    prototype.js

    《prototype.js:JavaScript框架的核心与应用》 在Web开发领域,JavaScript库和框架极大地提高了开发效率,其中Prototype.js就是一款非常流行的开源JavaScript框架。本文将深入探讨Prototype.js的核心概念、功能...

    prototype.js 1.4-1.6[全]

    《Prototype.js 1.4-1.6:JavaScript 动态原型框架的探索与实践》 Prototype.js 是一个广泛使用的JavaScript库,它扩展了JavaScript语言的功能,为开发人员提供了更强大的面向对象编程支持。该库的核心特性是其对...

    prototype.js 1.6中文手册、prototype.js 1.6英文手册、

    Prototype.js 是一个开源的JavaScript库,它扩展了JavaScript语言,为开发者提供了许多便利的功能,特别是在对象操作、DOM操作和事件处理方面。1.6版本是该库的一个重要里程碑,引入了诸多改进和新特性。 ### 1. ...

    prototype.js文件使用和讲解

    `prototype.js`是一个开源库,旨在扩展JavaScript的基础功能,尤其是面向对象编程的支持。这个库由Sam Stephenson创建,是Prototype Library的一部分,广泛应用于Web应用开发中,尤其在Rails框架下的Ajax开发。 ###...

    prototype.js javaScript插件

    Prototype.js利用这一点来实现类的继承和对象的扩展。 - **扩展JavaScript对象**:Prototype.js提供了一系列方法,如`extend`和`merge`,用于方便地合并和扩展对象属性,使得代码更加简洁和可维护。 - **DOM操作**...

    prototype.js_v1.6_含中英文手册

     prototype.js是一个非常优雅的javascript基础类库,对javascript做了大量的扩展,而且很好的支持Ajax,国外有多个基于此类库实现的效果库,也做得很棒。  prototype.js不仅是一个有很大实用价值的js库,而且有很...

    prototype.js中文手册

    Prototype.js 是一个开源JavaScript库,由Sam Stephenson于2005年创建,主要用于简化DOM(文档对象模型)操作,增强JavaScript的面向对象编程能力,以及提供实用的函数扩展。它在Web开发中扮演着重要的角色,尤其在...

    prototype.js 1.4版开发者手册(强烈推荐)

    《prototype.js 1.4版开发者手册》是JavaScript开发领域中的一个重要参考资料,尤其对于那些希望深入理解并利用Prototype库的开发者来说,它是一份不可多得的资源。Prototype.js是一个强大的JavaScript库,由Sam ...

    prototype.js 1.6

    《Prototype.js 1.6:JavaScript 动态对象增强库的深度解析》 Prototype.js 是一个广泛使用的 JavaScript 库,它为浏览器环境提供了许多实用的功能,尤其是在对象操作和事件处理方面。1.6 版本是该库的一个重要里程...

    prototype.js 实例

    在JavaScript的世界里,Prototype.js是一个著名的库,它扩展了JavaScript的内置对象,为开发者提供了更加便利的编程体验。本实例将深入探讨如何利用Prototype.js来实现弹出窗口和移动窗口的功能,这对于创建交互性强...

    prototype.js jquery.js 打包下载(包含各自的API)

    Prototype.js是最早期的JavaScript框架之一,它的设计目标是增强JavaScript的基本功能,使得JavaScript的面向对象编程更加简洁和强大。Prototype的核心特性包括: 1. **对象扩展**:Prototype通过扩展JavaScript的...

    在vs2005基于prototype.js的模态弹出窗口

    **Prototype.js** 是一个轻量级的JavaScript库,旨在简化DOM操作,提供面向对象的JavaScript编程,并且包含一些实用的辅助函数。在2005年,Prototype.js因其强大的功能和易用性而受到开发者的欢迎,尤其在创建动态...

    prototype.js手册

    万一你没有使用过大名鼎鼎的prototype.js,那么让我来告诉你,prototype.js是由Sam Stephenson写的一个javascript类库。这个构思奇妙,而且兼容标准的类库,能帮助你轻松建立有高度互动的web2.0特性的富客户端...

    prototype(JS类库).rar

    Prototype是一个强大的JavaScript类库,它的出现是为了弥补JavaScript在面向对象编程方面的不足,提供了一套丰富的函数和工具,使开发者能够更高效地编写可维护的JavaScript代码。Prototype的核心理念是通过模拟传统...

    prototype.js.cn.doc.rar

    Prototype.js是一款强大的JavaScript库,由Sam Stephenson开发,旨在简化JavaScript的编程,提供了一系列实用的函数和类扩展,增强了JavaScript的基本功能。这款库的核心理念是通过类原型(Class Prototyping)实现...

Global site tag (gtag.js) - Google Analytics