Airtable JS点击修改API请求offset参数实现分页的解决方案
Airtable API分页加载实现方案
核心修改逻辑
- 封装URL生成方法,每次请求数据时动态拼接最新的offset参数,解决全局URL不会随offset更新的问题
- 下一页按钮绑定点击事件,阻止默认跳转行为,更新全局offset值后重新拉取数据
- 每次加载新页面前清空旧的卡片内容,同时移除上一次生成的下一页按钮,避免重复渲染
- 判断Airtable返回的offset是否存在,没有下一页数据时不渲染下一页按钮
注意:你原有代码里的
filterByFormula参数末尾多了一个多余的2,会导致过滤条件失效,建议修正为&filterByFormula=%7Bvip_ou_50%7D%3D%2250%22
修正后完整JS代码
var type = "Coupons" var api_key = "?api_key=1234" var maxRecords = "&maxRecords=10" var filterByFormula = "&filterByFormula=%7Bvip_ou_50%7D%3D%2250%22" // 初始offset为空,第一次请求不需要传offset参数 var offset = "" const app = document.getElementById('root') const card = document.createElement('div'); card.setAttribute('class', 'rightcontainer w-container') app.appendChild(card) // 封装URL生成函数,每次调用动态拼接最新参数 function generateUrl() { let offsetParam = offset ? `&offset=${offset}` : "" return "https://api.airtable.com/v0/app1234/" + type + api_key + maxRecords + filterByFormula + offsetParam + "&sort%5B0%5D%5Bfield%5D=coupons_id"; } async function catchJson() { const url = generateUrl() const response = await fetch(url); const data = await response.json(); if (response.status >= 200 && response.status < 400) { // 加载新数据前清空旧内容 card.innerHTML = '' const records_length = document.getElementById('number') records_length.innerHTML = 'Liste de coupons <br> <a href="" class="button-2 left-aligned w-button"><span class="text-span-2">Ouvrir la Map</span></a>' data.records.forEach(records => { const property_card = document.createElement('a') property_card.setAttribute('class', 'property-card left w-inline-block w-clearfix') property_card.style.background = `-webkit-gradient(linear, left top, left bottom, color-stop(29%, hsla(0, 0%, 100%, 0)), color-stop(68%, rgba(0, 0, 0, 0.5))), url('${records.fields.image_url}')`; property_card.style.background = `linear-gradient(180deg, hsla(0, 0 %, 100 %, 0) 29 %, rgba(0, 0, 0, 0.5) 68 %), url('${records.fields.image_url}')`; const image_quantity_div = document.createElement('div') image_quantity_div.setAttribute('class', 'image-quantity-div') const price_text = document.createElement('h1') price_text.setAttribute('class', 'price-text') price_text.innerText = records.fields.titre const div_lower_info = document.createElement('div') div_lower_info.setAttribute('class', 'div-lower-info w-clearfix') const info_text = document.createElement('div') info_text.setAttribute('class', 'info-text') info_text.innerText = records.fields.compagny_name + ' - ' + records.fields.description_sub.substring(0, 100) + '...' const view_button = document.createElement('div') view_button.setAttribute('class', 'view-button') view_button.textContent = 'Plus' property_card.appendChild(image_quantity_div); property_card.appendChild(price_text); div_lower_info.appendChild(info_text); div_lower_info.appendChild(view_button); property_card.appendChild(div_lower_info); card.appendChild(property_card); }) // 只有存在下一页offset时才渲染下一页按钮 if(data.offset) { const offset_page = document.createElement('a'); offset_page.setAttribute('class', 'button-2 left-aligned w-button') offset_page.setAttribute('id', 'next') offset_page.setAttribute('href', 'javascript:;') offset_page.innerHTML = "Page Suivante" // 绑定下一页点击事件 offset_page.addEventListener('click', function(e) { e.preventDefault() offset = data.offset catchJson() }) card.appendChild(offset_page); } } else { const errorMessage = document.createElement('a') errorMessage.textContent = `Bah, ça ne marche pas !` app.appendChild(errorMessage) } } document.addEventListener('DOMContentLoaded', function () { catchJson() });
HTML代码(无需修改)
<div class="premium-properties-div" id="root"> </div>
内容的提问来源于stack exchange,提问作者Kazero G
相关产品推荐
相关产品推荐

