将 <img> 替代文本转换为图像标题节点
Converting <img> alt text to image caption node
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 文档中的所有图像下方插入一个标题文本,该文档包含一个以“Fig”开头的 alt
属性。似乎工作正常,除非 img
节点位于 div
或 span
内。在那种情况下有一个例外:
Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."
我建议更改线路:
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>
您需要使用图片的parentNode
调用insertBefore
。
作为额外的清理,您可以使用 for..of
稍微清理一下代码。
我提议:
function altTextToImageCaption() {
let imgs = document.getElementsByTagName('img')
for(let img of imgs) {
var att = img.attributes.getNamedItem('alt')
if (!att) continue
let alt = att.value
if (!alt) continue
if (!alt.startsWith('Fig ')) continue
let cap = document.createElement('div')
cap.setAttribute('class', 'imageCaption')
cap.appendChild(document.createTextNode(alt))
img.parentNode.insertBefore(cap, img.nextSibling)
}
}
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 文档中的所有图像下方插入一个标题文本,该文档包含一个以“Fig”开头的 alt
属性。似乎工作正常,除非 img
节点位于 div
或 span
内。在那种情况下有一个例外:
Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."
我建议更改线路:
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>
您需要使用图片的parentNode
调用insertBefore
。
作为额外的清理,您可以使用 for..of
稍微清理一下代码。
我提议:
function altTextToImageCaption() {
let imgs = document.getElementsByTagName('img')
for(let img of imgs) {
var att = img.attributes.getNamedItem('alt')
if (!att) continue
let alt = att.value
if (!alt) continue
if (!alt.startsWith('Fig ')) continue
let cap = document.createElement('div')
cap.setAttribute('class', 'imageCaption')
cap.appendChild(document.createTextNode(alt))
img.parentNode.insertBefore(cap, img.nextSibling)
}
}