IE не желал новой строки на TD, динамически добавляемый с Javascript - PullRequest
3 голосов
/ 24 января 2012

Я написал JS-скрипт для динамического добавления строк в таблицу.При изменении элемента select этот сценарий читает HTML-код div, заданный для отображения: none, и клонирует этот шаблон с помощью метода CloneNode (True).Затем он добавляет этот новый объект перед заполнителем.

Вот мои коды HTML + Javascript:

<script type="text/javascript" src="./js/getElementsByClassName-1.0.1.js"></script>
<script language="JavaScript" type="text/javascript">

var browser     = '';

function checkBrowser() {

var version     = '';
var entrance    = '';
var cond        = '';
// BROWSER?
if (browser == ''){
    if (navigator.appName.indexOf('Microsoft') != -1)
    browser = 'IE'
else if (navigator.appName.indexOf('Netscape') != -1)
    browser = 'Netscape'
else browser = 'IE';
}
if (version == ''){
    version= navigator.appVersion;
    paren = version.indexOf('(');
    whole_version = navigator.appVersion.substring(0,paren-1);
    version = parseInt(whole_version);
}
//if (browser == 'IE' && version >= 4) document.write('<'+'link rel="stylesheet" href="ie.css" />');
//if (browser == 'Netscape' && version >= 2.02) document.write('<'+'link rel="stylesheet" href="nn.css" />');
return browser;

}


var counter = 0;

function addRow() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
//alert(newFields.innerHTML);
//newFields.style.display = 'block';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
    var theName = newField[i].name
    if (theName)
        newField[i].name = theName + counter;
}

var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);

 }

 function deleteRow() {
try {
    var element;
    var removeHere=document.getElementById('writeroot');
    var oldCounter=counter;
    for (var i= 0; i<removeHere.parentNode.childNodes.length && counter>1; i++) {
        if(removeHere.parentNode.childNodes[i].nodeName=='DIV')
        {
            for(var k=0;k< removeHere.parentNode.childNodes[i].childNodes.length;k++)
            {
                element=removeHere.parentNode.childNodes[i].childNodes[k];
                if(element.checked)
                {
                    removeHere.parentNode.removeChild(removeHere.parentNode.childNodes[i]);
                    counter--;
                    i--;
                    break;
                }       
            }
        }       
    }
    removeHere.parentNode.childNodes.length-=(oldCounter-counter);
    /*
    if(counter==1)
    {
        alert("Non è possibile eliminare tutte le indagini nella richiesta di preventivo. Se non si vogliono specificare indagini, scegliere INFORMAZIONI nel campo TIPO RICHIESTA");
    }       */
}catch(e) {
    //alert(e);
}   
}



function changeRows(obj)
{   

if(obj.value=="preventivo")
{
    if(counter==0)
        addRow();
    if(checkBrowser()=='IE'){
        //caso IE
        try{
            list=getElementsByClassName("campiPreventivo");
            for (var i = 0; i < list.length; i++)
            {
                if(list[i].nodeName=='DIV') {
                    list[i].style.display="block";
                }
                else {
                    list[i].style.display="table-cell";
                }
            }
        } 
        catch(err) {
            //alert(err);
        }

    }
    else {

        var list = document.getElementsByClassName("campiPreventivo");
        for (var i = 0; i < list.length; i++)
        {
            if(list[i].nodeName=='DIV') {
                list[i].style.display="block";
            }
            else {
                list[i].style.display="table-cell";
            }
        }
    }   

}
else {

        if(checkBrowser()=='IE'){
        //caso IE
            try{
                list=getElementsByClassName("campiPreventivo");
                for (var j = 0; j < list.length; j++)
                {
                    list[j].style.display="none";
                }
            } 
            catch(err) {
                //alert(err);
            }

        }
        else {

                var list = document.getElementsByClassName("campiPreventivo");
                for (var k = 0; k < list.length; k++)
                {
                    list[k].style.display="none";
                }
        }

        try {
            var removeHere=document.getElementById('writeroot');
            //var oldCounter=counter
            for (var z= 0; z<removeHere.parentNode.childNodes.length; z++) {
                if(removeHere.parentNode.childNodes[z].nodeName=='DIV')
                {
                }       
        }

        counter=0;
        }catch(e) {
            //alert(e);
        }   
    }

}       



</script>

</head>

<body>


<div id="main"> 
    <div id="content">

    <div class="contentTxtStyle"><font style="font-size:24px; text-decoration:underline; padding-left:30px ">Contatti</font><br><br>
    <img class="contattiContentImg" alt="Chiedere descrizione" src="img/logo.png">
    <div id="qrDescription">Aggiungi EmmeElle ai  contatti con il codice QR.</div>
    <div id="appLinkDesc">Non hai una app per i QR code? Ottienila gratuitamente dal tuo market.</div>
    <a href="http://qr.ai/uq"><img class="marketLogo1" alt="QR Droid su Android Market" src="img/android market.jpg"></a>
    <a href="http://itunes.apple.com/app/i-nigma-4-qr-datamatrix-barcode/id388923203?mt=8"><img class="marketLogo2" alt="I-nigma su APPSTORE" src="img/appstore.jpg"></a>
    <a href="http://appworld.blackberry.com/webstore/content/27049?lang=en"><img class="marketLogo3" alt="I-nigma su BlackBerry App World" src="img/BB-App-World-Logo.jpg"></a>
    <a href="http://windowsphone.com/s?appid=828c4e78-1d2b-4fd2-ad22-fde9c553e263"><img class="marketLogo4" alt="I-nigma per Windows Phone" src="img/Windows-Phon01.png"></a>
    <b> <font style="font-size:115%"> EmmeElle </font> <br> 
    di Matteo Mantovanelli e Lorenzo Cinti</b>
    <br><br>
    Via I Maggio, 15 - 50022 - Greve in Chianti (Fi)
    <br><br>
    <i>Email:</i><br>
    <a href="mailto:lorenzo@geoemmelle.it">lorenzo@geoemmelle.it</a><br>
    <a href="mailto:matteo@geoemmelle.it">matteo@geoemmelle.it</a><br>
    <br>

    <i>Tel:</i><br>        
    <table border="0">
        <tr>
            <td>Dott. Geol. Lorenzo Cinti</td>
            <td width="150" align="right">+39 328 4896574</td>
        </tr>
      <tr>
        <td>Dott. Geol. Matteo Mantovanelli</td>
        <td width="150" align="right">+39 328 2824617</td>
      </tr>
    </table>
    <img class="contattiQRCode" alt="Contatto in QR Code" src="img/contattoQR.png"> <br>

    <i>Web:</i><br>
    <a href="http://www.geoemmelle.it">WWW.GEOEMMELLE.IT</a>

    <br><br><br><br>
    Per qualsiasi domanda o per richiedere un preventivo potete contattarci ad uno dei recapiti sopra elencati oppure compilare il modulo sottostante.
    <br><br>

    <h2>Richiesta informazioni e preventivi</h2>

    <div id="readroot" style="display: none">
        <TR>
            <TD width="80" align="center"><INPUT type="checkbox" name="chk_cancella"></TD>
            <TD width="215"><INPUT type="text" name="indagine" size="34"></TD>
            <TD width="70" align="center"><input type="text" name="qta" value="1" size="1" maxlength="2" onKeyPress="return numbersonly(this, event)"></TD>
        </TR>

    </div>


     <div id=formDiv>                
            <form name="contactForm" action="php/mail.php" onsubmit="return validateForm()" method="post">
                <table width="668" border="0" cellpadding="0" cellspacing="0" id="formTable">
                    <tr>
                        <td width="303">Tipo Richiesta</td>
                            <td id="requestType" colspan="4">
                                <select name="tipo_richiesta" onChange="changeRows(this)" autocomplete="off">
                                <option selected value="info">Informazioni</option>
                                <option value="preventivo">Preventivo</option>
                                </select>
                            </td>
                    </tr>
                    <tr>
                        <td>Azienda/Referente*</td><td colspan="4"> <input type="text" name="referente" size="50"></td>
                    </tr>
                    <tr>
                        <td>Email*</td><td colspan="4"><input  id="emailAddr" type="text" name="email" size="50"></td>
                    </tr>
                    <tr>
                        <td>Telefono</td><td colspan="4"> <input type="text" name="telefono" size="50" onKeyPress="return numbersonly(this, event)"></td>
                    </tr>
                    <tr>
                        <td class="campiPreventivo">Intervento</td><td class="campiPreventivo" colspan="4"> <input type="text" name="intervento" size="50"></td>
                    </tr>
                    <tr>
                        <td class="campiPreventivo">Ubicazione*</td><td class="campiPreventivo" colspan="4"><input type="text" name="ubicazione" size="50"></td>
                    </tr>
                    <tr>
                        <td style="padding-top:20px" valign="top" class="campiPreventivo" rowspan="2"><INPUT type="button" value="+ Aggiungi Indagine" onclick="addRow()">
                        <br><INPUT type="button" value="-   Cancella Indagine" onclick="deleteRow()"></td><td style="padding-top:20px" class="campiPreventivo" width="80" align="center">Cancella</td><td style="padding-top:20px" class="campiPreventivo" width="215">Indagine*</td><td class="campiPreventivo" style="padding-top:20px" width="70" align="center">Quantità</td>
                    </tr>
                    <tr>
                        <td colspan="4">
                        <TABLE id="dataTable" border="0" cellpadding="0" cellspacing="0">
                            <span id="writeroot"></span>
                        </TABLE>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding-top:20px" valign="top">Dettagli/Note</td><td style="padding-top:20px" colspan="4"><textarea name="dettagli" cols="47" rows="10" style="resize:none" wrap="hard"></textarea></td>
                    </tr>
                    <tr>
                        <td style="padding-top:20px; font-size:12px" colspan="4" align="center"><input type="checkbox" name="privacy">Autorizzo il trattamento dei dati personali secondo la vigente normativa sulla privacy: D.lgs 196/03</td>
                    </tr>
                    <tr>
                        <td style="padding-top:20px" colspan="4" align="center"><input type="submit" value="Invia richiesta"></td>
                    </tr>
                </table>
            </form>
            <br>
            <font style="font-size:85%">I campi contrassegnati con * sono obbligatori</font>

        </div>
    </div>
</div>

<div id="copirightBox">
  <div id="copyrightTxt">Copyright © Tutti i diritti riservati</div>
</div>
<div id="corpInfoTxt">
    <p id="ciTxtStyle">EmmeElle - Indagini Geologiche - P.Iva: 06160480486</p>
</div>

Теперь мойПроблема в том, что когда я запускаю этот скрипт в браузерах IE (все версии, которые я проверял), он добавляет мои строки с новой строкой после каждого элемента TD.Это не то, чего я хочу, и это не то поведение, которое я имею в Chrome, Firefox, Safari и т. Д. ...

Вы можете перейти к http://www.geoemmelle.it/contatti.html, используя все, кроме IE, и затем выбрать «Preventivo»."в первом поле запустить скрипт.Затем сделайте то же самое с IE и проверьте разницу.

Я действительно не знаю, как подойти к этому.Есть ли кто-нибудь, кто знает об этой проблеме?

Заранее спасибо за вашу помощь!

РЕДАКТИРОВАТЬ:

Похоже на "Новая строка »добавляется после каждого элемента TD элемента TR в DIV, который я добавляю.Пожалуйста, помогите разобраться, как найти решение?

Еще раз спасибо.

Ответы [ 3 ]

1 голос
/ 29 января 2012

Как здесь ответили - div внутри таблицы - недопустимо иметь <div> в качестве дочернего элемента <table>. Я считаю, что <div> вызывает новые строки, но установка display:inline не решает проблему. Что вы должны сделать, это добавить новые элементы <tr> в таблицу.

Я потратил некоторое время на разработку решения JavaScript для этой проблемы, но я также рекомендую изучить библиотеку JavaScript (например, jQuery ), которая запутывает многие из кросс-браузеров и DOM проблемы манипуляции с кодом.

В следующем решении я переписал addRow(), чтобы программно создать новую строку в DOM, и использовал метод appendChild для вставки правильного <tr> в существующий <table>. removeRow() значительно упрощен, чтобы просто удалить последнюю строку таблицы. Я также добавил и исправил кроссплатформенную функцию getElementsByClassName , чтобы расширить документ, если браузер не поддерживает getElementsByClassName . (Кредит для http://code.google.com/p/getelementsbyclassname/ проекта для этого). Наконец, я удалил код обнаружения браузера в пользу условных комментариев , которые поддерживаются только в IE. Это было возможно, так как вам нужно только определить IE <7 при установке <code>style.display = 'table-cell';, поскольку IE <7 не поддерживает <code>table-cell

Вам также следует обратить внимание на написание разметки, которая будет соответствовать выбранному вами DOCTYPE . Неправильная разметка также может привести к непредвиденным проблемам с рендерингом или взаимодействием. Встроенные CSS и JavaScript также следует перенести в файл CSS и JS, что позволит браузерам легче кэшировать эти ресурсы.

Полное решение

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>EmmeElle Indagini Geologiche contatti, richiesta informazioni, preventivi</title>
<style type="text/css">
    .campiPreventivo {
        display:none;
    }
</style>
<script type="text/javascript">
var oldIE = false;

if (typeof document.getElementsByClassName!='function') {
    document.getElementsByClassName = function (className, tag, elm){
    if (document.evaluate) {
        getElementsByClassName = function (className, tag, elm) {
            tag = tag || "*";
            elm = elm || document;
            var classes = className.split(" "),
                classesToCheck = "",
                xhtmlNamespace = "http://www.w3.org/1999/xhtml",
                namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
                returnElements = [],
                elements,
                node;
            for(var j=0, jl=classes.length; j<jl; j+=1){
                classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
            }
            try {
                elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
            }
            catch (e) {
                elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
            }
            while ((node = elements.iterateNext())) {
                returnElements.push(node);
            }
            return returnElements;
        };
    }
    else {
        getElementsByClassName = function (className, tag, elm) {
            tag = tag || "*";
            elm = elm || document;
            var classes = className.split(" "),
                classesToCheck = [],
                elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
                current,
                returnElements = [],
                match;
            for(var k=0, kl=classes.length; k<kl; k+=1){
                classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
            }
            for(var l=0, ll=elements.length; l<ll; l+=1){
                current = elements[l];
                match = false;
                for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
                    match = classesToCheck[m].test(current.className);
                    if (!match) {
                        break;
                    }
                }
                if (match) {
                    returnElements.push(current);
                }
            }
            return returnElements;
        };
    }
    return getElementsByClassName(className, tag, elm);
    };
}

var counter = 0;

function addRow() {
    var table = document.getElementById('dataTable');
    var tbody = table.getElementsByTagName('tbody')[0];
    var tr = document.createElement('tr');
    var td1 = document.createElement('td');
    td1.setAttribute('width', '80');
    td1.setAttribute('align', 'center');

    var td2 = document.createElement('td');
    td2.setAttribute('width', '215');

    var td3 = document.createElement('td');
    td3.setAttribute('width', '70');
    td3.setAttribute('align', 'center');

    td1.innerHTML = '<input type="checkbox" name="chk_cancella' + counter + '"/>';
    td2.innerHTML = '<input type="text" name="indagine' + counter + '" size="34"/>';
    td3.innerHTML = '<input type="text" name="qta' + counter + '" value="1" size="1" maxlength="2" onKeyPress="return numbersonly(this, event)"/>';

    tr.appendChild(td1);
    tr.appendChild(td2);
    tr.appendChild(td3);

    tbody.appendChild(tr);

    counter++;
}

function deleteRow() {
    if (counter === 1) {
        alert("Non è possibile eliminare tutte le indagini nella richiesta di preventivo. Se non si vogliono specificare indagini, scegliere INFORMAZIONI nel campo TIPO RICHIESTA");
        return;
    }

    try {
        var table = document.getElementById('dataTable');
        var tbody = table.getElementsByTagName('tbody')[0];
        var rows = table.getElementsByTagName('tr');

        tbody.removeChild(rows[rows.length-1]);
        counter--;
    } catch(e) {}
}

function changeRows(obj) {
    var list = document.getElementsByClassName('campiPreventivo');

    if(obj.value == 'preventivo') {
        if(counter === 0) {
            addRow();
        }

        for (var i = 0; i < list.length; i++) {
            var displayType = oldIE ? 'block' : 'table-cell';

            if (list[i].nodeName === 'TD') {
                list[i].style.display = displayType;
            }
        }
    } else {
        for (var k = 0; k < list.length; k++) {
            list[k].style.display = 'none';
        }

        try {
            var removeHere = document.getElementById('dataTable');
            for (var z= 0; z<removeHere.parentNode.childNodes.length; z++) {
                if(removeHere.parentNode.childNodes[z].nodeName=='DIV')
                {
                }
            }

            counter=0;
        } catch (e) {}
    }
}
</script>
    <!--[if lte IE 7]>
    <script type="text/javascript">
        oldIE = true;
    </script>
    <![endif]-->
</head>
<body>
<div id=formDiv>
    <form name="contactForm" action="php/mail.php" onsubmit="return validateForm()" method="post">
        <table width="668" border="0" cellpadding="0" cellspacing="0" id="formTable">
            <tr>
                <td width="303">Tipo Richiesta</td>
                    <td id="requestType" colspan="4">
                        <select name="tipo_richiesta" onChange="changeRows(this)">
                            <option selected value="info">Informazioni</option>
                            <option value="preventivo">Preventivo</option>
                        </select>
                    </td>
            </tr>
            <tr>
                <td class="campiPreventivo">Intervento</td>
                <td class="campiPreventivo" colspan="4"> <input type="text" name="intervento" size="50"></td>
            </tr>
            <tr>
                <td class="campiPreventivo">Ubicazione*</td>
                <td class="campiPreventivo" colspan="4"><input type="text" name="ubicazione" size="50"></td>
            </tr>
            <tr>
                <td style="padding-top:20px" valign="top" class="campiPreventivo" rowspan="2">
                    <input type="button" value="+ Aggiungi Indagine" onclick="addRow()"><br>
                    <input type="button" value="- Cancella Indagine" onclick="deleteRow()">
                </td>
                <td style="padding-top:20px" class="campiPreventivo" width="80" align="center">Cancella</td>
                <td style="padding-top:20px" class="campiPreventivo" width="215">Indagine*</td>
                <td class="campiPreventivo" style="padding-top:20px" width="70" align="center">Quantità</td>
            </tr>
            <tr>
                <td colspan="4">
                    <table id="dataTable" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td><td></td><td></td><td></td></tr></tbody></table>
                </td>
            </tr>
        </table>
    </form>
</div>
</body>
</html>
1 голос
/ 29 января 2012

Хотя я уже ответил с помощью решения JavaScript, вот версия, которая использует библиотеку JavaScript jQuery , которая, я надеюсь, вы увидите, намного меньше кода, хотя и имеет (небольшие) накладные расходы включая библиотеку jQuery.

События click и change связаны с использованием функций jQuery, а не с более старыми событиями onclick и onchange . Это не полное решение, так как динамические строки не скрываются при возврате выпадающего списка. Допустим, я оставил это как учебное упражнение: -)

Полное решение

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>EmmeElle Indagini Geologiche contatti, richiesta informazioni, preventivi</title>
<style type="text/css">
    .campiPreventivo {
        display:none;
    }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function() {
        var template = $('<tr><td style="width:80px;text-align:center;"><input type="checkbox" name="chk_cancella"/></td><td style="width:215px"><input type="text" name="indagine" size="34"/></td><td style="width:70px;text-align:center;"><input type="text" name="qta" value="1" size="1" maxlength="2" onKeyPress="return numbersonly(this, event)"/></td></tr>');

        $('#addRow').on('click', function() {
            var counter = $('#dataTable tr').length;
            var newRow = template.clone();

            newRow.find('input').each(function() {
                var $this = $(this);
                $this.prop('name', $this.prop('name') + counter);
            });

            $('#dataTable').append(newRow);
        });

        $('#removeRow').on('click', function() {
            if ($('#dataTable tr').length === 2) { // 2 because there is always one blank row to make the HTML valid
                alert("Non è possibile eliminare tutte le indagini nella richiesta di preventivo. Se non si vogliono specificare indagini, scegliere INFORMAZIONI nel campo TIPO RICHIESTA");
                return;
            }

            $('#dataTable tr:last').remove();
        });

        $('select[name="tipo_richiesta"]').on('change', function() {
            $('.campiPreventivo').toggle();
            $('#addRow').trigger('click');
        });
    });
</script>

</head>
<body>
<div id=formDiv>
    <form name="contactForm" action="php/mail.php" onsubmit="return validateForm()" method="post">
        <table width="668" border="0" cellpadding="0" cellspacing="0" id="formTable">
            <tr>
                <td width="303">Tipo Richiesta</td>
                    <td id="requestType" colspan="4">
                        <select name="tipo_richiesta">
                            <option selected value="info">Informazioni</option>
                            <option value="preventivo">Preventivo</option>
                        </select>
                    </td>
            </tr>
            <tr>
                <td class="campiPreventivo">Intervento</td>
                <td class="campiPreventivo" colspan="4"> <input type="text" name="intervento" size="50"></td>
            </tr>
            <tr>
                <td class="campiPreventivo">Ubicazione*</td>
                <td class="campiPreventivo" colspan="4"><input type="text" name="ubicazione" size="50"></td>
            </tr>
            <tr>
                <td style="padding-top:20px" valign="top" class="campiPreventivo" rowspan="2">
                    <input type="button" value="+ Aggiungi Indagine" id="addRow"><br>
                    <input type="button" value="- Cancella Indagine" id="removeRow">
                </td>
                <td style="padding-top:20px" class="campiPreventivo" width="80" align="center">Cancella</td>
                <td style="padding-top:20px" class="campiPreventivo" width="215">Indagine*</td>
                <td class="campiPreventivo" style="padding-top:20px" width="70" align="center">Quantità</td>
            </tr>
            <tr>
                <td colspan="4">
                    <table id="dataTable" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td></td><td></td><td></td><td></td></tr></tbody></table>
                </td>
            </tr>
        </table>
    </form>
</div>
</body>
</html>
0 голосов
/ 24 января 2012

Возможно, пытаюсь поставить дисплей: встроенный; для IE.

...