Каков наиболее эффективный способ получения индекса столбца для строк, затронутых «rowspan»? - PullRequest
3 голосов
/ 21 сентября 2009

Рассмотрим следующую таблицу:

<table>
    <thead>
        <tr>
            <th scope="col" />
            <th scope="col">A</th>
            <th scope="col">B</th>
            <th scope="col">C</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">1</th>
            <td>Apples</td>
            <td>Oranges</td>
            <td>Pears</td>
        </tr>
        <tr>
            <th scope="row">2</th>
            <td rowspan="2">Subcategory Heading</td>
            <td>ASP.Net</td>
            <td>Other</td>
        </tr>
        <tr>
            <th scope="row">3</th>
            <td>MVC</td>
            <td>PHP</td>
        </tr>
        <tr>
            <th scope="row">4</th>
            <td>Red</td>
            <td>Green</td>
            <td>Blue</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td colspan="4">Some pointless footer content</td>
        </tr>
    </tfoot>
</table>

Как бы я получил правильный номер столбца для ячейки, содержащей текст "MVC" или "PHP", используя jQuery? Правильный ответ будет в столбце 3, но только использование .prevAll().length будет подсчитывать только количество предыдущих ячеек, которое в этом случае не будет точно отражать их фактическое положение в столбце?

Я уверен, что мне нужно будет использовать each(), но я также ищу наиболее эффективную реализацию.

Ответы [ 5 ]

3 голосов
/ 12 июня 2012

Я недавно написал решение для этой ситуации для той же проблемы:

Как найти "визуальное местоположение" каждой ячейки таблицы с помощью jQuery?

Может быть еще одним решением для людей, которые ищут это.

1 голос
/ 21 сентября 2009

Как то так?

<!doctype html>
<table id="foo">
    <thead>
        <tr>
            <th scope="col" />
            <th scope="col">A</th>
            <th scope="col">B</th>
            <th scope="col">C</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th scope="row">1</th>
            <td>Apples</td>
            <td>Oranges</td>
            <td>Pears</td>
        </tr>
        <tr>
            <th scope="row">2</th>
            <td rowspan="2">Subcategory Heading</td>
            <td>ASP.Net</td>
            <td>Other</td>
        </tr>
        <tr>
            <th scope="row">3</th>
            <td>MVC</td>
            <td>PHP</td>
        </tr>
        <tr>
            <th scope="row">4</th>
            <td>Red</td>
            <td>Green</td>
            <td>Blue</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td colspan="4">Some pointless footer content</td>
        </tr>
    </tfoot>
</table>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script>
    var table = $('table#foo');
    table.find('td[rowspan], th[rowspan]').each(function() {
    var cellNum,
        reference = this,
        columnNum = $(this).attr('rowspan'),
        parentTr = $(this).closest('tr'),
        parentTrs = $(this).closest('tr').parent().find('tr');

    parentTr.find('>td, >th').each(function(i,o) {
        if ( this == reference ) {
        cellNum = i;

        var counter = columnNum;

        while ( counter-- ) {
            $(this).closest('tr').next().find('>td,>th').each(function(i,o) {
            if ( cellNum == i ) {
                $(this).addClass('rowspan-affected');
                $(this).attr('colNum', columnNum);
            }
            });
        }
        }
    });

    /* testing
    window.num = num;
    window.parentTr = parentTr;
    window.parentTrs = parentTrs;
    */
    });
</script>
0 голосов
/ 21 мая 2015

Попробуйте что-то вроде этого, вы поймете. Это работает, так почему бы и нет:

.stuffing {
    display: none;
}
<table>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
    </tr>
    <tr>
        <td colspan="3">1</td>
        <td class="stuffing"></td>
        <td class="stuffing"></td>
        <td>4</td>
    </tr>
</table>
var tb= document.querySelector('table');
tb.rows[0].cells[3].innerHTML;  //4
tb.rows[1].cells[3].innerHTML;  //4

Подарите этого парня за его ответ на моем вопросе .

0 голосов
/ 24 сентября 2009

Я думаю, что самые близкие к сокращению шаги поиска будут делать что-то вроде этого:

var counter = 0;
$("#idTable tbody tr").each(function(){

   var html = $(this).html();
   var php = html.indexOf("PHP") > -1 ? true : false;
   var mvc = html.indexOf("MVC") > -1 ? true : false;

   if(php || mvc) {
       $(this).find("td").each(function(){ counter += (($(this).html()=="PHP") || ($(this).html()=="MVC")) ? 1 : 0; });
   }

});
0 голосов
/ 21 сентября 2009

Ну, самое короткое (сверх) упрощение:

var theCell = $('td:contains("MVC")');
col = theCell.parent().children().index(theCell);
row = theCell.parent().parent().children().index(theCell.parent());

Обратите внимание, возвращаемые индексы начинаются с нуля. По сути, сначала вы находите интересующую клетку. Для столбца вы поднимаетесь на уровень в DOM до <tr>, получаете все дочерние элементы (которые в этом случае будут потомками <td> s и <th> s) и находите позицию интересующего элемента в этом наборе. Для строки вы поднимаетесь до, в данном случае, <tbody>, получаете все строки и находите положение строки <td>, представляющей интерес.

Как вы понимаете, изменения в структуре таблицы изменяют возможные результаты. Однако, если вы программно используете индексы позже так же, как вы их получили, вы можете вернуться к той же ячейке. Я говорю об этом, потому что, если вы каким-то образом используете индексы визуально в пользовательском интерфейсе, вам, возможно, придется усложнить и учесть промежутки, <tbody> против <tbody> и т. Д.

Не знаю, эффективнее ли это, чем ответ медера. Но это, безусловно, гораздо более ремонтопригодны! :)

...