عام النصي نقر للتسمية في جافا سكريبت (نص لإدخال / النص)

StackOverflow https://stackoverflow.com/questions/1619884

سؤال

وكتابة القطعة لتكون قادرة على إعادة تسمية الملفات عن طريق النقر على اسم النص وإدخال اسم جديد. لم أجد أي حلول جاهزة للاستخدام، وربما يمكنك أن تشير لي إلى واحد؟

وهنا حيث انتهى بي الأمر وأنها لا تعمل: لسبب ما، فقط مربع الإدخال الماضي آخذ في التغير، والأولى والثانية لا يتم الرجوع إليها:

<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>

وشكرا.

هل كانت مفيدة؟

المحلول

وهذه مشكلة ملزمة الكلاسيكية حلقة متغير. انظر هذا السؤال للحصول على بعض المناقشات.

وإغلاق الخاص بك هو غير فعال لأنه يغلق على نسخة من changer في استخدام داخل الحلقة، والتي سوف تغير الحلقة. ربط ذلك، تحتاج إغلاق آخر لأخذ نسخة من الإصدار الحالي من 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))
            );
        };
    };
}

نصائح أخرى

إذا كنت لا تمانع في الاعتماد مسج، لقد استعملت مسج في المكان محرر لتحرير الحقول قبل.

والمشكلة هي أنه عندما أضافت ظائف المستمع هنا النار، أنها تحتوي على كل ما يشير إلى المتغير "المغير" العالمي. في الوقت الذي تطلق حلقة أكملت بالفعل، وهكذا "المغير" يشير إلى العنصر الأخير في الحلقة.

وبالإضافة إلى ذلك، مضيفا المستمعين يمكن أن يكون فوضوي عبر متصفح، انها أكثر أمانا للاستخدام مكتبة مثل مسج أو YUI للقيام بذلك. وهذا أيضا تمكنك من تمرير كائن إلى كل مستمع الحدث (بطريقة عبر متصفح)، وذلك على سبيل المثال يمكن أن تفعله:

for (var i=0; i < 3; i++) {
                var changer = new TextChanger(i);
                YAHOO.util.Event.addListener(changer.textNode, "click", changer.change, changer); 
                ...
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top