我写了一些代码,基于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')
} );
}
}
如何解决此问题?还有什么我应该做的来改进这个难看的代码呢?
更新:
控制台中出现以下错误:
类型错误:$(…)。entityselector不是函数[Weitere
信息en]
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()
仍然可能抛出。