javascript - JavaScript 中的通用点击重命名脚本(文本到输入/文本框)

标签 javascript textbox input click

编写一个小部件,以便能够通过单击文本名称并输入新名称来重命名文件。我没有找到任何现成的解决方案,也许你可以给我指一个?

这是我最终的结果,它不起作用:由于某种原因,只有最后一个输入框发生了变化,而第一个和第二个输入框没有被引用:

<span id="text_name_0">Hello, world. Click me please.</span>
<input type="hidden" id="name_changer_0" />
<input type="hidden" id="done_changing_0" value="Done"/>
<br/>
<span id="text_name_1">Hello, world. Click me please.</span>
<input type="hidden" id="name_changer_1" />
<input type="hidden" id="done_changing_1" value="Done"/>
<br/>
<span id="text_name_2">Hello, world. Click me please.</span>
<input type="hidden" id="name_changer_2" />
<input type="hidden" id="done_changing_2" value="Done"/>

<script type="text/javascript">

function TextChanger(id) {
    this.textNode = document.getElementById('text_name_' + id);
    this.textValue = this.textNode.firstChild.nodeValue;
    this.textboxNode = document.getElementById('name_changer_' + id);
    this.doneButton = document.getElementById('done_changing_' + id);
}   

TextChanger.prototype.change = function(node) {
          node.textboxNode.setAttribute('value', node.textValue);
          node.textNode.style.display = 'none';
          node.textboxNode.setAttribute('type','text');
          node.doneButton.setAttribute('type','button');
}   

TextChanger.prototype.changeBack = function(node) {
          node.textNode.firstChild.nodeValue = node.textboxNode.value;
          node.textNode.style.display = 'block';
          node.textboxNode.setAttribute('type', 'hidden');
          node.doneButton.setAttribute('type','hidden');
}

for (var i=0; i < 3; i++) {
        changer = new TextChanger(i);
        changer.textNode.addEventListener("click", function() {
            changer.change(changer);
        }, false);

        changer.doneButton.addEventListener("click", function() {
            changer.changeBack(changer);
        }, false);
}
</script>

谢谢。

最佳答案

这是一个经典的循环变量绑定(bind)问题。请参阅this question进行一些讨论。

您的闭包无效,因为它关闭了循环内使用的 changer 副本,循环将更改该副本。要绑定(bind)它,您需要另一个闭包来获取 changer 当前版本的副本:

function changebind(c) {
    return function() {
        c.change(c);
    };
}

for (var i=0; i<3; i++) {
    var changer= new TextChanger(i);
    changer.textNode.addEventListener('click', changebind(changer), false);

(您可能更愿意放弃 node 参数并仅使用 this。)

将来(ECMAScript 第五版),将会有一种更快、更有效的方式来表达:

for (var i=0; i<3; i++) {
    var changer= new TextChanger(i);
    changer.textNode.addEventListener('click', changer.change.bind(changer), false);
    changer.doneButton.addEventListener('click', changer.changeBack.bind(changer), false);
}

但与此同时,由于大多数浏览器尚不支持 function.bind,您可以像这样破解它:

if (!Object.bind) {
    Function.prototype.bind= function(owner) {
        var that= this;
        var args= Array.prototype.slice.call(arguments, 1);
        return function() {
            return that.apply(owner,
                args.length===0? arguments : arguments.length===0? args :
                args.concat(Array.prototype.slice.call(arguments, 0))
            );
        };
    };
}

关于javascript - JavaScript 中的通用点击重命名脚本(文本到输入/文本框),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1619884/

相关文章:

javascript - jquery SlideToggle 在所有打开的 div 上

javascript - 通过 Java 脚本访问 Magento Admin Grid 的对象

javascript - 使用jquery获取容器内文本框的位置

Javascript 问题 - 在 document.getElementById 之后无法提交表单

javascript - Set State形式函数的返回值

javascript - 将事件监听器附加到 DOM,而不是污染全局命名空间

javascript - 通过xslt将xhtml转为javascript输出

c# - 如何在文本框中使用 double?

c# - 使用控制台更改对象变量

java - 如何在JSP中对输入框的文本更改执行查询