我写了一些代码来生成一堆基于 Json 对象的 html 元素。我通过 JQuerys .append()
和 .after()
将它添加到页面。
它确实经常完美地工作,但有时外循环只执行一次并在 $( '#'+inputname ).entityselector()
处停止。
function addlinks(qid, prop) {
html="<fieldset id=\"quickpresets\">" +
"<legend>Quick Presets (" + prop.name + ")</legend></fieldset>";
$('.wikibase-statementgrouplistview').first().after( html );
for( var p = 0; p < prop.defaults.length; p++ ) {
pid=prop.defaults[p].pid;
pname=prop.defaults[p].name;
pvalues=prop.defaults[p].values;
inputname="input"+pname;
pclass="addstatement";
if($('#P'+pid).find(".wikibase-snakview-value a").length !== 0) {
pclass += " disabled";
}
str="<p class='"+pclass+"'>Add "+pname+":";
for( var i = 0; i < pvalues.length; i++) {
toqid=pvalues[i].qid;
toname=pvalues[i].name;
str += " <a href='javascript:void(0);' onclick=\""+
"additemstatement("+qid+","+pid+",'"+pname+"',"+ toqid +",'" + toname+ "')\">" + toname+ "</a>"+
" ∙";
}
str += "<span class=\"quickpresetsinput\"><input id='"+inputname+"'/> ";
str += "<a href=\'javascript:void(0);\' onclick=\""+
"onselectitem("+qid+","+pid+",'"+pname+"','"+ inputname +"')\">✔</a>";
str += "</span></p>";
$('#quickpresets').append( str );
input = $( '#'+inputname ).entityselector( {
url: 'https://www.wikidata.org/w/api.php',
language: mw.config.get('wgUserLanguage')
} );
}
}
我该如何解决这个问题?我还应该做些什么来改进这个丑陋的代码?
更新:
- 我在控制台中收到以下错误:
TypeError: $(...).entityselector is not a function [Weitere Informationen]
- full code可以在这里找到。
- 我必须使用 ES5。
- 数据始终是相同的(“硬编码”)JSON。
- 请参阅下面的 Roamer-1888 的可读性更好的版本——它仍然会导致相同的错误。
最佳答案
为什么 .entityselector()
应该在某些情况下抛出,在代码中并不明显。最可能的原因是您试图在加载插件之前调用它。
在尝试解决此问题时,您可以尝试一次性初始化所有输入,而不是在循环中单独初始化。
此外,通过将一个相当简单的片段附加到 DOM,然后立即添加链接并使用 jQuery 附加事件处理程序,可以使代码更具可读性。
这就是我的写法(经过大量整理):
function addlinks(qid, prop) {
// compose and intert fieldset.
var $fieldset = $("<fieldset><legend>Quick Presets (" + prop.name + ")</legend></fieldset>")
.insertAfter($('.wikibase-statementgrouplistview').first());
// loop through prop.defaults
prop.defaults.forEach(function(dflt) {
// compose and append a basic fragment ...
var $fragment = $("<p class='addstatement'>Add " + dflt.pname + ":<span class=\"links\"></span>"
+ "<span class=\"quickpresetsinput\"><input /> <a href=\"#\">✔</a></span></p>")
.appendTo($fieldset);
// ... then allow jQuery to augment the appended fragment :
// i) conditionally addClass('disabled')
if($('#P' + dflt.pid).find(".wikibase-snakview-value a").length !== 0) {
$fragment.addClass('disabled');
}
// ii) loop through dflt.values and add links.
dflt.values.forEach(function(val) {
$("<span> <a href=\"#\"></a> ∙</span>")
.appendTo($fragment.find('span.links'))
.find('a')
.text(val.name)
.on('click', function(e) {
e.preventDefault();
additemstatement(qid, dflt.pid, dflt.pname, val.qid, val.name);
});
});
// iii) attach click handlers to the quickpresets inputs
$fragment.find('.quickpresetsinput').find('a').on('click', function(e) {
e.preventDefault();
var selection = $(this).prev('input').data('entityselector').selectedEntity();
additemstatement(qid, dflt.pid, dflt.pname, selection.id.substring(1), selection.label);
});
});
// invoke .entityselector() on all the quickpresets inputs in one hit
$('.quickpresetsinput input').entityselector({
'url': 'https://www.wikidata.org/w/api.php',
'language': mw.config.get('wgUserLanguage')
});
}
除语法外未经测试
尽管没有对原始问题的正确理解,这肯定更简洁,.entityselector()
可能仍然会抛出错误。
关于javascript - 添加和使用带有 jquery 的 html 仅有时有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47985370/