【问题标题】:jQuery UI Sortable Refresh Error - How to Refresh Dynamically Added Sortable Elements?jQuery UI 可排序刷新错误 - 如何刷新动态添加的可排序元素?
【发布时间】:2021-12-13 01:57:29
【问题描述】:

在 gif 中

  1. 页面加载初始化我的可排序代码(如下)
  2. 添加部分按钮(与本题无关)
  3. 向该部分添加课程(动态,页面加载时元素不存在,重要!
  4. 该课程不可排序,因为它是动态创建的
  5. 在控制台中,我冗余地粘贴了整个可排序初始化程序
  6. 课程变得可排序(根据需要)

我的问题:

创建动态元素后,如何正确“刷新”或为新元素提供已初始化的可排序项所具有的所有属性和事件(选项?)。

我的 GIF 的最简单的 HTML 伪代码:

<div>
  <ul class="sortable-sections">
    <li class="section">
      <ul class="sortable-lessons">
        <li>Item 1</li>
      </ul>
    </li>
  </ul>
</div>

有没有办法说(使用 jQuery),“任何在页面加载时加载或使用 sortable-lessons 类动态创建的项目都是可排序项目”。?

我的可排序代码:

$('.sortable-lessons').sortable({
        connectWith: ".sortable-lessons",
        placeholder: 'placeholder',
        items: "li:not(.unsortable)",
        forcePlaceholderSize: true,
        start: function( event, ui ) {
            $(ui.item).addClass("yellow");
        },
        stop: function(event, ui) {
            $(ui.item).removeClass("yellow");
        }
    });

我的努力:

我想也许在我的函数添加新课程之后,我可以调用:

$( ".sortable-lessons" ).sortable( "refresh" );

但这会引发错误,我不知道为什么。

错误:

jquery.min.js:2 Uncaught Error: cannot call methods on sortable prior to initialization;
  attempted to call method 'refresh'
    at Function.error (jquery.min.js:2)
    at HTMLUListElement.<anonymous> (jquery-ui.min.js:6)
    at Function.each (jquery.min.js:2)
    at S.fn.init.each (jquery.min.js:2)
    at S.fn.init.t.fn.<computed> [as sortable] (jquery-ui.min.js:6)
    at <anonymous>:1:26

从字面上看,documentation on refresh 似乎表明这正是 ("refresh") 方法的用途:

刷新()

刷新可排序的项目。触发所有可排序的重新加载 项目,导致新项目被识别。此方法不接受 任何论据。代码示例:调用刷新方法:

$( ".selector" ).sortable( "refresh" );

我发现的一个简单愚蠢的解决方案 (Refresh list after adding an item with jQuery UI sortable plugin) 提到再次执行整个可排序初始化程序。 这肯定是错误的做法。我想以正确的方式做到这一点。

Others call destroy 在原版上,然后再次重建。同样,这似乎不是正确的方法。

编辑/更新可重现示例

let sectionId = 1;
let lessonId = 1;

$('.sortable-sections').sortable();
$('.sortable-lessons').sortable({
  connectWith: ".sortable-lessons",
  items: "li",
});

function addSection(id) {
  const item = '' +
    '<li class="section" id="' + id + '">' +
      '<span>section ' + id + ' <button class="add-lesson">Add lesson</button></span>' +
      '<ul class="sortable-lessons"></ul>' +
    '</li>';
  $('.sortable-sections').append(item);
}

$('body').on('click', '#add-section', function () {
  addSection(sectionId);
  sectionId+=1;
});

function addLesson(sectionId, lessonId) {
  const section = $('#' + sectionId);
  const item = '<li class="lesson"><div class="border">lesson ' + lessonId + '</div></li>';
  section.find('ul.sortable-lessons').append(item);
  $('.sortable-lessons').sortable('refresh');
}

$('body').on('click', '.add-lesson', function () {
  const section_id = $(this).closest('.section').attr('id');
  addLesson(section_id, lessonId);
  lessonId+=1;
});
.border {
  border: 1px solid black;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <div>
    <button id="add-section">Add Section</button>
    <ul class="sortable-sections">
    </ul>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
</body>
</html>

但是当没有任何部分或课程存在时,该示例是从头开始的。

这是一个存在某些部分和课程的示例。

  1. 添加新部分
  2. 尝试在该部分添加新课程

let sectionId = 7;
let lessonId = 12;

$('.sortable-sections').sortable();
$('.sortable-lessons').sortable({
  connectWith: ".sortable-lessons",
  items: "li",
});

function initializeSortableLessons() {
  $('.sortable-lessons').sortable({
    connectWith: ".sortable-lessons",
    items: "li",
  });
}


function addSection(id) {
  const item = '' +
    '<li class="section" id="' + id + '">' +
      '<span>section ' + id + ' <button class="add-lesson">Add lesson</button></span>' +
      '<ul class="sortable-lessons"></ul>' +
    '</li>';
  $('.sortable-sections').append(item);
}

$('body').on('click', '#add-section', function () {
  addSection(sectionId);
  sectionId+=1;
});

function addLesson(sectionId, lessonId) {
  const section = $('#' + sectionId);
  const item = '<li class="lesson"><div style="border: 1px solid black;">lesson ' + lessonId + '</div></li>';
  section.find('ul.sortable-lessons').append(item);
  $('.sortable-lessons').sortable('refresh');
}

$('body').on('click', '.add-lesson', function () {
  const section_id = $(this).closest('.section').attr('id');
  addLesson(section_id, lessonId);
  lessonId+=1;
});
.border {
        border: 1px solid black;
    }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

  <div>
    <button id="add-section">Add Section</button>
    <ul class="sortable-sections ui-sortable">
      <li class="section" id="1"><span>section 1 <button class="add-lesson">Add lesson</button></span><ul class="sortable-lessons"></ul></li><li class="section" id="2"><span>section 2 <button class="add-lesson">Add lesson</button></span><ul class="sortable-lessons"><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li></ul></li><li class="section" id="3"><span>section 3 <button class="add-lesson">Add lesson</button></span><ul class="sortable-lessons"></ul></li><li class="section" id="4"><span>section 4 <button class="add-lesson">Add lesson</button></span><ul class="sortable-lessons"><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li></ul></li><li class="section" id="5" style=""><span>section 5 <button class="add-lesson">Add lesson</button></span><ul class="sortable-lessons"><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li></ul></li><li class="section" id="6" style=""><span>section 6 <button class="add-lesson">Add lesson</button></span><ul class="sortable-lessons"><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li><li class="lesson"><div style="border: 1px solid black;">lesson 1</div></li></ul></li></ul>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
</body>
</html>

【问题讨论】:

  • 您需要在添加新项目后运行refresh。该错误表明您在第一次初始化 Sortable 之前运行它。
  • 您发布的示例并未指明您在哪里运行refresh。您能否提供一个最小的、可重现的示例:stackoverflow.com/help/minimal-reproducible-example
  • @Twisty 我用一个可重现的示例更新了我的问题,该示例引发了我正在谈论的错误。

标签: jquery jquery-ui jquery-ui-sortable


【解决方案1】:

考虑以下问题。您必须将新的&lt;ul&gt; 初始化为可排序的。这样,当您添加 &lt;li&gt; 并调用 refresh 时,它已经被初始化为一个 Sortable。

$(function() {

  function addLesson(event) {
    var section = $(this).closest("li");
    var item = $("<li>", {
      class: "lesson"
    });
    $("<div>").css("border", "1px solid black").html("Lesson " + ($(".lesson").length + 1)).appendTo(item);
    $('ul.sortable-lessons', section).append(item).sortable('refresh');
  }

  function addSection(props, target) {
    var item = $("<li>", props);
    $("<span>").html("Section " + props.id + " ").appendTo(item);
    $("<button>", {
      class: "add-lesson"
    }).html("Add Lesson").appendTo($("span", item));
    $("<ul>", {
      class: "sortable-lessons"
    }).appendTo(item).sortable({
      connectWith: ".sortable-lessons"
    });
    if (target === undefined) {
      item.appendTo($(".sortable-sections"));
      $(".sortable-sections").sortable("refresh");
    } else {
      item.appendTo(target);
      if ($(target).hasClass("ui-sortable")) {
        $(target).sortable("refresh");
      }
    }
  }

  $('.sortable-sections').sortable();
  $('.sortable-lessons').sortable({
    connectWith: ".sortable-lessons"
  });

  $('body').on('click', '#add-section', function() {
    addSection({
      id: $(".section").length + 1
    });
  });

  $('body').on('click', '.add-lesson', addLesson);
});
.border {
  border: 1px solid black;
}
<div>
  <button id="add-section">Add Section</button>
  <ul class="sortable-sections ui-sortable">
    <li class="section" id="1"><span>section 1 <button class="add-lesson">Add lesson</button></span>
      <ul class="sortable-lessons"></ul>
    </li>
    <li class="section" id="2"><span>section 2 <button class="add-lesson">Add lesson</button></span>
      <ul class="sortable-lessons">
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
      </ul>
    </li>
    <li class="section" id="3"><span>section 3 <button class="add-lesson">Add lesson</button></span>
      <ul class="sortable-lessons"></ul>
    </li>
    <li class="section" id="4"><span>section 4 <button class="add-lesson">Add lesson</button></span>
      <ul class="sortable-lessons">
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
      </ul>
    </li>
    <li class="section" id="5" style=""><span>section 5 <button class="add-lesson">Add lesson</button></span>
      <ul class="sortable-lessons">
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
      </ul>
    </li>
    <li class="section" id="6" style=""><span>section 6 <button class="add-lesson">Add lesson</button></span>
      <ul class="sortable-lessons">
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
        <li class="lesson">
          <div style="border: 1px solid black;">lesson 1</div>
        </li>
      </ul>
    </li>
  </ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

【讨论】:

    猜你喜欢
    • 2011-01-12
    • 2019-06-27
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多