Bootstrap卡片加密货币API折叠功能失效,点击按钮报ReferenceError错误求助
加密货币项目折叠功能错误排查与修复
问题描述
正在学习全栈开发,做一个加密货币项目:通过Ajax调用CoinGecko API,搜索并展示加密货币到Bootstrap卡片中,添加折叠面板显示额外信息。但点击Bitcoin的“MORE INFO”按钮时,控制台抛出错误:
Uncaught ReferenceError: bitcoin is not defined at HTMLButtonElement.onclick (home.html:1:15) onclick @ home.html:1
折叠功能完全无法工作,尝试多种方法两周仍未解决。原代码如下:
let cryptos = [] const baseUrl = 'https://api.coingecko.com/api/v3/coins' let singleCrypto = {} showAll() // SEARCH function onSubmit(val) { console.log('SUBMIT : ', val) cryptoContainer.innerHTML = '' $.ajax({ type: 'GET', datatype: 'json', url: baseUrl + "/" + val, success: function (data) { singleCrypto = data printShow(singleCrypto) }, error: function (error) { console.log('error : ', error) }, }) } function showAll() { $.ajax({ type: 'GET', datatype: 'json', url: baseUrl, success: function (data) { cryptos = data printShowsAll() }, error: function (error) { console.log('error : ', error) }, }) } function printShowsAll() { for (var i = 0; i < cryptos.length; i++) { printShow(cryptos[i]) } } function printShows() { for (var i = 0; i < cryptos.length; i++) { printShow(cryptos[i].crypto) } } function printShow(crypto) { // console.log(crypto) cryptoContainer.innerHTML += ` <div class="col-3"> <div class="card" style="margin: 10px; border: 1px solid gray"> <div class="card-body"> <div id="toggle"></div> <h5 class="card-title">${crypto.name}</h5> <div class="symbolDV"> ${crypto.symbol} </div> <button type="button" class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#collapse" aria-expanded="false" onClick=moreInfoPrint(${crypto.id})>MORE INFO </button> <div id="collapse"></div> </div> </div> </div>` } function moreInfo(data) { collapse.innerHTML = ` <img src="${data.image ? data.image.thumb : ''}" alt="Card image cap"> <div class="usd">${(data.market_data.current_price.usd) + 'USD'}</div> <div class="eur">${(data.market_data.current_price.eur) + 'EUR'}</div> <div class="ils">${(data.market_data.current_price.ils) + 'ILS'}</div> ` console.log('moreInfo:', data) } function moreInfoPrint(id){ console.log(id) showAll(moreInfo, id) }
错误原因分析
- onClick参数未加引号:
onClick=moreInfoPrint(${crypto.id})生成的HTML是onClick=moreInfoPrint(bitcoin),浏览器会把bitcoin当作变量而非字符串,但全局不存在这个变量,导致ReferenceError。 - 重复的DOM ID:所有卡片的折叠面板都用
id="collapse",Bootstrap的Collapse组件要求目标ID唯一,否则点击会触发所有面板,且无法精准定位单个面板。 - moreInfoPrint函数逻辑错误:调用
showAll(moreInfo, id),但showAll函数没有接收回调和ID参数的逻辑,无法正确获取单条加密货币的详情数据。 - 未定义的DOM元素引用:
moreInfo函数中直接使用collapse变量,但该变量未通过document.getElementById或其他方式获取,会导致后续操作失败。
修复步骤及代码
核心修改点:
- 为
onClick的ID参数添加引号,确保传递字符串值:onClick="moreInfoPrint('${crypto.id}')" - 为每个折叠面板生成唯一ID:
id="collapse-${crypto.id}",对应按钮的data-bs-target改为#collapse-${crypto.id} - 重写
moreInfoPrint函数,单独请求对应ID的加密货币数据,并传入目标折叠面板元素 - 在
moreInfo函数中操作指定的折叠面板元素
修复后的完整代码:
let cryptos = [] const baseUrl = 'https://api.coingecko.com/api/v3/coins' let singleCrypto = {} showAll() // SEARCH function onSubmit(val) { console.log('SUBMIT : ', val) cryptoContainer.innerHTML = '' $.ajax({ type: 'GET', datatype: 'json', url: `${baseUrl}/${val}`, success: function (data) { singleCrypto = data printShow(singleCrypto) }, error: function (error) { console.log('error : ', error) }, }) } function showAll() { $.ajax({ type: 'GET', datatype: 'json', url: baseUrl, success: function (data) { cryptos = data printShowsAll() }, error: function (error) { console.log('error : ', error) }, }) } function printShowsAll() { cryptoContainer.innerHTML = '' // 清空容器避免重复渲染 for (let i = 0; i < cryptos.length; i++) { printShow(cryptos[i]) } } function printShow(crypto) { const collapseId = `collapse-${crypto.id}` cryptoContainer.innerHTML += ` <div class="col-3"> <div class="card" style="margin: 10px; border: 1px solid gray"> <div class="card-body"> <div id="toggle-${crypto.id}"></div> <h5 class="card-title">${crypto.name}</h5> <div class="symbolDV">${crypto.symbol.toUpperCase()}</div> <button type="button" class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#${collapseId}" aria-expanded="false" onclick="moreInfoPrint('${crypto.id}')"> MORE INFO </button> <div id="${collapseId}" class="collapse mt-2"></div> </div> </div> </div>` } function moreInfo(data, collapseElement) { collapseElement.innerHTML = ` <img src="${data.image?.thumb || ''}" alt="${data.name} logo" class="img-fluid mb-2"> <div class="usd">USD: ${data.market_data.current_price.usd.toFixed(2)}</div> <div class="eur">EUR: ${data.market_data.current_price.eur.toFixed(2)}</div> <div class="ils">ILS: ${data.market_data.current_price.ils.toFixed(2)}</div> ` } function moreInfoPrint(id) { const collapseElement = document.getElementById(`collapse-${id}`) // 避免重复请求,若面板已展开可直接返回 if (collapseElement.innerHTML) return $.ajax({ type: 'GET', datatype: 'json', url: `${baseUrl}/${id}`, success: function (data) { moreInfo(data, collapseElement) }, error: function (error) { console.log('error fetching details: ', error) collapseElement.innerHTML = '<p>Failed to load details</p>' }, }) }
额外优化说明
- 添加了
cryptoContainer.innerHTML = ''在printShowsAll中,避免多次调用时重复渲染卡片 - 对价格使用
toFixed(2)保留两位小数,提升显示美观度 - 使用可选链操作符
data.image?.thumb简化空值判断 - 为toggle元素也添加了唯一ID,方便后续扩展切换开关功能
- 增加了错误提示,当详情请求失败时显示友好信息
内容的提问来源于stack exchange,提问作者user20792158
相关产品推荐
相关产品推荐

