我正在尝试为画廊编写基于JavaScript的分页,该画廊通过来自服务器的onClick
事件加载HTML。只需通过innerHtml
附加HTML。唯一的困难是我需要用缩略图URL填充数组以进行预览。数据通过与HTML相同的HTTP请求提供。
我试图通过<script>
标签将其添加到HTML,但是当通过innerHtml
插入时,这些标签不会执行(请参见here)。
约束:
可能的解决方案
由于我对JavaScript的了解有限,所以我只看到2个解决方案,但似乎没有一个对的。
innerHTML
附加HTML,并且可以将数组数据传递给函数。<script>
元素中,并通过一些晦涩的JS技巧来提取其内容。但是我敢肯定,我会为此受到殴打。任何建议都值得赞赏。
可能与谁有关的一些代码:
function loadNextPage(uri) {
var xhr = new XMLHttpRequest();
xhr.open('GET', uri);
xhr.onload = function() {
if (xhr.status === 200) {
var loadNextButton = document.getElementById("load-next-button");
loadNextButton.parentNode.removeChild(loadNextButton);
var vbw = document.getElementById("vbw");
vbw.innerHTML = vbw.innerHTML + xhr.response;
} else {
conosole.log('Failed: ' + xhr.status);
}
};
xhr.send();
}
<div id="vbw">
<script type="application/javascript">
let thumbNailStore = {
concat: function() {
console.log('Concat has been ran');
},
};
function addThumbnailListeners() {
console.log('addThumbnailListeners has been ran');
}
thumbNailStore.concat(); // This produces a JSON which is appended to an array in the <head> of the page
addThumbnailListeners();
</script>
<button id="load-next-button" onclick="loadNextPage('10')">Load more</button>
</div>
和模板:
@standardtemplate.commons.gallery(videoList, LandingPage.empty()) // That produces the actual gallery HTML
@if(pagination.getNextPath.isPresent) {
<script type="application/javascript">
thumbNailStore.concat(@Html(TemplateHelper.thumbListToJson(videoList))); // This produces a JSON which is appended to an array in the <head> of the page
addThumbnailListeners();
</script>
<button id="load-next-button" onclick="loadNextPage('@pagination.getNextPath.get()')">Load more</button>
}
谢谢!
答案 0 :(得分:1)
如果使用jQuery,load()
将执行加载的内容中包含的所有脚本元素,并修改内部HTML,这听起来像您所需要的。
否则,您可以使用eval。您只需要某种方法来检索脚本元素(也许是vbw
的最后一个脚本元素子级,可以是某个预定的id,甚至可以是从响应数据中创建一个元素并从那里访问脚本subElement)。无论哪种方式,一旦有了脚本元素对象:
eval(scriptElement.innterHtml);
答案 1 :(得分:1)
您的解决方案几乎是正确的,我将vbw.innerHTML = vbw.innerHTML + xhr.response;
替换为.appendChild()
方法。但我也注意到您要添加倍数<script type="application/javascript">...</script>
。因此,我认为如果您两次按下按钮 Load More (加载更多),最终将在代码中添加3个<script>
标签。
好吧,首先提取内联脚本inlineScript
并将其附加到当前脚本中。然后,使用DOMParser().parseFromString()
方法创建一个新文档。这将解析您的xhr.response
,然后获取<button>
元素,最后将其附加到您的<div>
。
这里是一个例子:
let matches, clickCount = 0;
const regexScript = /<script[\s\S]*?>([\s\S]*?)<\/script>/gi;
const regexButton = /<button[\s\S]*?>[\s\S]*?<\/button>/gi;
let nodeCounter = document.getElementById('counter');
function getResponse() {
// To simulate response from your server
return `<script type="application/javascript">let thumbNailStore={concat:function(){console.log('Concat for videolist ${clickCount} ')}};function addThumbnailListeners(){console.log('addThumbnailListeners called ${clickCount}')}thumbNailStore.concat(),addThumbnailListeners();</script><button id="load-next-button" onclick="loadNextPage('https://jsonplaceholder.typicode.com/users/1')">Load more</button>`;
}
function htmlDecode(input) {
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes[0].nodeValue;;
}
function loadNextPage(uri) {
let xhr = new XMLHttpRequest();
xhr.open('GET', uri);
xhr.onload = function() {
if (xhr.status === 200) {
// Im' using responseTest you should use xhr.response
let rawdata = htmlDecode(getResponse());
clickCount++
// Script matches
matches = Array.from(rawdata.matchAll(regexScript));
let rawScript = matches[0][1];
let inlineScript = document.createTextNode(rawScript);
// Button matches
matches = Array.from(rawdata.matchAll(regexButton));
let rawButton = matches[0];
let script = document.getElementById('loaded-script');
script.innerHTML = '';
script.appendChild(inlineScript);
let loadNextButton = document.getElementById('load-next-button');
loadNextButton.parentNode.removeChild(loadNextButton);
let vbw = document.getElementById('vbw');
let doc = new DOMParser().parseFromString(rawButton, 'text/html');
//let script = doc.body.childNodes;
let button = doc.getElementById('load-next-button');
// vbw.innerHTML = vbw.innerHTML + xhr.response;
vbw.appendChild(button);
nodeCounter.innerHTML = 'Request processed: ' + clickCount;
eval(script.innerHTML);
} else {
conosole.log('Failed: ' + xhr.status);
}
};
xhr.send();
}
<div id="vbw">
<script id="loaded-script" type="application/javascript">
let thumbNailStore = {
concat: function() {
console.log('Concat original');
},
};
function addThumbnailListeners() {
console.log('addThumbnailListeners');
}
thumbNailStore.concat(); // This produces a JSON which is appended to an array in the <head> of the page
addThumbnailListeners();
</script>
<button id="load-next-button" onclick="loadNextPage('https://jsonplaceholder.typicode.com/users/1')">Load more</button>
</div>
<div id="counter"></div>