JavaScript получить естественную ширину / высоту всех изображений в таблице - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь получить фактические размеры изображений из изображений, перечисленных в столбце Изображение , и отобразить их в столбце Размер изображения .

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

jsFiddle: https://jsfiddle.net/a92ck0em/

  var xmlFile = 'https://raw.githubusercontent.com/joenbergen/files/master/XMLParse2.xml';

  function loadDoc() {
    var xhttp = new XMLHttpRequest();

    xhttp.open("GET", xmlFile, true);
    xhttp.send();
    xhttp.onreadystatechange = function() {
      if (this.readyState === 4 && this.status === 200) {
        xmlFunction(this.response);
      }
    };

  }

  function xmlFunction(xml) {
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(xml, "text/xml");
    var table = "<tr><th>Category</th><th>Title</th><th>Image</th><th>Image Size</th></tr>";
    var x = xmlDoc.getElementsByTagName("ITEM");
    for (var elem of x) {
      var titles = elem.getElementsByTagName(
        "TITLE")[0].childNodes[0].nodeValue;
      var cats = elem.getElementsByTagName("CATEGORY")[0].childNodes[0].nodeValue;
      var imageURL = elem.getElementsByTagName("IMAGE").length === 0 ? "..." : elem.getElementsByTagName("IMAGE")[0].getAttribute('url');
      var imageSize = elem.getElementsByTagName("IMAGE").length === 0 ? "..." : elem.getElementsByTagName("IMAGE")[0].width + 'x' + [0].height;

      table += "<tr><td>" + cats + "</td><td>" + titles + "</td><td>" + "<img src=" + imageURL + ' height="150" width="100">' + '</td><td id="cellId"><textTag>' + "" + "</textTag></td></tr>";
    }
    document.getElementById("myTable").innerHTML = table;
		
    document.querySelector("img").addEventListener('load', function() {
      var imgTags = document.querySelectorAll('img'), i;
      for (i = 0; i < imgTags.length; ++i) {
          var image_width = document.querySelector("img").naturalWidth;
          var image_height = document.querySelector("img").naturalHeight;
      }
      $('#myTable textTag').each(function() {
      $(this).append(image_width + 'x' + image_height);
      //console.log(image_width + 'x' + image_height);
      });
    });
}
table,
th,
td {
  border: 1px solid black;
  border-collapse: collapse;
}

th,
td {
  padding: 5px;
}
<head>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>

<button type="button" onclick="loadDoc()">Load</button>
<br><br>
<table id="myTable"></table>

Ожидаемое:

enter image description here

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Хорошо, в вашем вопросе есть много частей, я начал делать простейшую вещь, регистрируя проанализированный XML-документ, и выглядит так:

...
<IMAGE url="...."></IMAGE>
<IMAGESIZE></IMAGESIZE>
...

Итак, в вашем скрипте вы получаете атрибут, который несуществовать.Таким образом, вы можете безопасно удалить эту строку:

var imageSize = elem.getElementsByTagName("IMAGE").length === 0 ? "..." : elem.getElementsByTagName("IMAGE")[0].width + 'x' + [0].height;

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

"<img src=" + imageURL + ' height="150" width="100" onload="this._loaded = true;">' +

, это добавит проприетарный _loadedсвойство к нему.

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

var imgTags = document.getElementsByTagName('img');
    function isLoaded(){
        if(Array.prototype.slice.call(imgTags).some(function(d,i){return !d._loaded})){
        setTimeout(isLoaded,4);
      } else {
        $('#myTable textTag').each(function(i,node) {
         node.textContent = imgTags[i].naturalWidth + 'x' + imgTags[i].naturalHeight;
          //console.log(image_width + 'x' + image_height);
        });
      }
    };
    isLoaded();

Я удалил бит querySelectorAll(img), он медленнее по сравнению с getElementsByTagName и не возвращает LIVE HTML Collection, возвращает NodeList.Загруженная функция запустит ваш Jquery, как только обнаружит все свойства _loaded.Array.prototype.slice.call - это старомодный способ преобразования HTML Collection или NodeList в обычный массив, крутые дети, которых вы Array.from в наше время, решать только вам.Вы также можете немного оптимизировать вышеупомянутую функцию, сохраняя результат Array.prototype.slice.call... один раз, я оставляю это вам.В целом это выглядит так:

https://jsfiddle.net/ibowankenobi/h9evc81a/

0 голосов
/ 06 февраля 2019

Проблема в том, что вам нужно подождать, пока изображения загрузятся, прежде чем запрашивать такие свойства, как width или height.

Обычно это делается путем установки обработчика событий onload, который обновляет отображениеиз этих свойств.

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

Вывместо этого нужно выполнить запрос во втором цикле.

...