2007年2月9日

令人费解 [a href="javascript:void(0)"] 问题

当我们做一个复杂的HTML和脚本应用的时候,在表现一个链接但又要执行一段javascript代码的时候,大多我们这样做

<href="javascript:void(0)" onclick="click_handle()">链接1</a>
<href="javascript:click_handle()" >链接2</a>
<href="javascript:void(click_handle())" >链接3</a>
这样做的好处是可以使用链接的css自带样式并且使HTML代码看起来更规范。使用void可以防止函数返回值影响链接地址,看来这个方案是“无懈可击”了,因为大家也都是这样做的。 但是今天我碰到了一种情况让人十分困惑,在IE6中如果你的页面有一个Window Media Player控件,并且同时使用上面的方案时,你会发现但点击过链接后会导致正在播放/暂停的文件变成了“停止”状态。当我发现这个问题的原因是因为链接上有javascript:字样而导致的时候真是十分狼狈了,因为我的树型控件,日期控件,下拉控件都使用了上面的方案。 但问题出现了,就要解决它,我最先想到的是,用无址链接#代替javascript:
<href="#" onclick="click_handle()">链接1</a>
但随后我发现URL后始终跟着一个#,我们知道#NO是代表页面的一个书签,在如今ajax的时代它更是被“利用”上了,尽管我对这种使用方式的使用是否合理表示怀疑,因为它似乎破坏了HTML的本身的结构,但毕竟如今许多主流AJAX框架运用了这种方式。所以就要去掉它以保护我们的URL:
<href="#" onclick="click_handle();event.cancelBubble = true;return false;">链接1</a>
这样就可以防止URL上出现#,当然你也可以这样声明一个方法
<href="#" onclick="return click_handle();">链接1</a>
function click_handle (e) {
  
  
//end of the method
  if (!e) {
    e
=window.event;
  } 
  event.cancelBubble 
= true;
  
return false;
}
至此问题似乎解决了,不过增加了代码量,此方案也值得考究。如果我发现新的方案,会及时给出。

2007年2月5日

如何方便的显示页面的Xml对象数据

我们在做javascript/ajax开发的时候经常要处理Xml对象数据,有时候我们要跟踪一个这对象的某个节点的值是什么。一种传统的方式就是我们在页面中加入

alert(xxx);
而这样被alert出来的数据由于没有一个xml解析器的帮助当文档比较庞大的时候就很难找到并知道自己需要的部分是否正确。 当然我们也可以使用Visual Studio、Venkman这样的工具进行代码的跟踪。但是这样效率又比较低,影响开发速度。 实际上无论是IE,还是Firefox都可以对一个xml提供一个“树”的解析结构。同时对于弹出一个窗口我们可以用
window.opener
window.opener.xxx
来获取弹出它的父窗口。并可以索引到任何在父窗口全局范围内可以访问到的变量、对象,方法返回值等。 根据上面的思路我们就来实现一个可随时观看页面xml的模型。(注:C#实现) 效果如下: 首先我们创建一个xml.aspx文件在页面加入如下脚本
   function getRequestString(sName){
        
var _arr = location.search.substring(1).split('&');
      
var n= _arr.length;
      
for(var i=0;i<n;i++){      
        
if(_arr[i].split("=")[0]===sName) {
          
var t = _arr[i].split("=")[1];
          
try {
            t 
= decodeURI(t);
          } 
catch (ex){}
          t 
= unescape(t);
          
return t;
        }
      }
      
return null;
      }     
      
        
function FixPrototypeForGecko(){ 
          Object.prototype.__defineGetter__(
"xml"function () {
            
return (new XMLSerializer()).serializeToString(this);
          });
        }
        
        
function loaded()
        {
         
if(window.addEventListener&&!document.all){
             FixPrototypeForGecko();
           }
           
           
        
try{              
            eval(
"var ttt = window.opener."+getRequestString("xml")+";");        
            
if(typeof ttt == "string"){
                document.getElementById(
"xmlFiled").value = "<html><![CDATA[" + ttt + "]]></html>";
            }
else{
                
if(typeof ttt != "undefined") {        
                  document.getElementById(
"xmlFiled").value = ttt.xml;                  
                }
else{
                  document.write(
"父文档并没有这样的数据!");
                  
return;
                }
            }            
          }
catch(e){
            alert(
"发生错误:非法的访问,此页将被关闭!");
            
try{
              window.opener 
= "";
            }
catch(ex){}
            window.close();
            
return;
          }
      
          ttt 
= null;
          document.getElementById(
"Form1").submit();
      }
在body标签上加上
<body onload="loaded();">
然后进入cs文件在Page_Load下加入
if (this.Page.IsPostBack)
      {
        
string _text = "";
        
if (xmlFiled.Value.IndexOf("<?"== 0)
        {
          _text 
= xmlFiled.Value;
        }
        
else
        {
          _text 
= "<?xml version=\"1.0\" ?>" + xmlFiled.Value;
        }
        Response.Write(_text);
        Response.ContentType 
= "text/xml";
        Response.End();      
      }
      
else if (Request["xml"== null || Request["xml"== string.Empty)
      {
        Response.Write(
"参数不正确!");
        Response.End();
      }
在使用的时候只要在要跟踪的文档上加入
function showXml(sXmlVariable){
  
try{
      
var tOpenXml = open("../@Files/xml.aspx?xml="+sXmlVariable);    
    }
catch(ex){
      alert(ex.message);
    }
}
这个方法,在适当的时候调用就可以了,sXmlVariable是一个可以在全局范围内可以访问到的任何变量、对象、方法返回值等。

2007年2月2日

外语学习:满城尽带黄金甲

相信大家都看过这部电影了,不过我可不是要讨论它的剧情。我们是来研究一下它这个“有趣”的名字。 据说官方的英文名字是:Curse of the Golden Flower,那么这个翻译成中文会是什么样呢? 诅咒的金花(来自Google translate)太直白了也语义不通,curse 还有“祸根”之意,以我的翻译可以是都是金花惹得祸,如果夹杂着剧情就是祸起菊花。如果是日语可能是:金花により災害を引き起こした 如果直译成英语应该是:The entire city makes armored of the gold armor, 直译成日语就是:全体の都市は金の装甲とする