在 table html 中显示图片

show image in table html

我需要这方面的帮助。 首先检查 image_file_name 是否存在于 html table 中,然后使用 javascript.I 在另一个单元格中检查 show_image 是否提供了 2 张图像。第一张图片包含一个图片文件夹,其中我有一个图片列表,第二张图片显示 HTML 页面

的布局

[图片下载][1]: https://i.stack.imgur.com/nbbgH.png

[HTML 显示 table][2] 的页面:https://i.stack.imgur.com/cgQ5N.png

  <table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>Image_id</th>
      <th class="image_file_name">image_file_name</th>
      <th>Image_Text_output </th>
      <th>date</th>
      <th id="show_image">Show_image</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>./imagetocsv/img/MessageMediaPhoto-ID-158.jpg</td>
      <td>test 2</td>
      <td>24-09-2021 12:20:47</td>
      <td>NaN</td>
    </tr>
    <tr>
      <td>2</td>
      <td>./imagetocsv/img/MessageMediaPhoto-ID-428.jpg</td>
      <td>test 2</td>
      <td>24-09-2021 12:20:47</td>
      <td>NaN</td>
    </tr>

好吧,让我们把这个问题分解成更小的问题,这样更容易解决。

我们需要:

  • 根据 class/id(.image_file_name#show_image
  • 查找列元素
  • 查找列的索引。所以我们知道根据header单元格(<th>
  • 的索引获取哪个数据单元格(<td>
  • 检查图像是否存在(当我们尝试获取图像时,它是 returns 200 还是 404
  • 创建图像元素并将它们附加到适当的 row/column

让我们为此创建一些辅助函数:

/**
 * Return the index of the given column.
 *
 * @param {HTMLElement} column
 * @return {number}
 */
 const getColumnIndex = (column) => {
  const row = column.parentNode;
  const columns = [...row.children];
  return columns.indexOf(column);
}

getColumnIndex() 函数接受一个列(作为 HTMLElement)和 returns 它的索引。

/**
 * Asynchonously check if the file with the given filename exists.
 *
 * @return {Promise<boolean>}
 */
const fileExists = async (filename) => {
  const response = await fetch(filename, { method: 'HEAD' });
  return response.ok;
}

fileExists()函数是异步的(returns一个Promise)。它接受图像文件名和 returns 解析为 boolean 的 Promise,指示图像是否存在(响应 200 OK 状态)或不存在(响应 non-ok状态,即 404 Not Found).

/**
 * Create an image element with the given URL.
 *
 * @param {string} url
 * @return {HTMLElement}
 */
const createImageElement = (url) => {
  const image = document.createElement('img');
  image.setAttribute('src', url);
  return image;
};

createImageElement() 函数接受一个 URL,创建一个 <img> 元素并 returns 它。

现在我们有了我们的辅助函数,让我们来编写它的其余部分。我们将监听 DOMContentLoaded 事件以确保初始 HTML 文档已完全加载(即我们的 <table> 存在)。

/**
 * Run the initial HTML document has been completely loaded.
 */
const init = async () => {
  // Do stuff
}

window.addEventListener('DOMContentLoaded', init);

让我们获取 table 及其行:

// Get the table and its rows
const table = document.querySelector('.dataframe');
const rows = table.querySelectorAll('tbody > tr');

如果我们知道 table 的布局,我们可以显式设置 image_file_nameshow_image 索引:

const filenameIndex = 1;
const imageIndex = 4;

否则,我们可以利用 getColumnIndex() 函数来查找它们,如下所示:

// Get the `image_file_name` and `show_image` columns
const filenameColumn = table.querySelector('th.image_file_name');
const imageColumn = table.querySelector('th#show_image');

const filenameIndex = getColumnIndex(filenameColumn);
const imageIndex = getColumnIndex(imageColumn);

最后,我们将遍历每一行,获取文件名,检查该图像是否存在,如果存在则显示它。

// Iterate over each row
for await (const row of rows) {
  // Get all columns of the currently iterated row
  const columns = row.children;

  // Get the filename
  const filename = columns[filenameIndex].textContent;

  // Check if the image exists
  const imageExists = await fileExists(filename);

  // If it exists
  if (imageExists) {
    // Clear the `show_image` column
    columns[imageIndex].innerHTML = '';

    // Create an image element
    const image = createImageElement(filename);

    // Add the image
    columns[imageIndex].appendChild(image);
  }
}

综合起来:

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>Image_id</th>
      <th class="image_file_name">image_file_name</th>
      <th>Image_Text_output </th>
      <th>date</th>
      <th id="show_image">Show_image</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>./imagetocsv/img/MessageMediaPhoto-ID-158.jpg</td>
      <td>test 2</td>
      <td>24-09-2021 12:20:47</td>
      <td>NaN</td>
    </tr>
    <tr>
      <td>2</td>
      <td>./imagetocsv/img/MessageMediaPhoto-ID-428.jpg</td>
      <td>test 2</td>
      <td>24-09-2021 12:20:47</td>
      <td>NaN</td>
    </tr>
  </tbody>
</table>
<script type="text/javascript">
  /**
    * Return the index of the given column.
    *
    * @param {HTMLElement} column
    * @return {number}
    */
  const getColumnIndex = (column) => {
    const row = column.parentNode;
    const columns = [...row.children];
    return columns.indexOf(column);
  }

  /**
    * Asynchonously check if the file with the given filename exists.
    *
    * @return {Promise<boolean>}
    */
  const fileExists = async (filename) => {
    const response = await fetch(filename, { method: 'HEAD' });
    return response.ok;
  }

  /**
    * Create an image element with the given URL.
    *
    * @param {string} url
    * @return {HTMLElement}
    */
  const createImageElement = (url) => {
    const image = document.createElement('img');
    image.setAttribute('src', url);
    return image;
  };

  /**
    * Run  the initial HTML document has been completely loaded.
    */
  const init = async () => {
    // Get the table element
    const table = document.querySelector('.dataframe');

    // Get the `image_file_name` and `show_image` columns
    const filenameColumn = table.querySelector('th.image_file_name');
    const imageColumn = table.querySelector('th#show_image');
    
    const filenameIndex = getColumnIndex(filenameColumn);
    const imageIndex = getColumnIndex(imageColumn);

    // Get the table rows
    const rows = table.querySelectorAll('tbody > tr');

    // Iterate over each row
    for await (const row of rows) {
      // Get all columns of the currently iterated row
      const columns = row.children;

      // Get the filename
      const filename = columns[filenameIndex].textContent;

      // Check if the image exists
      const imageExists = await fileExists(filename);

      // If it exists
      if (imageExists) {
        // Clear the `show_image` column
        columns[imageIndex].innerHTML = '';

        // Create an image element
        const image = createImageElement(filename);

        // Add the image
        columns[imageIndex].appendChild(image);
      }
    }
  };

  window.addEventListener('DOMContentLoaded', init);
</script>

免责声明:此答案包括箭头函数、promises、async/await、展开运算符和其他 ES6+ 功能。

我的方法是在每个 table 行中创建一个图像对象,然后将源设置为第二列的内容。 为此,我们需要给 tbody 元素一个 id,然后遍历它的每个子元素。

像这样:

function displayPictures(){
    //Get the tbody element
    var tbody=document.getElementById("tbody")
    //For each row
    for (var row of tbody){
        //We create an image object 
        var imageObject=new Image()
        //We set the image source to the 2nd columns content
        imageObject.src=row[1].innerText
        //And finally, we replace the 5th cell's content
        row[4].innerHTML=""
        row[4].appendChild(imageObject)
    }
}

为了提高内存效率,我们可以在单个 var 语句中声明每个局部变量,如下所示:

function displayPictures(){
    //Deaclaring variables
    var tbody,row,imageObject
    //Get the tbody element
    tbody=document.getElementById("tbody")
    //For each row
    for (row of tbody){
        //We create an image object 
        imageObject=new Image()
        //We set the image source to the 2nd columns content
        imageObject.src=row[1].innerText
        //And finally, we replace the 5th cell's content
        row[4].innerHTML=""
        row[4].appendChild(imageObject)
    }
}

您可以在插入图片之前轻松地操作它们(例如:设置它们的高度和宽度)。


另一种方法是 fetch 图片,但这不是必需的,因为跨源资源共享策略不影响简单的图像查询(据我所知)。

编辑: Over-engineer 的 Ansver 让我想起了错误处理: 您可以简单地将 onerror 处理程序附加到 Image 对象,以设置占位符图像或更轻松地设置一个 alt 文本,当图像无法显示时显示该文本。

//This sets a placeholder image if any error occours.
imageObject.onerror=function(e){this.src=[path to placeholder image]}
//The alt text is only shown when the image fails to load properly.
//It's mostly used to describe the functionality of the image, but in this case, the 'Not found' is enough.
imageObject.alt="Not found"

这个方法不单纯依赖JS,它也利用了HTML的功能