动态生成的Base64图片无法赋值给img src?求解决方案
动态生成的Base64图片无法绑定到img的src属性
代码可生成有效的Base64字符串,但执行img.src = imgbase64动态赋值时无效,手动将该Base64字符串粘贴到img的src属性中却能正常显示。
请在代码片段中点击图片并上传任意图片测试
核心问题
如何将动态生成的图片Base64字符串绑定到HTML img元素的src属性?
操作步骤
- 点击任意图片
- 上传任意图片
- 代码将上传的图片转换为Base64字符串
- 问题出现:将Base64赋值给img的src时失效
问题根源
FileReader.readAsDataURL()是异步操作,原代码中在调用reader.readAsDataURL(file)之前就执行了imgToChange.src = base64String,此时base64String还是初始的空字符串。等异步读取完成后,虽然base64String被正确赋值,但已经没有再更新img的src,所以图片无法显示。
修复后的完整代码
完整代码(HTML+CSS+JS)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .reverb-image-changer{ display: block; border: 1px solid transparent; text-align: center; color: white; cursor: pointer; margin-top: 0; transition: .3s; z-index: 999; } .reverb-image-changer:hover{ border-color: rgb(46, 204, 113); cursor: pointer; } .reverb-image-changer input{ width: 0px; height: 0px; visibility: hidden; position: absolute; top: 0; left: -100%; } </style> </head> <body> <img src="https://picsum.photos/200/300" alt="" width="200" height="300"> <img src="https://picsum.photos/200/300" alt="" width="200" height="300"> <img src="https://picsum.photos/200/300" alt="" width="200" height="300"> <img src="https://picsum.photos/200/300" alt="" width="200" height="300"> <script> function log(msg){return console.log(msg); } function removeClass(el, _className="active"){if(el){return hasClass(el, _className) ? el.classList.remove(_className) : true; } return false; } function hasClass(el, _className="active"){if(el.classList.contains(_className)){return true; } else {return false; } return false; } function getElement(target, targetFrom=false){return targetFrom ? targetFrom.querySelector(target) : document.querySelector(target); } function getElements(target, targetFrom=false){return targetFrom ? [...targetFrom.querySelectorAll(target)] : [...document.querySelectorAll(target)]; } function getElementById(target, targetFrom=false){return targetFrom ? targetFrom.getElementById(target) : document.getElementById(target); } function addClass(el, _className="active"){if(el){return !hasClass(el, _className) ? el.classList.add(_className) : true; } return false; } function getParent(el, idx){previouslyParent = el.parentElement; for (let index = 0; index < idx - 1; index++) {previouslyParent = previouslyParent.parentElement; } return previouslyParent; } function getOffset(el) {const rect = el.getBoundingClientRect(); return {"top": rect.top + window.scrollY, "left": rect.left + window.scrollX }; } function objectToTagStyles(selector, styles){if(styles){var style = document.createElement('style'); resonanceCssString = `${selector} {`; for (const [key, value] of Object.entries(styles)) {resonanceCssString += `${key}:${value};`; } resonanceCssString += "}"; if (style.styleSheet) {style.styleSheet.cssText = resonanceCssString; } else {style.appendChild(document.createTextNode(resonanceCssString)); } document.getElementsByTagName('head')[0].appendChild(style); return true; } return false; } function objectToCssTextStyles(styles){if(styles){resonanceCssString = ''; for (const [key, value] of Object.entries(styles)) {resonanceCssString += `${key}:${value};`; } return resonanceCssString; } return false; } function getAttribute(element, attr, isReturnValue){return isReturnValue ? element.attributes[attr].value : element.attributes[attr]; } function stringGen(yourNumber){var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < yourNumber; i++){text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; } let base64String = ""; function imageUploaded() { var file = this['files'][0]; var reader = new FileReader(); // 保存当前input的id,避免回调中this指向变化 const currentInputId = this.id; reader.onload = function () { base64String = reader.result; console.log(base64String); // 读取完成后再给img赋值src const imgToChange = getElement(`.change-this-image__${currentInputId}`); if(imgToChange) { imgToChange.src = base64String; } } reader.readAsDataURL(file); } const imgs = getElements('img'); const svgs = getElements('svg'); getElement('body').style.position = 'relative'; for(let imageElement of imgs){ const newChangeImageWrapper = document.createElement("label"); const newChangeImageInput = document.createElement("input"); addClass(newChangeImageWrapper, 'reverb-image-changer'); const randomNewWapperId = stringGen(10); const randomNewInputId = stringGen(10); const currentImgOffset = getOffset(imageElement); addClass(newChangeImageWrapper, `reverb-image-changer--id_${randomNewWapperId}`); newChangeImageWrapper.setAttribute("for", randomNewInputId); newChangeImageInput.setAttribute("id", randomNewInputId); newChangeImageInput.type = "file"; newChangeImageInput.onchange = imageUploaded; newChangeImageWrapper.appendChild(newChangeImageInput) addClass(imageElement, `change-this-image__${randomNewInputId}`); const currentImageBoundaries = imageElement.getBoundingClientRect(); const currentWrapperStyles = { "width": `${currentImageBoundaries.width}px`, "height": `${currentImageBoundaries.height}px`, "position": "fixed", "top": `${currentImageBoundaries.y}px`, "left": `${currentImageBoundaries.x}px` } newChangeImageWrapper.style.cssText = objectToCssTextStyles(currentWrapperStyles); getElement('body').appendChild(newChangeImageWrapper); } </script> </body> </html>
关键修改点
- 将
imgToChange.src的赋值逻辑移到reader.onload回调内部,确保Base64字符串生成后再执行赋值。 - 提前保存当前input的id,避免在异步回调中
this指向发生变化,导致无法正确匹配对应的img元素。
内容的提问来源于stack exchange,提问作者perolamutr
相关产品推荐
相关产品推荐

