Получение максимальной ширины каждого столбца в моей таблице Javascript / Jquery

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

Моя таблица выглядит как это

поэтому самая большая ячейка в первом столбце Имя должна быть Бриэль Уильямсон, а самая большая ячейка в первом столбце Должность должна быть Главный исполнительный директор (CEO) и так далее ...

Я вставляю ширину этих ячеек в массив, который будет выглядеть так: var widths = ["70", "90", "60",....];

Вот мой код

var max = 0; 
 var i = 0;
 var j = 0;
 var arr = [];
 
 for (i = 1; i < 7; i++) { 
 $('table tbody tr td:nth-child('+ i +')').each(function() {
    max = Math.max($(this).width(), max); });
    arr[j] = max;     
 		j = j + 1;    
} 

alert(JSON.stringify(arr));
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
      <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Airi Satou</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>33</td>
                <td>2008/11/28</td>
                <td>$162,700</td>
            </tr>
            <tr>
                <td>Angelica Ramos</td>
                <td>Chief Executive Officer (CEO)</td>
                <td>London</td>
                <td>47</td>
                <td>2009/10/09</td>
                <td>$1,200,000</td>
            </tr>
            <tr>
                <td>Ashton Cox</td>
                <td>Junior Technical Author</td>
                <td>San Francisco</td>
                <td>66</td>
                <td>2009/01/12</td>
                <td>$86,000</td>
            </tr>
            <tr>
                <td>Bradley Greer</td>
                <td>Software Engineer</td>
                <td>London</td>
                <td>41</td>
                <td>2012/10/13</td>
                <td>$132,000</td>
            </tr>
            <tr>
                <td>Brenden Wagner</td>
                <td>Software Engineer</td>
                <td>San Francisco</td>
                <td>28</td>
                <td>2011/06/07</td>
                <td>$206,850</td>
            </tr>
            <tr>
                <td>Brielle Williamson</td>
                <td>Integration Specialist</td>
                <td>New York</td>
                <td>61</td>
                <td>2012/12/02</td>
                <td>$372,000</td>
            </tr>
            </tbody>
</table>

Я не понимаю, что не так с моим кодом. Он по-прежнему получает максимальную ширину во всей таблице, а не в каждом столбце. Есть предложения, пожалуйста?

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

Rajit 04.06.2018 16:07

@Rajit, если вы запустите мой код, вы увидите этот результат в предупреждении [122,201,201,201,201,201], но, например, столбцы Position и Age имеют разную ширину

JuniorDev 04.06.2018 16:09

Это похоже на XY проблема - какова общая цель обнаружения этих данных; Что ты пытаешься сделать? Я спрашиваю только потому, что может быть лучший способ сделать это, чем то, что вы задумали.

amphetamachine 04.06.2018 16:10

@amphetamachine Я пытаюсь получить ширину каждого столбца и вставить его в массив

JuniorDev 04.06.2018 16:12

@JuniorDev Вставить его в массив, чтобы его больше не читали? В чем смысл?

amphetamachine 04.06.2018 16:13

@amphetamachine Я хочу получить ширину каждого столбца, чтобы я мог настроить экспортированный файл Excel с той же шириной, что и в таблице

JuniorDev 04.06.2018 16:15

@JuniorDev Я неправильно понял, извиняюсь. Мне кажется, вы просто хотите вычислить ширину каждого столбца, поскольку самая большая ячейка будет определять ширину всего столбца. Вы использовали Math.max без надобности. Вы можете просто назначить .width прямо вашему массиву. Поскольку вы используете Math.max, вы до сих пор находите максимальную ширину и каждый раз присваиваете то же значение массиву

Rajit 04.06.2018 16:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
7
1 380
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Это потому, что здесь вы всегда сохраняете максимальное значение между столбцами:

max = Math.max($(this).width(), max); });.

Следовательно, 201 повторяется. Как указано в комментариях Раджита, ваши столбцы автоматически устанавливаются на максимальную ширину максимальной ячейки, поэтому вам не нужно делать это самостоятельно.

Кроме того, у вас есть один ненужный цикл, попробуйте вместо него (без for):

 $('table thead tr th').each(function() {
    arr[j] = $(this).width();     
    j = j + 1;    
} 

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

const columns = $("tbody tr:first td").map(function(i) {
  return $(this).width()
}).get();

console.info(columns)
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Office</th>
      <th>Age</th>
      <th>Start date</th>
      <th>Salary</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Airi Satou</td>
      <td>Accountant</td>
      <td>Tokyo</td>
      <td>33</td>
      <td>2008/11/28</td>
      <td>$162,700</td>
    </tr>
    <tr>
      <td>Angelica Ramos</td>
      <td>Chief Executive Officer (CEO)</td>
      <td>London</td>
      <td>47</td>
      <td>2009/10/09</td>
      <td>$1,200,000</td>
    </tr>
    <tr>
      <td>Ashton Cox</td>
      <td>Junior Technical Author</td>
      <td>San Francisco</td>
      <td>66</td>
      <td>2009/01/12</td>
      <td>$86,000</td>
    </tr>
    <tr>
      <td>Bradley Greer</td>
      <td>Software Engineer</td>
      <td>London</td>
      <td>41</td>
      <td>2012/10/13</td>
      <td>$132,000</td>
    </tr>
    <tr>
      <td>Brenden Wagner</td>
      <td>Software Engineer</td>
      <td>San Francisco</td>
      <td>28</td>
      <td>2011/06/07</td>
      <td>$206,850</td>
    </tr>
    <tr>
      <td>Brielle Williamson</td>
      <td>Integration Specialist</td>
      <td>New York</td>
      <td>61</td>
      <td>2012/12/02</td>
      <td>$372,000</td>
    </tr>
  </tbody>
</table>

Пример на чистом javascript.

        var trs  = document.querySelectorAll('tbody tr'),
            cols = 0,           // Columns length
            rows = trs.length,  // Rows length
            res  = [],          // Result
            txt  = [];          // Text values

        for(var i=0; i<rows; i++){
            var row = trs[i],
                tds = row.querySelectorAll('td');

            if (res.length == 0){
                cols = tds.length;
                res  = new Array(cols);
            }

            for(var e=0; e<tds.length; e++){
                var td = tds[e];

                // Wrap text to inline element
                td.innerHTML = '<span>'+td.innerText+'</span>';

                var sp = td.querySelector('span');

                if (!res[e] || res[e] < sp.offsetWidth){
                    res[e] = sp.offsetWidth;
                    txt[e] = sp.innerText;
                }

                // Unwarp after calculating
                td.innerHTML = td.innerText;
            }
        }

        console.info(res);
        console.info(txt);
Ответ принят как подходящий

Проблема в том, что вы используете одно и то же значение max для всех столбцов.

Переместите var max = 0; внутрь цикла for (или, вернее, каждый раз сбрасывайте его на 0, из-за того, как работает js scoping).

var i = 0;
var j = 0;
var arr = [];
var max;

for (i = 1; i < 7; i++) {
  max = 0;
  $('table tbody tr td:nth-child(' + i + ')').each(function() {
    max = Math.max($(this).width(), max);
  });
  arr[j] = max;
  j = j + 1;
}

alert(JSON.stringify(arr));
th {text-align:left}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Office</th>
      <th>Age</th>
      <th>Start date</th>
      <th>Salary</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Airi Satou</td>
      <td>Accountant</td>
      <td>Tokyo</td>
      <td>33</td>
      <td>2008/11/28</td>
      <td>$162,700</td>
    </tr>
    <tr>
      <td>Angelica Ramos</td>
      <td>Chief Executive Officer (CEO)</td>
      <td>London</td>
      <td>47</td>
      <td>2009/10/09</td>
      <td>$1,200,000</td>
    </tr>
    <tr>
      <td>Ashton Cox</td>
      <td>Junior Technical Author</td>
      <td>San Francisco</td>
      <td>66</td>
      <td>2009/01/12</td>
      <td>$86,000</td>
    </tr>
    <tr>
      <td>Bradley Greer</td>
      <td>Software Engineer</td>
      <td>London</td>
      <td>41</td>
      <td>2012/10/13</td>
      <td>$132,000</td>
    </tr>
    <tr>
      <td>Brenden Wagner</td>
      <td>Software Engineer</td>
      <td>San Francisco</td>
      <td>28</td>
      <td>2011/06/07</td>
      <td>$206,850</td>
    </tr>
    <tr>
      <td>Brielle Williamson</td>
      <td>Integration Specialist</td>
      <td>New York</td>
      <td>61</td>
      <td>2012/12/02</td>
      <td>$372,000</td>
    </tr>
  </tbody>
</table>

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

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

Тем не менее, есть много областей для реструктуризации кода.

var max = 0; 
 var i = 0;
 var j = 0;
 var arr = [];
 
 for (i = 1; i < 7; i++) { 
    max =0;//<-- Note this change
    $('table tbody tr td:nth-child('+ i +')').each(function() {
       max = Math.max($(this).width(), max); 
    });
    arr[j] = max; 
    j = j + 1;    
} 

alert(JSON.stringify(arr));
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
      <thead>
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Age</th>
                <th>Start date</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Airi Satou</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>33</td>
                <td>2008/11/28</td>
                <td>$162,700</td>
            </tr>
            <tr>
                <td>Angelica Ramos</td>
                <td>Chief Executive Officer (CEO)</td>
                <td>London</td>
                <td>47</td>
                <td>2009/10/09</td>
                <td>$1,200,000</td>
            </tr>
            <tr>
                <td>Ashton Cox</td>
                <td>Junior Technical Author</td>
                <td>San Francisco</td>
                <td>66</td>
                <td>2009/01/12</td>
                <td>$86,000</td>
            </tr>
            <tr>
                <td>Bradley Greer</td>
                <td>Software Engineer</td>
                <td>London</td>
                <td>41</td>
                <td>2012/10/13</td>
                <td>$132,000</td>
            </tr>
            <tr>
                <td>Brenden Wagner</td>
                <td>Software Engineer</td>
                <td>San Francisco</td>
                <td>28</td>
                <td>2011/06/07</td>
                <td>$206,850</td>
            </tr>
            <tr>
                <td>Brielle Williamson</td>
                <td>Integration Specialist</td>
                <td>New York</td>
                <td>61</td>
                <td>2012/12/02</td>
                <td>$372,000</td>
            </tr>
            </tbody>
</table>

Другие вопросы по теме