2009-03-04 3 views
9

Я написал несколько Javascript, чтобы редактировать список элементов в HTML-форме, включая добавление и удаление элементов. Получил его работу в Firefox. При попытке использования в Internet Explorer я обнаружил, что любые добавленные элементы не были отправлены с формой.IE не отправляет; динамически добавленные элементы формы; это ошибка IE?

Длинный рассказ короткий ... много упрощения, отладки, выяснили, какая строка запускает IE, чтобы игнорировать ввод новой формы. Поэтому проблема поведения решена.

Но теперь я должен спросить: почему? Это ошибка IE?

Вот упрощенный код:

<html> 
<head> 
    <title>Test</title> 
    <script type="text/javascript"> 
     function add() { 
      div = document.getElementById("mylist"); 

      // *** Adding text here works perfectly fine. *** 
      div.innerHTML += " "; 

      e = document.createElement("input"); 
      e.setAttribute("type", "text"); 
      e.setAttribute("name", "field3"); 
      e.setAttribute("value", "--NEWVALUE--"); 
      div.appendChild(e); 

      // *** Adding text here works perfectly fine in Firefox, but for 
      //  Internet Explorer it causes field3 to not be submitted. *** 
      //div.innerHTML += " "; 
     } 
    </script> 
</head> 
<body> 
    <form action="" method="get"> 
     <div id="mylist"> 
      <input type="text" name="field1" value="value1" /> 
      <input type="text" name="field2" value="value2" /> 
     </div> 
     <a href="javascript:" onclick="add()" />Add</a> 
     <input type="submit" value="Submit" /> 
    </form> 
</body> 
</html> 

Чтобы попробовать его, сделать очевидное: нагрузка в IE, нажмите кнопку Добавить, нажмите кнопку Добавить, посмотрите, что в адресной строке. Если вы раскомментируете последнюю строку в add(), IE внезапно прекратит сообщать field3. Он отлично работает в Firefox.

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

ответ

7

Является ли это ошибка IE?

Кажется, что так. Когда вы создаете элемент ввода < через методы DOM, IE не совсем подбирает атрибут «name». Это нечто вроде того, что элемент действительно представляет, но если вы попытаетесь получить представление «innerHTML» элемента, оно таинственно исчезнет. Этого не происходит, если вы создаете элемент, написав непосредственно на innerHTML.

Также, если вы используете методы навигации формы DOM Level 0, такие как «myform.elements.x.value», доступ через массив «elements» может не работать (аналогично, прямой доступ «myform.x» к некоторым людям ошибочно использует). В любом случае в эти дни вы можете предпочесть getElementById().

So использование внутреннегоHTML или использование методов DOM; лучше не смешивать их при создании полей формы.

Это documented (see ‘Remarks’) и, наконец, исправлено в IE8.

В любом случае, никогда не делать:

div.innerHTML + = '...';

Это лишь синтаксический сахар для:

div.innerHTML = div.innerHTML + '...';

Другими словами, он должен сериализация все содержание ребенка HTML элемента, затем сделать конкатенацию, а затем повторно проанализировать новую строку обратно в элемент, отбрасывая все оригинальное содержание. Это означает, что вы теряете все, что не может быть сериализовано: а также поддельные атрибуты «имя» IE, которые также означают любые обработчики событий JavaScript, DOM Listeners или другие пользовательские свойства, которые вы привязали к каждому дочернему элементу. Кроме того, медленный цикл сериализации/разбора медленный.

3

IE очень придирчив к изменению некоторых встроенных свойств во время выполнения. Например, имя элемента ввода не может быть изменено во время установки.

Две вещи, которые я хотел бы попробовать, если я вам:

  1. Вместо использования setAttribute(), попытайтесь установить свойства name, type и value явно:

    e.name = "text";

  2. Если это Безразлично Не работает, возможно, вам придется включить все эти атрибуты в вызов document.createElement():

    var e = document.createElement("<input type='text' name='field'>");

    Это может фактически вызвать исключение в некоторых браузерах. Таким образом, лучший способ переходов между браузерами:

.

var e; 
    try { 
    e = document.createElement("<input type='text' name='field'>"); 
    } catch (ex) { 
    e = document.createElement("input"); 
    e.type = 'text'; 
    e.name = 'field'; 
    } 
    e.value = 'value'; 
+0

+1 об избежании SetAttribute. -1 на вызове createElement-with-markup, который является грубым уродливым взломом только для IE. – bobince

+0

Я согласен с тем, что это взлом - вот почему я предлагаю, чтобы плакат попытался установить свойства в первую очередь. Если это не сработает, я не вижу другого способа сделать то, что он хочет. – levik

3

Благодарим вас за bobince и levik. Используя эти и некоторые дополнительные эксперименты, вот мои выводы:

  1. Да, это ошибка IE.

  2. IE 8 исправляет ошибку в соответствии с Microsoft: «Internet Explorer 8 и более поздние версии могут устанавливать атрибут NAME во время выполнения элементов, динамически созданных с помощью метода createElement».

  3. Ошибка: Вызов e.setAttribute("name", "field3") только вид устанавливает имя. Он будет работать, если ничего не произойдет с элементом, но если его попросят сериализовать, имя не будет сериализовано. Поэтому, когда я сказал innerHTML += " ", который заставил сериализацию, которая потеряла имя, поэтому она не была восстановлена ​​при десериализации. Нет имени, без включения в подачу формы.

  4. Обходное решение № 1: e = document.createElement("<input name='field3' />") будет работать даже при столкновении.

  5. Обходное решение # 2: Вместо добавления текста с использованием innerHTML + =, я могу добавить текстовый элемент следующим образом: div.appendChild(document.createTextNode(" "));. Я понял, что должен быть лучший способ добавить текст, и теперь я это знаю :-).

Приветствия,
--jsf

+0

Я добавляю несколько элементов через document.createElement, и каждый элемент имеет несколько атрибутов. Один атрибут - это идентификатор. У меня также есть функция javascipt на той же странице, которая захватывает идентификатор через document.getElementById (ID) и innerHTML. Как я могу ссылаться или захватывать правильный элемент на основе идентификатора элемента, который был динамически создан?Я использую IE 8..works в Firefox :) – Jim

Смежные вопросы