$(this) 未在 jQuery UI 对话框“打开”选项中设置

问题描述 投票:0回答:1

文字游戏的底部有 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 对话框“打开”选项需要一个

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()
在我的关闭中无效。

有办法让它发挥作用吗?

javascript jquery jquery-ui closures jquery-ui-dialog
1个回答
0
投票

这非常粗糙,但在这里我创建了一个名为

filterWords
的 UI 小部件方法,并将其添加到
ui.dialog
,然后展示了如何使用按钮调用它。

或者,我添加了一个在对话框打开时调用的方法。

备注:

  • dialog
    filterWords
    也会触发打开
  • 注释掉了这个演示的大部分代码,因为我没有
    HASHED
    可用。
  • 如果您想朝那个方向添加一个开放处理程序
  • 注意小部件代码如何使用
    this.element
  • 小部件文档:https://jqueryui.com/widget/

$.widget("ui.dialog", $.ui.dialog, {
  filterWords: function(event) {
    console.log('we are here!');
    //console.log(this.element);
    let myWords = this.element.find('.words');
    console.log('words:', myWords.length, myWords.html());
    $(this).trigger('open');

    /*
           // the words already filtered and assigned to the dialog's innerHTML
    if ($(this).find('.words').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');
    };
     */
  }
});


function filterWordsRaw(event, ui) {
  console.log('in RAW form');
  // the words already filtered and assigned to the dialog's innerHTML
  if ($(this).html().length > 1000) {
    return (ev, ui) => {};
  }
/* commented out as I do not have HASHED defined 
  // 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');
  };
  */
}

/* just to show we did this */
function handleOpen(event) {
  console.log('opened');
  console.log(event.target === this);
}

$(".selector").dialog({
  modal: true,
  appendTo: '#fullDiv',
  autoOpen: false,
  open: handleOpen,
  buttons: {
    'Close': function() {
      $(this).dialog('close');
    }
  }
});

$(".selector").on("dialogopen", filterWordsRaw);

$('.go-do-it').on('click', function(event) {
  console.log('hi');
  $(".selector").dialog("filterWords");
});
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/redmond/jquery-ui.css">
<div class="container">
  <button type="button" class="go-do-it">Click</button>
</div>

<div class="selector" title="Dialog Title">
  <span class="words">one fish two fish red fish blue fish</span>
</div>
<div id="fullDiv"></div>

© www.soinside.com 2019 - 2024. All rights reserved.