查询SharePoint列表后,JS生成的letterButtons仅显示首个元素问题
看起来你遇到了一个典型的DOM操作隐性问题——虽然控制台显示letterButtons的innerHTML内容完整,但实际DOM中只有第一个字母按钮被渲染。这大概率是因为循环中反复使用innerHTML +=导致的浏览器渲染异常,尤其是在SharePoint这种有复杂页面环境的场景下。
问题根源分析
每次执行innerHTML +=时,浏览器都会重新解析整个元素的HTML内容并重新渲染,这种反复的操作在SharePoint的页面上下文(比如母版页脚本、控件冲突)中可能会导致DOM更新不完整,虽然最终的innerHTML字符串是正确的,但实际渲染时只有第一个元素被保留下来。你尝试过拼接字符串一次性赋值但没显示,可能是拼接过程中存在隐性的格式问题,或者赋值时机不对。
修复方案1:使用DOM元素创建(推荐,更稳定)
直接通过createElement创建节点并追加到容器中,避免innerHTML的解析问题,这是更可靠的DOM操作方式:
QueryList( '/sites/SKCopspcs/testing/', 'QAVGlossary', 1, 1000, function( sender, args ){ var foundItems = queryItems.getEnumerator(); var letterButtons = document.getElementById( 'letterButtons' ); var letterContainers = document.getElementById( 'letterContainers' ); var _all = ""; // 用对象记录已处理的字母,比字符串includes更高效 var processedLetters = {}; while( foundItems.moveNext() ) { var found = foundItems.get_current(); var title = found.get_item( 'Title' ) + ''; var definition = found.get_item( 'n5ud' ) + ''; var letter = found.get_item( 'Category' ) ; if( !processedLetters[letter] ) { processedLetters[letter] = true; letters.push( letter ); // 创建字母按钮节点 var letterSpan = document.createElement('span'); letterSpan.className = 'bioTitle'; letterSpan.id = `${letter}Span`; letterSpan.textContent = letter; letterSpan.onclick = () => Show(this); letterButtons.appendChild(letterSpan); // 创建字母容器节点 var letterDiv = document.createElement('div'); letterDiv.className = 'FXmasonry bio'; letterDiv.id = letter; letterContainers.appendChild(letterDiv); } // 添加内容到对应字母容器 document.getElementById(letter).innerHTML += `<div class="FXmasonryItem"><span class="titleB">${title}</span><br>${definition}</div>`; _all += `<div class="FXmasonryItem"><span class="titleB">${title}</span><br>${definition}</div>`; } // 添加"All"按钮 var allSpan = document.createElement('span'); allSpan.className = 'bioTitle'; allSpan.id = 'AllSpan'; allSpan.textContent = 'All'; allSpan.onclick = () => Show(this); letterButtons.appendChild(allSpan); // 添加"All"容器 var allDiv = document.createElement('div'); allDiv.className = 'FXmasonry bio'; allDiv.id = 'All'; allDiv.innerHTML = _all; letterContainers.appendChild(allDiv); console.log( letterButtons.innerHTML ); }, function( s, a ){ alert( 'Could not query list \"QAVGlossary\"' ); });
修复方案2:修正字符串拼接一次性赋值
如果你更倾向于使用innerHTML,确保先完整拼接所有按钮的HTML字符串,再一次性赋值给容器,避免反复修改innerHTML:
QueryList( '/sites/SKCopspcs/testing/', 'QAVGlossary', 1, 1000, function( sender, args ){ var foundItems = queryItems.getEnumerator(); var letterButtons = document.getElementById( 'letterButtons' ); var letterContainers = document.getElementById( 'letterContainers' ); var _all = ""; var letterButtonsHTML = ''; var processedLetters = {}; while( foundItems.moveNext() ) { var found = foundItems.get_current(); var title = found.get_item( 'Title' ) + ''; var definition = found.get_item( 'n5ud' ) + ''; var letter = found.get_item( 'Category' ) ; if( !processedLetters[letter] ) { processedLetters[letter] = true; letters.push( letter ); // 拼接按钮HTML letterButtonsHTML += `<span class="bioTitle" id="${letter}Span" onclick="Show(this)">${letter}</span>`; // 添加字母容器 letterContainers.innerHTML += `<div class="FXmasonry bio" id="${letter}"></div>`; } document.getElementById(letter).innerHTML += `<div class="FXmasonryItem"><span class="titleB">${title}</span><br>${definition}</div>`; _all += `<div class="FXmasonryItem"><span class="titleB">${title}</span><br>${definition}</div>`; } // 追加"All"按钮并一次性赋值 letterButtonsHTML += `<span class="bioTitle" id="AllSpan" onclick="Show(this)">All</span>`; letterButtons.innerHTML = letterButtonsHTML; // 添加"All"容器 letterContainers.innerHTML += `<div class="FXmasonry bio" id="All"></div>`; document.getElementById('All').innerHTML = _all; console.log( letterButtons.innerHTML ); }, function( s, a ){ alert( 'Could not query list \"QAVGlossary\"' ); });
额外优化建议
- 使用
processedLetters对象来记录已处理的字母,比字符串includes方法的性能更高,尤其是当列表数据较多时。 - 模板字符串(
`)比普通字符串拼接更易读,也减少了引号转义的问题。
内容的提问来源于stack exchange,提问作者Fuczi Fuczi
相关产品推荐
相关产品推荐

