Показать/скрыть строки таблицы, используя классы Javascript

У меня есть таблица, которая расширяет и сворачивает, но она становится слишком запутанной, чтобы использовать ее, а IE и Firefox не работают должным образом.

Итак, вот код JavaScript:

  function toggle_it(itemID){ 
      // Toggle visibility between none and '' 
      if ((document.getElementById(itemID).style.display == 'none')) { 
            document.getElementById(itemID).style.display = '' 
            event.preventDefault()
      } else { 
            document.getElementById(itemID).style.display = 'none'; 
            event.preventDefault()
      }    
  } 

И пример HTML:

<table>
    <tr>
        <td>Product</td>
        <td>Price</td>
        <td>Destination</td>
        <td>Updated on</td>
    </tr>
    <tr>
        <td>Oranges</td>
        <td>100</td>
        <td><a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')">+ On Store</a></td>
        <td>22/10</td>
    </tr>
    <tr id="tr1" style="display:none">
        <td></td>
        <td>120</td>
        <td>City 1</td>
        <td>22/10</td>
    </tr>
    <tr id="tr2" style="display:none">
        <td></td>
        <td>140</td>
        <td>City 2</td>
        <td>22/10</td>
    </tr>
    <tr>
        <td>Apples</td>
        <td>100</td>
        <td><a href="#" id="toggle" onClick="toggle_it('tr3');toggle_it('tr4')">+ On Store</a></td>
        <td>22/10</td>
    </tr>
    <tr id="tr3" style="display:none">
        <td></td>
        <td>120</td>
        <td>City 1</td>
        <td>22/10</td>
    </tr>
    <tr id="tr4" style="display:none">
        <td></td>
        <td>140</td>
        <td>City 2</td>
        <td>22/10</td>
    </tr>
</table>

Проблема в том, что я использую один ID для каждого и очень раздражающий, потому что я хочу иметь много скрытых строк для каждого родителя и большого количества родителей, поэтому для обработки будет слишком много идентификаторов. И IE и FireFox показывают только первую скрытую строку, а не другие. Я подозреваю, что это происходит, потому что я сделал это, запуская все идентификаторы вместе. Я думаю, было бы лучше, если бы я использовал классы вместо идентификаторов, чтобы индексировать скрытые строки.

Я действительно новичок в этом, поэтому, пожалуйста, попробуйте объяснить это любым способом. Также я пробовал jQuery, но не смог его получить.

Ответ 1

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

Здесь скрипка: ссылка.

Что вы делаете, вместо работы с идентификаторами вы работаете с классами. В вашем примере кода есть апельсины и яблоки. Я рассматриваю их как категории продуктов (так как я действительно не знаю, какова ваша цель), с их собственными идентификаторами. Итак, я отмечаю продукт <tr> с помощью class="cat1" или class="cat2".

Я также отмечаю ссылки с простым классом .toggler. Неправильная практика иметь атрибуты onclick для самих элементов. Вы должны "связывать" события с загрузкой страницы с помощью JavaScript. Я делаю это с помощью jQuery.

$(".toggler").click(function(e){
    // you handle the event here
});

В этом формате вы привязываете обработчик событий к событию click ссылок с классом toggler. В моем коде я добавляю атрибут data-prod-cat к ссылкам toggler, чтобы указать, какие строки продуктов они должны контролировать. (Причина моего использования атрибута data-* объясняется здесь. Для получения дополнительной информации вы можете использовать атрибуты данных "html5" Google.)

В обработчике событий я делаю следующее:

$('.cat'+$(this).attr('data-prod-cat')).toggle();

С помощью этого кода я на самом деле пытаюсь создать селектор типа $('.cat1'), чтобы я мог выбирать строки для определенной категории продуктов и изменять их видимость. Я использую $(this).attr('data-prod-cat') для доступа к атрибуту data-prod-cat ссылки, которую пользователь нажимает. Я использую функцию jQuery toggle, поэтому мне не нужно писать такую ​​логику, как if visible, then hide element, else make it visible, как в вашем JS-коде. jQuery занимается этим. Функция переключения делает то, что она говорит, и toggle видимость указанного элемента (ов).

Надеюсь, это было достаточно объяснительным.

Ответ 2

Ну, один способ сделать это - просто поместить класс в "родительские" строки и удалить все идентификаторы ids и inline onclick:

<table id="products">
    <thead>
    <tr>
        <th>Product</th>
        <th>Price</th>
        <th>Destination</th>
        <th>Updated on</th>
    </tr>
    </thead>
    <tbody>
    <tr class="parent">
        <td>Oranges</td>
        <td>100</td>
        <td><a href="#">+ On Store</a></td>
        <td>22/10</td>
    </tr>
    <tr>
        <td></td>
        <td>120</td>
        <td>City 1</td>
        <td>22/10</td>
    </tr>
    <tr>
        <td></td>
        <td>140</td>
        <td>City 2</td>
        <td>22/10</td>
    </tr>
    ...etc.
    </tbody>
</table>

И затем у вас есть CSS, который скрывает всех не-родителей:

tbody tr {
    display : none;          // default is hidden
}
tr.parent {
    display : table-row;     // parents are shown
}
tr.open {
    display : table-row;     // class to be given to "open" child rows
}

Это значительно упрощает ваш html. Обратите внимание, что я добавил <thead> и <tbody> к вашей разметке, чтобы упростить скрытие строк данных и игнорировать строки заголовков.

С помощью jQuery вы можете просто сделать это:

// when an anchor in the table is clicked
$("#products").on("click","a",function(e) {
    // prevent default behaviour
    e.preventDefault();
    // find all the following TR elements up to the next "parent"
    // and toggle their "open" class
    $(this).closest("tr").nextUntil(".parent").toggleClass("open");
});

Демо: http://jsfiddle.net/CBLWS/1/

Или, чтобы реализовать что-то подобное в простом JavaScript, возможно, что-то вроде следующего:

document.getElementById("products").addEventListener("click", function(e) {
    // if clicked item is an anchor
    if (e.target.tagName === "A") {
        e.preventDefault();
        // get reference to anchor parent TR
        var row = e.target.parentNode.parentNode;
        // loop through all of the following TRs until the next parent is found
        while ((row = nextTr(row)) && !/\bparent\b/.test(row.className))
            toggle_it(row);
    }
});

function nextTr(row) {
    // find next sibling that is an element (skip text nodes, etc.)
    while ((row = row.nextSibling) && row.nodeType != 1);
    return row;
}

function toggle_it(item){ 
     if (/\bopen\b/.test(item.className))       // if item already has the class
         item.className = item.className.replace(/\bopen\b/," "); // remove it
     else                                       // otherwise
         item.className += " open";             // add it
}

Демо: http://jsfiddle.net/CBLWS/

В любом случае, поместите JavaScript в элемент <script>, который находится в конце тела, чтобы он запускался после того, как таблица была проанализирована.

Ответ 3

JQuery 10.1.2 имеет приятное шоу и скрывает функции, которые инкапсулируют поведение, о котором вы говорите. Это избавит вас от необходимости писать новую функцию или отслеживать классы css.

$("tr1").show();

$("tr1").hide();

w3cSchool ссылку на JQuery показать и скрыть

Ответ 4

event.preventDefault()

Не работает во всех браузерах. Вместо этого вы можете вернуть false в событии OnClick.

onClick="toggle_it('tr1');toggle_it('tr2'); return false;">

Не уверен, что это лучший способ, но я тестировал в IE, FF и Chrome и прекрасно работал.

Ответ 5

Ниже представлен мой Script, который отображает/скрывает строку таблицы с идентификатором "агентский".

<script type="text/javascript">

                        function showhiderow() {
                            if (document.getElementById("<%=RadioButton1.ClientID %>").checked == true) {

                                document.getElementById("agencyrow").style.display = '';
                            } else {

                                document.getElementById("agencyrow").style.display = 'none';
                            }


                        }
    </script> 

Просто вызывать функцию showhiderow() при событии радиообмена onClick

Ответ 6

AngularJS директивы ng-show, ng-hide позволяет отображать и скрывать строку:

   <tr ng-show="rw.isExpanded">
   </tr>

Строка будет видна, когда rw.isExpanded == true и скрыто, когда rw.isExpanded == false. ng-hide выполняет ту же задачу, но требует обратного условия.