编写一个小部件,以便能够通过单击文本名称并输入新名称来重命名文件。我没有找到任何现成的解决方案,也许你可以给我指一个?
这是我最终的结果,它不起作用:由于某种原因,只有最后一个输入框发生了变化,而第一个和第二个输入框没有被引用:
<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/