-
2008-09-21
编写运行按钮程序笔记 - [web前端]
概要:
- FF中nodevalue对textarea的不同,节点的访问。
- FF中实现把内容复制到剪切板
- FF中实现innerText方法
- Mozilla__defineGetter__、__defineSetter__方法追加定义
在论坛中我们经常遇到诸如下图的运行按钮

如今想要在页面中也实现这样的功能,编写了一段js代码。
1.runCode()函数
function runCode(obj)
{
var code=obj.form.elements[0].value;
/* x=obj.parentNode.childNodes;
for(i=0;i<x.length;i++)
{
if(x[i].nodeName=="TEXTAREA")
{code=x[i].firstChild.nodeValue;
break;
}
}*/
newWindow= window.open('', "_blank", '');
newWindow.document.open('text/html', 'replace');
newWindow.opener = null;//防止更改原页
newWindow.document.write(code);
newWindow.document.close();
}
首先是获得textarea中的内容,我开始时使用的getElementsById但是当页面中有多个textarea时,要一个一个的传入id就会比较麻烦。想到了this关键字,使用核心Dom方法,有了如下代码:
x=obj.parentNode.childNodes;
for(i=0;i<x.length;i++)
{
if(x[i].nodeName=="TEXTAREA")
{code=x[i].firstChild.nodeValue;
break;
}
}在IE中运行正确,可在FF中问题就来了。通过nodeValue获得是textarea中的默认内容,无法获得其现行值。
随改变方向,使用了:obj.form.elements[0].value;利用textarea的value属性。
剩下的就简单了,利用open方法打开页面,装入代码,然后关闭。2.copyCode()函数
function copyCode(obj)
{
var copyText=obj.form.elements[0].value;
if (window.clipboardData)
{
window.clipboardData.setData("Text", copyText)
}
else
{
var flashcopier = 'flashcopier';
if(!document.getElementById(flashcopier))
{
var divholder = document.createElement('div');
divholder.id = flashcopier;
document.body.appendChild(divholder);
}
document.getElementById(flashcopier).innerHTML = '';
var divinfo = '<embed src="http://rong179.blogbus.com/files/12219139100.swf" FlashVars="clipboard='+encodeURIComponent(copyText)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
document.getElementById(flashcopier).innerHTML = divinfo;
}
//alert('copy成功!');
}在IE中很容易实现,在FF中实现就不是那么容易了,搜索了一下解决方法:
借助阿里妈妈的复制广告代码到剪贴板的功能,利用一个flash文件实现。3.ShowRunCode()函数
if(navigator.appName.indexOf("Explorer")==-1)
{HTMLElement.prototype.__defineGetter__
(
"innerText",
function ()
{
var anyString = "";
var childS = this.childNodes;
for(var i=0; i<childS.length; i++)
{
if(childS[i].nodeType==1)
anyString += childS[i].tagName=="BR" ? '\n' :childS[i].innerText;
else if(childS[i].nodeType==3)
anyString += childS[i].nodeValue.replace(/\n/g,"");
}
return anyString;
}
)
}
//替换code代码window.onload=
function showRunCode()
{
var x=document.getElementsByTagName("code");
for(var i=0;i<x.length;i++)
{
//var text=navigator.appName.indexOf("Explorer") > -1?x[i].innerText:x[i].textContent;
x[i].innerHTML='<form id="code" method="post" action=""><textarea name="code" id="codetext" cols="70" rows="10">'+x[i].innerText+'</textarea><input type="button" name="start" value="运行代码" onClick="runCode(this)" class="button2" /><input type="button" name="copy" value="复制代码" onClick="copyCode(this)" class="button2" /><span>提示:您可以先修改部分代码再运行</span></form>'
}
}有 了上面的两个函数,在页面中调用就over了。但是在写日志的时候,每次要加入代码,还得添加form ,textarea那样的标签,太麻烦了。所以就写了这个函数,只要把代码放在<code></code>之间,就搞定了。就像 论坛上的[html][/html],不过比它还是麻烦些,要在页面源码中加入标签。
主要应用innerText,和innerHtml方法。
问题又来了,众所周知innerText在FF中不支持的,FF有个方法:textContent。可以实现,但是,textContent有些缺点,比如会把空格,换行符省略掉。尤其是对<br>的处理,使得在页面显示时会显得很乱。
好在FF中有__defineGetter__、__defineSetter__方法来追加定义。
最后就是加载了,让页面在载入是执行fresh函数,你肯定会想到onload事件,不错。但是,在实际页面中由于onload要在页面完全装入后才会执 行,而页面有些内容,可能会加载很慢,使得fresh函数会隔很长时间才执行,影响效果。所以,用到了img的onerror事件,在页面靠前的位置插入 如下代码
<img src="" onerror="fresh()" style="display:none;" />
就能保证在图像载入出错时,完成函数的加载。最终效果:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<meta http-equiv="Description" content="运行、复制按钮的实现" />
<meta content="all" name="robots" />
<meta name="author" content="rong179,rong179@yahoo.cn" />
<meta name="copyright" content="http://rong179.blogbus.com" />
<title>运行、复制按钮的实现</title>
</head>
<body>
<div id="container">
<img src="http://rong179.blogbus.com/files/12218497280.png" />
</div>
</body>
</html>随机文章:
动态下拉菜单编写笔记 2008-11-18line-height IE中的一点问题 2008-10-28(X)HTML Strict 下的嵌套规则 2008-09-28establish a new block formatting context 2008-07-24Clear Floats 2008-07-22






