如何在JavaScript中结合querySelectorAll与switch处理自定义data属性?
解决根据自定义data属性用switch处理元素的问题
你的核心问题是:之前用element.tagName.toLowerCase()拿的是元素的标签名(比如h2、div),但你要匹配的是data-printpdf-*这类自定义属性的后缀,两者完全不搭,所以switch分支根本触发不了。同时,表单元素(input、textarea)不能用textContent取内容,得用value,这也是你拿不到文本的原因。
下面是具体的修正方案:
1. 写个辅助函数,精准获取printpdf属性类型
遍历元素的所有属性,找到以data-printpdf-开头的那个,提取后面的部分作为switch的判断依据:
function getPrintPdfElementType(element) { for (const attr of element.attributes) { if (attr.name.startsWith('data-printpdf-')) { return attr.name.replace('data-printpdf-', ''); } } return null; // 没找到匹配属性就跳过 }
2. 改写循环和switch逻辑
替换原来的elementType赋值,用上面的函数拿到属性类型,然后对应分支处理:
var elementsToPrint = document.querySelectorAll( '[data-printpdf-Cpv-response-div="true"], [data-printpdf-Cpv-div="true"], [data-printpdf-Cig-div="true"], [data-printpdf-h2="true"], [data-printpdf-span="true"], [data-printpdf-input="true"], [data-printpdf-textarea="true"], [data-printpdf-label="true"], [data-printpdf-div="true"], [data-printpdf-label-roleName-label="true"], [data-printpdf-label-procedure-label="true"], [data-printpdf-strong="true"]' ); // 遍历元素生成PDF for (var i = 0; i < elementsToPrint.length; i++) { var element = elementsToPrint[i]; var printType = getPrintPdfElementType(element); if (!printType) continue; // 无匹配属性直接跳过 switch (printType) { case 'h2': // h2的PDF样式和文本处理 doc.setFont("Verdana", "bold"); doc.setFontSize(12); var textParts = doc.splitTextToSize(element.textContent, pageWidth - 2 * margin); textParts.forEach((part) => { if (currentY + 5 > pageHeight - margin) { doc.addPage(); currentY = margin; } doc.text(part, leftMargin, currentY); currentY += 10; }); break; case 'span': case 'strong': // 普通文本元素的处理 doc.setFont("Verdana", "normal"); doc.setFontSize(10); var textParts = doc.splitTextToSize(element.textContent, pageWidth - 2 * margin); textParts.forEach((part) => { if (currentY + 5 > pageHeight - margin) { doc.addPage(); currentY = margin; } doc.text(part, leftMargin, currentY); currentY += 8; }); break; case 'input': case 'textarea': // 表单元素要取value而非textContent doc.setFont("Verdana", "normal"); doc.setFontSize(10); var content = element.value || '无输入内容'; var textParts = doc.splitTextToSize(content, pageWidth - 2 * margin); textParts.forEach((part) => { if (currentY + 5 > pageHeight - margin) { doc.addPage(); currentY = margin; } doc.text(part, leftMargin, currentY); currentY += 8; }); break; case 'Cpv-response-div': case 'Cpv-div': // 自定义div的特殊处理 doc.setFont("Verdana", "italic"); doc.setFontSize(10); var textParts = doc.splitTextToSize(element.textContent, pageWidth - 2 * margin); textParts.forEach((part) => { if (currentY + 5 > pageHeight - margin) { doc.addPage(); currentY = margin; } doc.text(part, leftMargin, currentY); currentY += 8; }); break; // 其他属性类型的分支可以继续添加 default: // 默认处理逻辑,兜底用 doc.setFont("Verdana", "normal"); doc.setFontSize(10); var content = element.textContent || element.value || ''; var textParts = doc.splitTextToSize(content, pageWidth - 2 * margin); textParts.forEach((part) => { if (currentY + 5 > pageHeight - margin) { doc.addPage(); currentY = margin; } doc.text(part, leftMargin, currentY); currentY += 8; }); } }
重点提醒
- 表单元素(input、textarea)必须用
element.value获取内容,textContent拿不到用户输入的值。 - 如果一个元素同时有多个
data-printpdf-*属性,上面的辅助函数会返回第一个匹配的;如果需要处理多属性,可以改成返回属性数组再逐个处理。
内容的提问来源于stack exchange,提问作者Gaetano Cerciello
相关产品推荐
相关产品推荐

