Почему этот JavaScript не работает в IE? - PullRequest
0 голосов
/ 14 декабря 2009

Я использую следующий JavaScript для динамического добавления строк в таблицу: -

    var trObj = document.createElement('tr');
    trObj.setAttribute('name', 'dynamicTR');

    var tdObjEmpty = document.createElement('td');
    tdObjEmpty.setAttribute('colspan', '2');
    tdObjEmpty.innerHTML = ' '
    trObj.appendChild ( tdObjEmpty );

    var tdObj = document.createElement('td');
    tdObj.setAttribute('colspan', '15');
    tdObj.innerHTML = postingDivObj.innerHTML; // <-- copy the innerHTML
    trObj.appendChild ( tdObj );    
    parentObj = approvedDisapprovedTableObj.getElementsByTagName('tbody')[0];               
    targetElementObj = getNthTr ( parentObj, rowIndex1 - extraTr ); // <-- it will just return the trObject, 
    if ( targetElementObj ){
        parentObj.insertBefore(trObj, targetElementObj.nextSibling )
    }else{
        //alert ( 'targetElementObj is null' );
    }

Это работает как в FF, так и в IE, [но, я думаю, в случае IE name и colspan атрибут не устанавливается с помощью setAttribute. но не уверен].

Теперь, когда мне нужно удалить все строки, которые создаются динамически, я использую: -

dynamicTRObjs = document.getElementsByName('dynamicTR');
    if ( dynamicTRObjs ){
            parentObj = approvedDisapprovedTableObj.getElementsByTagName('tbody')[0];
            for ( i = 0 ; i < dynamicTRObjs.length; i++ ){              
                parentObj.removeChild ( dynamicTRObjs[i] );          
                extraTr++;
            } 
        }

Этот код удаляет все динамически созданные TR. и он отлично работает в FF, но не в IE.
Также в случае IE dynamicTRObjs.length всегда равно 0, тогда как в FF dynamicTRObjs.length это дает правильное количество строк. Пожалуйста, скажите мне, что мне здесь не хватает.

Ответы [ 4 ]

9 голосов
/ 14 декабря 2009

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

  • Сохраняйте ссылки на все созданные вами TR, чтобы вам не приходилось их искать в DOM
  • Установите className на ваших TR и используйте селекторы, чтобы найти их

То, что Firefox использует getElementsByName «правильно», а IE - это не то, с чем столкнулись другие. Я бы просто не использовал здесь имя .

1 голос
/ 14 декабря 2009

, поскольку я не единственный, кто предлагает избегать низкоуровневых манипуляций с DOM, вот пример: непроверенная реализация с jquery не совсем ответ на ваш вопрос, но комментарий потеряет форматирование.

var mkTd = function (colspan, html)
{
    return $('<td />')
        .attr('colspan', colspan)
        .html(html)
    ;
}

var addRow = function (rowNr)
{
    var target = $('#approvedDisapprovedTableObj tbody tr:eq('+rowNr+')');
    if (!target.length) {
        //alert ( 'target is null' );
        return;
    }
    target.after(
        $('<tr />')
            .addClass('dynamicTR')
            .append(mkTd(2, '&nbsp;')
            .append(mkTd(15, $('#postingDivObj').html()))
    );
}
var dropRows = function ()
{
    $('.dynamicTR').remove();
}

обратите внимание, что выражение $('.dynamicTR').remove() достигает того же значения, что и ваше

dynamicTRObjs = document.getElementsByName('dynamicTR');
if ( dynamicTRObjs ){
    parentObj = approvedDisapprovedTableObj.getElementsByTagName('tbody')[0];
    for ( i = 0 ; i < dynamicTRObjs.length; i++ ){                          
        parentObj.removeChild ( dynamicTRObjs[i] );                      
        extraTr++;
    } 
}

ИМО, очевидно, что преимущества огромны.

1 голос
/ 14 декабря 2009

Я знаю, это немного не по теме, но позвольте мне дать вам небольшой совет по использованию функции getElementsByName в браузере. Это не поможет вам решить текущую проблему (поскольку TR не может иметь атрибута Name), но определенно поможет вам предотвратить будущие проблемы, с которыми вы столкнетесь.

getElementsByName возвращает вашу коллекцию, которая всегда обновляется в соответствии с деревом DOM. Это означает, что в тот момент, когда вы удаляете ОДИН элемент с помощью removeChild, РАЗМЕР коллекции будет уменьшен. Таким образом, если вы удалите узлы и продолжите полагаться на длину коллекции, не все узлы будут удалены.

Проверьте этот пример вашего цикла for:

  • Длина коллекции - 3, Ваш i var равен 0, i <длина <br> Вы удаляете ребенка,
  • длина коллекции равна 2, ваш i var равен 1, i <длина <br> Вы удаляете ребенка,
  • длина коллекции равна 1, а ваш i var i 2.
    Условие i

Выберите любое решение, которое вам нравится, чтобы исправить это, но старайтесь не полагаться на длину Коллекции, возвращаемой getElementsByTagName.

Удачи

1 голос
/ 14 декабря 2009

http://www.quirksmode.org/dom/w3c_core.html

getElementsByName () работает плохо в IE6-8

Я бы предложил вам другой способ идентификации этого элемента, если вы хотите использовать его в разных браузерах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...