对于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  οnclick="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  οnclick="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  οnclick="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) {
      this.updateContent();    <------ 这里调用更新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;
 
    if (!this.options.evalScripts)  <----哦,如果没设置evalScripts = true 就清空script代码
    {
        response = response.stripScripts();
    }
   
    if (receiver) {
      if (this.options.insertion) {
        new this.options.insertion(receiver, response);
      } else {
        Element.update(receiver, response); <----这里调用prototype扩展的Element.update函数,看下面。
      }
    }

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


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

String.evalScripts 函数的定义:
evalScripts: function() {
    //==========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  
    return this.extractScripts().map(eval);  <----这里可以继续找String.extractScript函数,发现里面仅仅是对页面上的js代码块进行了处理,对于引入的js文件并没有做任何处理,"罪魁祸首"就在这里了。没办法,咱只能自己动手实现了,所有有了上面一段加粗的代码,把返回的html中关于js文件导入的地方全部重新加入到当前文档中去。记住不能用简单的innerHTML = "...."来实现,那样没有任何效果,只能在当前文档中createElement("script") 然后append到当前文档中。
  },
   
     好了,现在咱们再重新试试看。终于可以在index .aspx中完好无损的调用本身存在于content.aspx中的js函数了。
     结束语:今天为了这个问题花了2个多小时的时间才解决,prototype确实非常实用非常方便,但是这里的处理确不尽人意。或许你会有更好的解决办法。欢迎讨论哈。
Re:对于prototype.js类库的一点点质疑。
[ 2006-11-5 13:39:04 | By: Aqing(游客) ]
最简单的解决方法是将Content.aspx中的JS代码全部复制到Index.aspx中.我用Prototype.js中的AJAX.Updater做的三级联动菜单就是这么做的,一直工作得很好.[quote][b]以下为blog主人的回复:[/b] 这样会导致整个index页面中js代码过多,维护起来太麻烦。[/quote]
个人主页 | 引用 | 返回 | 删除 | 回复
Re:对于prototype.js类库的一点点质疑。
[ 2006-9-29 11:32:58 | By: foxty ]

document.write会新建一个document流,会把当前页面本身的内容全部清空,这个肯定是不行的。

而且,我这里所说的其实是关于prototype中的一点点我以为的bug吧。

PS:就是因为不想用js来动态生成dom,所以才想到用局部替换页面来做的,毕竟动态生成dom,调试和维护都非常的麻烦,而且页面上会有很多无法看见的东西。不推荐这么做哈。

个人主页 | 引用 | 返回 | 删除 | 回复
Re:对于prototype.js类库的一点点质疑。
[ 2006-9-21 12:32:10 | By: 昌松 ]

这种情况,看看Swato框架的基础代码

html页面

<link href="/css/autosuggest.css" type="text/css" rel="stylesheet" />
<link href="/css/site.css" type="text/css" rel="stylesheet" />
<link href="/css/logger.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="/jslib/swato.js"></script>

swato.js

var Swato = {
 Version: '0.7',
 Author:'Zhijie Chen (zigzag.chen@gmail.com)'
};

var use = function (url) {
   document.write('<script src="', url, '" type="text/JavaScript"><//script>');
};


use("jslib/json.js");
use("jslib/prototype.js");
use("jslib/logger.js");
use("jslib/swato-engine.js");

同时JSAN这个js框架,可以把前台js当java类包那样管理,看看代码就明白了

 <script type="text/javascript" charset="utf-8" src="../prototype.js"></script>
  <script type="text/javascript" charset="utf-8" src="../JSAN.js"></script>
  <script type="text/javascript">
   JSAN.require('XXXXX.YYYYY.ZZZZZZ');
  </script>
当然你也可以在.js(比如上面的ZZZZZZ.js)文件中头加上这个.js运行所需要的js对象


另:如果前台纯用Ajax作的话,替换页面就不时很必要了,可以写js生成替换的
    如果不是的话,即只是做个小的tip就没必要用上面的东西了

呵呵,以上是我做了查不多一年的小小见解~,希望对你有用。现在偶看到javaScript代码都没感觉料

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JavaScript的Date对象是用来操作日期和时间的对象,它包含了很多有用的方法和属性。其中,Date.prototype.format()方法是一个常用的方法,用于格式化日期为特定格式。 Date.prototype.format()的语法如下: ```javascript Date.prototype.format(format) ``` 其中,format是一个字符串,用于指定输出日期的格式。可以使用以下格式占位符: - "yyyy" 代表年份,例如:"2021" - "MM" 代表月份,例如:"01" 表示一月份 - "dd" 代表日期,例如:"01" 表示第一天 - "HH" 代表小时,24小时制,例如:"12" 表示12小时 - "mm" 代表分钟,例如:"30" 表示30分钟 - "ss" 代表秒钟,例如:"00" 表示0秒钟 以下是一个使用Date.prototype.format()方法的示例: ```javascript let date = new Date(); let formattedDate = date.format("yyyy-MM-dd HH:mm:ss"); console.log(formattedDate); ``` 输出结果将会是类似"2021-07-01 12:30:00"这样的格式化日期字符串。 除了以上示例中的格式以外,还可以根据需要自行组合占位符来定义输出的日期格式。例如,可以使用"yyyy年MM月dd日 HH时mm分ss秒"来定义输出格式为"2021年07月01日 12时30分00秒"。 需要注意的是,Date.prototype.format()方法是自定义的方法,不是原生的JavaScript方法,所以在使用之前需要先定义该方法。 总而言之,使用Date.prototype.format()方法可以方便地格式化日期为指定的格式,提高日期处理的灵活性和可读性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值