Javascript onchange - получить неопределенность при нажатии

Чтобы сделать текст «редактируемым», я написал функцию, которая заменяет текст элементом ввода (шаг 1), а затем (при изменении) заменяет текст значением элемента ввода (шаг 2).

это работает, за исключением следующего сценария: если элемент ввода активен (шаг 1 процедуры) и я нажимаю на элемент ввода, текст (в элементе ввода) заменяется на «неопределенный», и функция не работать нормально больше

<html>
<head>

<title>Test</title>

<script type="text/javascript">
<!--

// global variables for use in (out-of-function) listeners
var changeText_actual;
var changeText_parent;

function changeText(actual) {
    // element representing a textNode
    changeText_actual = actual;
    // element containing the textNode
    changeText_parent = actual.parentNode;

    // create a new html-element to input text
    var textfield = window.document.createElement("input"); {
        textfield.setAttribute("type", "text");
        // text in textNode
        textfield.setAttribute("value", actual.data);
        // listener for when user has finished input (e.g. by pressing return)
        textfield.setAttribute("onchange",
             // if inputText is not empty
             "if(this.value && this.value.length > 0) {"
                 // fill textNode with inputText
            +"    changeText_actual.data = this.value;"
            +"}"
            // remove input-element and put textNode inplace
            +"changeText_parent.replaceChild(changeText_actual, this);"
        );
    }

    // remove textNode and put input-element inplace
    changeText_parent.replaceChild(textfield, changeText_actual);
    // select inputText for faster editing
    textfield.select();
}

//-->
</script>

</head>
<body>

<table border="1"><tr>
<th>1. Text</th><th onclick="changeText(this.firstChild)">2. Text</th><th>3. Text</th>
</tr><tr>
<td>4. Text</td><td>5. Text</td><td>6. Text</td>
</tr></table>

</body>
</html>

Я просто ищу объяснение, а не решение, так как я чувствую себя способным обойти эту проблему, если я знаю, откуда берется «неопределенное» (и где я могу его поймать)


person Hachi    schedule 23.01.2012    source источник
comment
Просто используйте contentEditable, например. <th contenteditable>lolwat</th>   -  person Mathias Bynens    schedule 23.01.2012


Ответы (1)


1\ При первом нажатии на элемент ‹th> его первый дочерний элемент является текстовым узлом. Его атрибут данных "2. Текст". Итак, когда вы ссылаетесь на this.firstChild, это текстовый узел.

2\ Функция changeText будет вызываться с текстовым узлом в качестве параметра, поэтому «фактический» будет текстовым узлом.

Затем вы меняете текстовый узел на текстовое поле.

3\ Когда вы нажимаете на текстовое поле, обработчик onclick его родителя снова выполняется (onclick ‹th>), но на этот раз this.firstChild является тегом ‹input>, поэтому функция будет вызываться с вводом элемент в качестве параметра. параметр «фактический» будет входным элементом. Элемент ввода не имеет атрибута, называемого данными, поэтому в строке

    textfield.setAttribute("value", actual.data);

фактические данные не определены.

Это ответ на ваш вопрос, но я чувствую необходимость прояснить некоторые вещи:

На самом деле вы можете использовать textfield.onclick = function () { ..... }, чтобы написать функцию, которая является гораздо более безопасным способом.

Использование onchange для изменения текстового поля обратно на текст не всегда удобно (например, если вы не хотите ничего менять), вы должны проверить, не теряет ли элемент также фокус (размытие).

person vinczemarton    schedule 23.01.2012
comment
о, я думаю, вы неправильно поняли мой вопрос; Я отредактирую, так будет понятнее - person Hachi; 23.01.2012
comment
Хорошо, я написал краткое описание того, что происходит. - person vinczemarton; 23.01.2012
comment
ах, я забыл о пузырях; поэтому проверка фактического.data делает свое дело; большое тебе спасибо - person Hachi; 23.01.2012
comment
тут ничего не булькает :D, это один и тот же обработчик, вызываемый дважды с разными параметрами. не имеет отношения, но также проверьте это: html5demos.com/contenteditable - person vinczemarton; 23.01.2012
comment
спасибо за дополнения, но на эти шаги влияет остальная часть моего программного обеспечения; это был просто пример, чтобы найти мою проблему - person Hachi; 23.01.2012