在文字游戏的底部有4个按钮,用于打开jQuery UI对话框,其中包含游戏字典中的某些单词:
我试图通过创建以下函数来简化游戏代码:
// select word using the filterFunc and then concat them all to a string
function filterWords(filterFunc) {
// the words already filtered and assigned to the dialog's innerHTML
if ($(this).html().length > 1000) {
return (ev, ui) => {};
}
// filter the keys of HASHED dictionary by calling the filterFunc on each
const filtered = Object.keys(HASHED)
.filter(word => filterFunc(word))
.reduce((result, word) => {
return result +
'<p><span class="tile">' + word + '</span> ' + HASHED[word] + '</p>'
}, '');
// return the closure expected by the dialog's "open" option
return (ev, ui) => {
$(this).html(filtered);
const title = $(this).dialog('option', 'title');
console.log(title + ': ' + filtered.length + ' chars');
};
}
我希望jQuery UI对话框“open”选项需要一个function (ev, ui) {}
,这就是我试图通过我的新函数给予的:
const twoDlg = $('#twoDlg').dialog({
modal: true,
appendTo: '#fullDiv',
autoOpen: false,
open: filterWords(word => word.length == 2),
buttons: {
'Close': function() {
$(this).dialog('close');
}
}
});
下面是另一个对话框:
const rare2Dlg = $('#rare2Dlg').dialog({
modal: true,
appendTo: '#fullDiv',
autoOpen: false,
open: filterWords(word => word.indexOf('X') >= 0),
buttons: {
'Close': function() {
$(this).dialog('close');
}
}
});
不幸的是,现在我得到了错误消息:
jquery.js:4095 Uncaught TypeError: Cannot read properties of undefined (reading 'length')
at filterWords (test?player=abcde:833:594)
at HTMLDocument.<anonymous> (test?player=abcde:835:139)
at mightThrow (jquery.js:3802:29)
at process (jquery.js:3870:12)
这表明$(this).html()
在我的闭包中是无效的。
有办法让它工作吗?
更新:
我已经准备了一个jsFiddle与3个对话框和3个按钮打开。方法filterWordsWorks()
可以工作,但是有太多的重复代码。注解掉的方法open: filterWordsBroken(word => word.length == 2),
失败。
下面是同样的演示代码,内联到Stackoverflow:
'use strict';
const HASHED = {
"one": "Word description 1",
"two": "Word description 2",
"three": "Word description 3",
"four": "Word description 4",
"five": "Word description 5",
"six": "Word description 6",
"seven": "Word description 7"
};
// select word using the filterFunc and then concat them all to a string
function filterWordsBroken(filterFunc) {
// the words already filtered and assigned to the dialog's innerHTML
if ($(this).html().length > 1000) {
return (ev, ui) => {};
}
// filter the keys of HASHED dictionary by calling the filterFunc on each
const filtered = Object.keys(HASHED)
.filter(word => filterFunc(word))
.reduce((result, word) => {
return result +
'<p>' + word + ': ' + HASHED[word] + '</p>'
}, '');
// return the closure expected by the dialog's "open" option
return (ev, ui) => {
$(this).html(filtered);
const title = $(this).dialog('option', 'title');
console.log(title + ': ' + filtered.length + ' chars');
};
}
// select word using the filterFunc and then concat them all to a string
function filterWordsWorks(filterFunc) {
return Object.keys(HASHED)
.filter(word => filterFunc(word))
.reduce((result, word) => {
return result +
'<p>' + word + ': ' + HASHED[word] + '</p>'
}, '');
}
jQuery(document).ready(function($) {
const twoDlg = $('#twoDlg').dialog({
modal: true,
autoOpen: false,
//open: filterWordsBroken(word => word.length == 2),
open: function(ev, ui) {
// prevent this code from running twice
if ($(this).html().length < 1000) {
const filtered = filterWordsWorks(word => word.length == 2);
$(this).html(filtered);
const title = $(this).dialog('option', 'title');
console.log(title + ': ' + filtered.length);
}
}
});
const threeDlg = $('#threeDlg').dialog({
modal: true,
autoOpen: false,
//open: filterWordsBroken(word => word.length == 3),
open: function(ev, ui) {
// prevent this code from running twice
if ($(this).html().length < 1000) {
const filtered = filterWordsWorks(word => word.length == 3);
$(this).html(filtered);
const title = $(this).dialog('option', 'title');
console.log(title + ': ' + filtered.length);
}
}
});
const fourDlg = $('#fourDlg').dialog({
modal: true,
autoOpen: false,
//open: filterWordsBroken(word => word.length == 3),
open: function(ev, ui) {
// prevent this code from running twice
if ($(this).html().length < 1000) {
const filtered = filterWordsWorks(word => word.length == 4);
$(this).html(filtered);
const title = $(this).dialog('option', 'title');
console.log(title + ': ' + filtered.length);
}
}
});
$('#twoBtn').button().click(function(ev) {
ev.preventDefault();
twoDlg.dialog('open');
});
$('#threeBtn').button().click(function(ev) {
ev.preventDefault();
threeDlg.dialog('open');
});
$('#fourBtn').button().click(function(ev) {
ev.preventDefault();
fourDlg.dialog('open');
});
});
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-ui@1/dist/themes/redmond/jquery-ui.min.css">
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-ui@1/dist/jquery-ui.min.js"></script>
<!-- beware: the twoDlg will be empty -->
<DIV ID="twoDlg" TITLE="2 letters"></DIV>
<DIV ID="threeDlg" TITLE="3 letters"></DIV>
<DIV ID="fourDlg" TITLE="4 letters"></DIV>
<BUTTON ID="twoBtn">2 letters</BUTTON>
<BUTTON ID="threeBtn">3 letters</BUTTON>
<BUTTON ID="fourBtn">4 letters</BUTTON>
2条答案
按热度按时间uelo1irk1#
你想用多少就用多少。
这不是对这个问题的直接回答,而是一个x/y的例子,说明你的目标是什么:更少的代码
既然你指出你的愿望是更少的代码,这里有一个更简单的例子。
wordLength: 3,
preventDefault
,而是在元素上使用type="button"
$('.my-letter-dialog') .on("dialogopen"
和.dialog(
- order很重要,因为.dialog(
不返回jQuery,但事件处理程序会返回。你可以从一个对话框创建一个对话框-添加了一个“5”字母的例子,但它可以是所有的。
a6b3iqyw2#
这是相当粗略的,但在这里我创建了一个名为
filterWords
的UI小部件方法,并将其添加到ui.dialog
中,然后展示了如何使用按钮调用它。另外,我添加了一个在对话框打开时调用的方法。
备注:
filterWords
也会触发打开HASHED
。this.element
$(this)
可用,如我在RAW函数中使用html的$(this).find('.words')
元素日志所示wordcount:2,
可能还有其他方法可以使其更有效,但这里我只是在这里展示了很多可用的选项。