【问题标题】:show image in table html在表格 html 中显示图像
【发布时间】:2021-09-26 06:09:55
【问题描述】:

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

[图片浏览器][1]:https://i.stack.imgur.com/nbbgH.png

[显示表格的HTML页面][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>

【问题讨论】:

    标签: javascript html csv html-table


    【解决方案1】:

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

    我们需要:

    • 根据其类/ID(.image_file_name#show_image)查找列元素
    • 查找列的索引。所以我们根据标题单元格 (&lt;th&gt;) 的索引知道要获取哪个数据单元格 (&lt;td&gt;)
    • 检查图像是否存在(当我们尝试获取图像时它是否返回200404
    • 创建图像元素并将它们附加到适当的行/列

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

    /**
     * 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)并返回其索引。

    /**
     * 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() 函数是异步的(返回 Promise)。它接受图像文件名并返回一个解析为boolean的Promise,指示图像是否存在(响应200 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,创建一个 &lt;img&gt; 元素并返回它。

    现在我们有了辅助函数,让我们编写剩下的部分。我们将监听 DOMContentLoaded 事件以确保初始 HTML 文档已完全加载(即我们的 &lt;table&gt; 存在)。

    /**
     * Run the initial HTML document has been completely loaded.
     */
    const init = async () => {
      // Do stuff
    }
    
    window.addEventListener('DOMContentLoaded', init);
    

    让我们获取表格及其行:

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

    如果我们知道表格的布局,我们可以显式设置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>
    

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

    【讨论】:

    • 如何将 table.html 文件连接到此代码?
    • @johndiv 您可以在&lt;script&gt; 文件中的&lt;script&gt; 标记中插入JavaScript。
    • @johndiv 我更新了我的答案以包含您在问题中提供的 HTML 代码。如果它解决了您的问题,请考虑将其标记为已接受:)
    • url 有什么作用,我所有的图像都在 show_image 文件夹中。我如何在代码中调用它
    • 您能详细说明一下吗?你指的是什么“网址”?
    【解决方案2】:

    我的方法是在每个表格行中创建一个图像对象,然后将源设置为第二列的内容。 为此,我们需要给 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的功能。

    【讨论】:

    • 如何将 table.html 文件连接到此代码?
    • 您将脚本作为&lt;script defer&gt;[code]&lt;/script&gt; 标记包含在html 的&lt;head&gt; 元素中。 defer 的意思是'在页面完全加载后加载脚本',需要避免document.getElementById 的错误。另外,不要忘记调用该函数。
    • 这是正确的 .... function displayPictures() { var tbody, row, imageObject tbody = document.getElementById("tbody >tr >td") for (row of tbody) { imageObject.onerror = function (e) { this.src = ['/imagetocsv/img/'] } imageObject.alt = "未找到" imageObject = new Image() imageObject.src = row[2].innerText row[5].innerHTML = "" 行[5].appendChild(imageObject) } }
    猜你喜欢
    • 1970-01-01
    • 2019-06-26
    • 2020-10-07
    • 1970-01-01
    • 2018-03-30
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    相关资源
    最近更新 更多