JavaScript 根据名称对 DOM 元素进行排序

发布于 2024-11-08 01:47:50 字数 995 浏览 0 评论 0原文

所以我有一个隐藏字段的列表:

<ul class="reorderable">
    <li>Foo<input class="hiddenThing" type=hidden name="thing[0]" value=foo /></li>
    <li>Bar<input class="hiddenThing" type=hidden name="thing[1]" value=bar /></li>
    <li>Baz<input class="hiddenThing" type=hidden name="thing[2]" value=baz /></li>
</ul>

纯粹是信息性的,我不希望这与答案相关,但仅供参考,我正在使用 JQuery UI“可排序”插件:

<script type="text/javascript">
$(document).ready(function () {
    $('ul.reorderable').sortable({ update: stuffHappens; });
}
</script>

您需要从中了解的是可排序插件允许用户任意重新排序这些元素。现在,我想做的是实现一个恢复按钮。

<button value="Revert" onClick="revertList()" />

我希望它根据隐藏输入的名称将列表元素按顺序放回。我想这将需要正则表达式(从名称中的括号中提取数字。 thing[10] 应该在 thing[9] 之后),我想 JQuery 会得心应手。但当我尝试解决这个问题时,我却一片空白,可能是因为我不熟悉对 DOM 元素进行排序,也不熟悉使用 JavaScript 进行正则化。

必须保留这种命名格式。

So I've got a list of hidden fields:

<ul class="reorderable">
    <li>Foo<input class="hiddenThing" type=hidden name="thing[0]" value=foo /></li>
    <li>Bar<input class="hiddenThing" type=hidden name="thing[1]" value=bar /></li>
    <li>Baz<input class="hiddenThing" type=hidden name="thing[2]" value=baz /></li>
</ul>

Purely informational, I don't expect this to be related to the answer, but FYI I'm using the JQuery UI "sortable" plugin:

<script type="text/javascript">
$(document).ready(function () {
    $('ul.reorderable').sortable({ update: stuffHappens; });
}
</script>

The thing you need to understand from this is that the sortable plugin allows the user to reorder these elements arbitrarily. Now, what I want to do is implement a revert button.

<button value="Revert" onClick="revertList()" />

I want this to put the elements of the list back in order based on the name of the hidden inputs. I imagine this will require regexes (to extract the number from the brackets in the name. thing[10] should come after thing[9]) and I imagine that JQuery will be handy. But I'm drawing a blank when I try to approach this problem, probably because I'm not familiar with sorting DOM elements nor regexing with JavaScript.

Keeping this naming format is a must.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沉睡月亮 2024-11-15 01:47:50
function revertList() {
    var $ul = $('ul.reorderable'),
        $inps = $ul.find('li').find('input.hiddenThing');

    for (var i = 0, il = $inps.length; i < il; i++) {
        $inps.filter('[name="thing['+i+']"]').closest('li')
             .detach().appendTo($ul);
    }
}

演示→

function revertList() {
    var $ul = $('ul.reorderable'),
        $inps = $ul.find('li').find('input.hiddenThing');

    for (var i = 0, il = $inps.length; i < il; i++) {
        $inps.filter('[name="thing['+i+']"]').closest('li')
             .detach().appendTo($ul);
    }
}

Demo →

掀纱窥君容 2024-11-15 01:47:50

我可能会使用标准数组排序,然后删除所有项目并将它们添加回排序:

$('#reorder').click(function() {
    // get the list items and store references to them,
    // grabbing their names on the way
    var items = [];
    $('ul.reorderable li').each(function() {
        var name = $('input', this).attr('name'),
            // regex is overkill if you're always using the same format
            // this is quick, but a little hacky - parseInt stops
            // at non-numeric characters
            pos = parseInt(name.split("[")[1]);
        items.push({
            item: this, // store a reference to the DOM element
            pos: pos 
        });
    });
    // now sort by name
    items.sort(function(a,b) {
        return a.pos > b.pos ? 1 : -1;
    });
    // delete the items and add them back sorted
    var $ul = $('ul.reorderable');
    $ul.empty();
    // forEach() might be more elegant, but isn't cross-browser yet
    for (var x=0; x<items.length; x++) {
        $ul.append(items[x].item);
    }
});

此处的工作版本: http://jsfiddle.net/nrabinowitz/Ew2EX/3/

如果您有大量项目,这可能会变慢,但这比尝试就地重新排序要容易得多。

更新了代码以比较单位数和两位数数字(因为"2" > "11")。

I'd probably use a standard array sort, then remove all the items and add them back sorted:

$('#reorder').click(function() {
    // get the list items and store references to them,
    // grabbing their names on the way
    var items = [];
    $('ul.reorderable li').each(function() {
        var name = $('input', this).attr('name'),
            // regex is overkill if you're always using the same format
            // this is quick, but a little hacky - parseInt stops
            // at non-numeric characters
            pos = parseInt(name.split("[")[1]);
        items.push({
            item: this, // store a reference to the DOM element
            pos: pos 
        });
    });
    // now sort by name
    items.sort(function(a,b) {
        return a.pos > b.pos ? 1 : -1;
    });
    // delete the items and add them back sorted
    var $ul = $('ul.reorderable');
    $ul.empty();
    // forEach() might be more elegant, but isn't cross-browser yet
    for (var x=0; x<items.length; x++) {
        $ul.append(items[x].item);
    }
});

Working version here: http://jsfiddle.net/nrabinowitz/Ew2EX/3/

This might get slow if you have a large number of items, but it's much easier than trying to reorder them in-place.

Code updated to compare single- and double-digit numbers (because "2" > "11").

与君绝 2024-11-15 01:47:50

我知道这是一个旧线程,但一旦使用 jQuery 选择元素,对元素进行排序实际上非常简单。

由于基于数组,您可以使用标准 Array.prototype.sort() 方法对其进行排序。一旦子元素排序完毕,您就可以将它们追加回父元素中,而不必担心元素重复;它会起作用:)

为了从名称中获取数字索引,我选择简单地过滤掉任何不是数字的内容。

$('.reorderable').append(function() {
  return $(this).children().sort(function(a, b) {
    var re = /\d+/,
        a_index = +a.name.match(re)[0],
        b_index = +b.name.match(re)[1];
    return a_index - b_index;
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="reorderable">
    <li>Foo<input class="hiddenThing" type=hidden name="thing[2]" value=foo /></li>
    <li>Bar<input class="hiddenThing" type=hidden name="thing[1]" value=bar /></li>
    <li>Baz<input class="hiddenThing" type=hidden name="thing[0]" value=baz /></li>
</ul>

I know this is an old thread, but it's actually very simple to sort elements once you have selected them with jQuery.

Being array-based, you can apply sorting to it using the standard Array.prototype.sort() method. Once the child elements have been sorted, you can append them back into the parent element without having to worry about duplicating elements; it would just work :)

To get the numeric index out of the name I've opted to simply filter out anything that's not a digit.

$('.reorderable').append(function() {
  return $(this).children().sort(function(a, b) {
    var re = /\d+/,
        a_index = +a.name.match(re)[0],
        b_index = +b.name.match(re)[1];
    return a_index - b_index;
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="reorderable">
    <li>Foo<input class="hiddenThing" type=hidden name="thing[2]" value=foo /></li>
    <li>Bar<input class="hiddenThing" type=hidden name="thing[1]" value=bar /></li>
    <li>Baz<input class="hiddenThing" type=hidden name="thing[0]" value=baz /></li>
</ul>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文