首页 > 解决方案 > 将替代文本转换为图像标题节点

问题描述

function altTextToImageCaption() {
  let imgs = document.getElementsByTagName('img');
  for (var i = 0; i < imgs.length; i++) {
    var att = imgs[i].attributes.getNamedItem('alt');
    if (!att) continue;
    var alt = att.value;
    if (!alt) continue;
    if (!alt.startsWith('Fig ')) continue;
    var cap = document.createElement('div');
    cap.setAttribute('class', 'imageCaption');
    cap.appendChild(document.createTextNode(alt));
    document.body.insertBefore(cap, imgs[i].nextSibling);
  }
}
<body onload="altTextToImageCaption()">
  <h1>Image Caption No Workie</h1>
  <img src="https://www.easyrgb.com/look/home_logo.png" alt="Fig 1. First caption.">

  <div>
  <img src="https://www.easyrgb.com/look/home_logo.png" alt="Fig 2. Second caption.">
  </div>
</body>

我正在尝试提出一个 jscript 函数,该函数在 html 文档中的所有图像下方插入标题文本,其中包含alt以“图”开头的属性。似乎可以工作,除非img节点位于 adivspan. 在这种情况下有一个例外:

Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."

标签: htmljscript

解决方案


我建议换行:

document.body.insertBefore(cap, imgs[i].nextSibling);

至:

imgs[i].parentNode.insertBefore(cap, imgs[i].nextSibling);

这确保<div>总是附加在<img>自身之后,无论它出现在 DOM 中的什么位置:

function altTextToImageCaption() {
  let imgs = document.getElementsByTagName('img');
  for (var i = 0; i < imgs.length; i++) {
    var att = imgs[i].attributes.getNamedItem('alt');
    if (!att) continue;
    var alt = att.value;
    if (!alt) continue;
    if (!alt.startsWith('Fig ')) continue;
    var cap = document.createElement('div');
    cap.setAttribute('class', 'imageCaption');
    cap.appendChild(document.createTextNode(alt));
    imgs[i].parentNode.insertBefore(cap, imgs[i].nextSibling);
  }
}
<body onload="altTextToImageCaption()">
  <h1>Image Caption No Workie</h1>
  <img src="https://www.easyrgb.com/look/home_logo.png" alt="Fig 1. First caption.">

  <div>
    <img src="https://www.easyrgb.com/look/home_logo.png" alt="Fig 2. Second caption.">
  </div>
</body>

然而,虽然这解决了问题,但我也会将您的函数完全重写为以下内容——并且还使用不显眼的 JavaScript——以下内容:

// using an Arrow function to create the function as a const:
const altTextToImageCaption = () => {
  // using document.querySelectorAll() to retrieve only
  // <img> elements that have an 'alt' attribute that starts
 // with the string "Fig "
  let images = document.querySelectorAll('img[alt^="Fig "]');

  // using NodeList.prototype.forEach() to iterate over the
  // NodeList of <img> element-nodes:
  images.forEach(
    // using an anonymous Arrow function:
    (img) => {
      // retrieving the attribute-value of the 'alt'
      // attribute, and removing leading/trailing
      // white-space:
      let alt = img.alt.trim(),
        // creating a <div> element:
        div = document.createElement('div');

      // using the Element.classList API to add the
      // 'imageCaption' class-name:
      div.classList.add('imageCaption');
      // using ParentNode.append() to append
      // the string:
      div.append(alt);

      // navigating to the <img> element's parent,
      // and using ParentNode.insertBefore() to
      // insert the new ('div') content before the
      // next-sibling of the <img> element:
      img.parentNode.insertBefore(div, img.nextSibling);
    });
}

// binding the event-handling in JavaScript rather than inline
// event-binding; here we bind the altTextToImageCaption() function
// as the event-handler for the 'DOMContentLoaded' event:
window.addEventListener('DOMContentLoaded', altTextToImageCaption);
<body>
  <h1>Image Caption No Workie</h1>
  <img src="https://www.easyrgb.com/look/home_logo.png" alt="Fig 1. First caption.">

  <div>
    <img src="https://www.easyrgb.com/look/home_logo.png" alt="Fig 2. Second caption.">
  </div>
</body>


推荐阅读