JavaScript DOM 学习第二章 编辑文本

例子
这个页面就是个例子。点击一个段落,编辑,然后点Ready。你的修改就会呈现。

问题
遇到的第一个问题是:我想用文本框作为编辑区域。一开始我却把内容放不进文本框去。读者发现Mozilla的一个警告说是只有在文本框放置到文档之后才能设置它的value。
另外,在Mozilla下面内容包装的不是很好。我试了好几种wrap参数,但是结果都不是很好。
最严重的问题就是把修改后的内容发回服务器,这是几乎所有的CMS系统都要做的。读者给了我很多高明巧妙的建议。然而因为不能通过JavaScript完成,所以我也不能提供解决办法。所以也请您不要发邮件告诉你找到了办法:那也许可行,但是我只想要纯JavaScript的不需要服务器端代码的方法。

脚本


代码如下:

var editing = false;

if (document.getElementById && document.createElement) {
    var butt = document.createElement('BUTTON');
    var buttext = document.createTextNode('Ready!');
    butt.appendChild(buttext);
    butt.onclick = saveEdit;
}

function catchIt(e) {
    if (editing) return;
    if (!document.getElementById || !document.createElement) return;
    if (!e) var obj = window.event.srcElement;
    else var obj = e.target;
    while (obj.nodeType != 1) {
        obj = obj.parentNode;
    }
    if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;
    while (obj.nodeName != 'P' && obj.nodeName != 'HTML') {
        obj = obj.parentNode;
    }
    if (obj.nodeName == 'HTML') return;
    var x = obj.innerHTML;
    var y = document.createElement('TEXTAREA');
    var z = obj.parentNode;
    z.insertBefore(y,obj);
    z.insertBefore(butt,obj);
    z.removeChild(obj);
    y.value = x;
    y.focus();
    editing = true;
}

function saveEdit() {
    var area = document.getElementsByTagName('TEXTAREA')[0];
    var y = document.createElement('P');
    var z = area.parentNode;
    y.innerHTML = area.value;
    z.insertBefore(y,area);
    z.removeChild(area);
    z.removeChild(document.getElementsByTagName('button')[0]);
    editing = false;
}

document.onclick = catchIt;

解释
我们设置一个editing标志为false。这用来显示用户是否正在编辑段落。当然初始是没有。

var editing=false;

创建一个按钮
然后我们创建一个Radey按钮,后面会需要很多次。这需要一些高级脚本技术,所以先做一些对象检测:

代码如下:

if (document.getElementById && document.createElement) {

如果是现代浏览器,则创建按钮:

代码如下:

var butt = document.createElement('BUTTON');

他的文本是:

代码如下:

var buttext = document.createTextNode('Ready!');

把这个文本添加到按钮上:

代码如下:

butt.appendChild(buttext);

然后添加一个onclick事件处理程序:

代码如下:

butt.onclick = saveEdit; 2 }

现在按钮就存储在butt里面,需要的时候我们就可以直接引用。

将P转为文本框
稍后我们会为整个页面定义一个onclick事件。所有的这些事件都会发送到catchIt()函数。

代码如下:

function catchIt(e){

首先检测用户是否正常编辑段落,如果是,结束函数:

代码如下:

if (editing) return;

然后是支持性检测:

代码如下:

if (!document.getElementById || !document.createElement) return;

然后寻找事件的源:

代码如下:

if (!e) var obj = window.event.srcElement; 2 else var obj = e.target;

现在我们有了事件的源,但是有个问题是Mozilla会认为文本节点是源(而不是我们需要的P节点)。所以如果节点不是标签(nodeType不是1),我们需要向上遍历DOM树:

代码如下:

while (obj.nodeType != 1) { 2 obj = obj.parentNode; 3 }

现在我们以一个标签结束。如果这是一个文本框的标签那么用户点击之后就可以编辑了。如果是一个链接的标签那么用户点击之后应该还是作为一个链接来反映的。这两种情况下我们就不需要这个函数了:

代码如下:

if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;

我们需要再一次的向上遍历DOM树直到找到P标签或者HTML标签:

代码如下:

while (obj.nodeName != 'P' && obj.nodeName != 'HTML') { 2 obj = obj.parentNode; 3 }

如果是HTML标签那么表示用户在段落之外点击的,就结束函数:

代码如下:

if (obj.nodeName == 'HTML') return;

经过这个检测我们最终确定用户点击的是我们想要编辑的段落。然后保存段落的innerHTML:

代码如下:

var x = obj.innerHTML;

创建一个新的TEXTAREA然后保存:

代码如下:

var y = document.createElement('TEXTAREA');

然后找到段落的父节点:

代码如下:

var z = obj.parentNode;

现在就成了这样:

            z
|
---------------------------------------
| | | | |
[more] y(TEXTAREA) butt(BUTTON) P [more]

然后删除段落。现在看起来就好像是文本框和按钮代替了之前的段落。

直到现在,插入文本框之后,我们才能把段落的innerHTML放置在文本框内。Mozilla里面不支持在插入之前给文本框内添加内容。

	y.value = x;

为了用户方便给文本框焦点:

	y.focus();

然后设置editing为true。

	editing = true;
}
将文本框转换为P
当用户点击Ready按钮,就应该反过来了。这个由saveEdit()函数来完成。
function saveEdit() {得到TEXTAREA(这里假设整个页面只有一个TEXTAREA):
    var area = document.getElementsByTagName('TEXTAREA')[0]创建一个新的段落并保存:


代码如下:

var y = document.createElement('P');

找到文本框的父元素:新的段落需要添加到那去:


代码如下:

var z = area.parentNode;

将文本框的值存储在新的段落里:


代码如下:

y.innerHTML = area.value;

然后把新的段落插入在文本框之前:


代码如下:

z.insertBefore(y,area);

移除文本框:


代码如下:

z.removeChild(area);

移除Ready按钮(同样的,假设页面只有一个按钮):


代码如下:

z.removeChild(document.getElementsByTagName('button')[0]);

然后设置editing为false:用户停止编辑:


代码如下:

editing = false; 2 }

事件
在函数之外,设置一个整个页面的onclick事件:


代码如下:

document.onclick = catchIt;

翻译地址:http://www.quirksmode.org/dom/cms.html
转载请保留以下信息
作者:北玉(tw:@rehawk)

(0)

相关推荐

  • JavaScript DOM 学习第二章 编辑文本

    例子 这个页面就是个例子.点击一个段落,编辑,然后点Ready.你的修改就会呈现. 问题 遇到的第一个问题是:我想用文本框作为编辑区域.一开始我却把内容放不进文本框去.读者发现Mozilla的一个警告说是只有在文本框放置到文档之后才能设置它的value. 另外,在Mozilla下面内容包装的不是很好.我试了好几种wrap参数,但是结果都不是很好. 最严重的问题就是把修改后的内容发回服务器,这是几乎所有的CMS系统都要做的.读者给了我很多高明巧妙的建议.然而因为不能通过JavaScript完成,所

  • JavaScript DOM学习第一章 W3C DOM简介

    在这一章我主要介绍已经被新一代的浏览器所支持的W3C 第一级的DOM.对他的运作做一个大概的了解并且让你知道你可以对他们做什么. 首先是对于DOM的一些建议和DOM设计的目的,然后我会告诉你什么是节点(nodes)并且怎样通过DOM树来遍历节点.接着是如何得到一个特定的节点,以及怎样改变他的值和属性.最后就是DOM的终极目标:怎么创建一个自己的新节点. 建议 Level 1DOM是W3C制定的用来提供给任何程序语言来访问XML文档的.不管你用什么语言程序来处理XML文档,只要是Level 1DO

  • JavaScript Event学习第二章 Event浏览器兼容性

    在这里提出的事件,当他们发生在一个确定的HTML元素上的时候,他们的名字能够被大多数的浏览器所识别.也就是说,浏览器会查找你为这个HTML元素所注册的事件处理程序的脚本,而且会被立即执行.      一开始只有为数很少的一些事件.这些事件在几乎所有的JavaScript浏览器都能运行,即使是那些非常古老的.需要注意的是那些早期的事件只能工作在链接或者表单上,有时候也能运行在整个窗口上,但是其他的大多数HTML元素不行.      时代变迁,很多新的事件也给大家介绍过了.第四代浏览器和更高级的浏览

  • JavaScript DOM 学习第九章 选取范围的介绍

    虽然我们会讲解用程序创建范围对象,但是我们把精力主要集中在如何将用户的选取范围转换成为W3C 范围或者微软的文档范围对象. 什么是范围 范围是指HTML文档中的任意一部分内容.一个范围的开始和结束点都可以是随意的,甚至是相同的(一个空范围).最常见的范围就是用户选取的文本.当用户在页面上选取了一部分,你就可以他的选取部分转换为范围对象.然而,你也可以让程序自动选择范围. 让我们以下面的代码为例.假设用户选择了下面的文字: <h4 id="entry1196"><a h

  • JavaScript DOM 学习总结(五)

    1.DOM简介. 当页面加载时,浏览器会创建页面的文档对象模型(Document Object Model).文档对象模型定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构,即节点树.通过DOM,JS可创建动态的HTML,可以使网页显示动态效果并实现与用户的交互功能.JS能够改变页面中所有的HTML元素.属性和CSS样式,并对页面中所有事件做出响应.所以学习JS的起点就是处理网页,处理网页就需要使用DOM进行操作. 2.DOM获取元素. JS要想操作H

  • JavaScript DOM 学习第五章 表单简介

    因为每一个表单的检测项都不同,所以我也不能给你一个万能的代码.你需要用我在这一章介绍的这些元素构建自己的检测函数.我在后面一张还有一个例子,你也可以参考. 在这一章我会首先讨论一下用JavaScript来检测表单的局限性,然后会解释一下提交时间处理程序,然后是表单本身的一些方法和属性.最后就是如何访问表单元素. 这里还有一篇Jeff Howden的介绍表单的使用错误和解决办法.Forms & JavaScript Living Together in Harmony局限性 首先,你需要了解当用户

  • JavaScript CSS修改学习第二章 样式

    另外,有时候你也许想知道添加到一个元素或者链接上的样式的具体内容.而style属性只能读取元素的内联形式的样式,所以如果你想读取其他样式就得另想办法了. 偏移 在使用一些小技巧之前,IE和Mozilla已经添加了一个比较好的办法:offsetSomething.使用这些属性你就能够读取这个段落现在的一些比较重要的样式. 举个例子,使用offsetWidth.你就能知道这个段落现在的宽度的像素值.为了测试,你可以改变一下窗口的大小然后再运行一下. 代码也非常的简单: 复制代码 代码如下: func

  • JavaScript DOM学习第四章 getElementByTagNames

    getElementByTagNames(注意是复数的names)会获得一些tag的元素,然后按照他们的顺序保存在一个数组中.这非常的有用,比如在上一章的TOCScript中,就需要获得整个文章里面的所有的H3和H4. 我非常希望在node原型中加入这个功能,但是在IE和Safari里面不行.所以只能把他当做一个普通函数. 使用 getElementByTagNames有两个参数: 1.一个用逗号分隔的tag名称字符串. 2.一个可选的开始元素.如果存在则在该元素的子元素中查找这些tag,如果不

  • JavaScript DOM 学习第三章 内容表格

    如果你也想这么做,那么你还需要我的getElementByTagNames()函数. 复制代码 代码如下: function createTOC() {     var y = document.createElement('div');     y.id = 'innertoc';     var a = y.appendChild(document.createElement('span'));     a.onclick = showhideTOC;     a.id = 'content

  • JavaScript DOM 学习第七章 表单的扩展

    想法 假设你有一个在线的CD评级工具.你希望用户查看他们喜欢的所有CD.但是你怎么知道用户平均会查看多少张呢?你在这个页面上需要添加多少字段呢? 在W3CDOM出现之前这确实是一个问题.假设你放置了7张CD.但是用户很可能只想查看一张,太多可能会吓着用户,而有些用户想查看自己的所有CD,这样就不得不反复提交很多次.这确实很烦人. 只有使用W3C DOM才能让用户决定生成多少个字段.这个效果和之前的大不相同. 例子 当你点击发送的时候,表单就会把得到的所有参数以数组的形式发送.这用来检查是否真正的

随机推荐