gpt4 book ai didi

javascript - 交换两个
  • 元素
  • 转载 作者:太空狗 更新时间:2023-10-29 13:09:33 25 4
    gpt4 key购买 nike

    我有一个包含两列无序列表的页面。在我点击一个之后,它会放大,所以只有一列,并且在它所在的行上有一个空间,所以我想将下一个 li 移到它之前,这样就没有那个空间了。

    图片显示了点击前的 div(它们不是空的,为此我只是删除了内容),点击 li 索引为 1 的 div 后它如何变化以及我想如何交换索引为 1 的 li 和2.

    我找到了一些解决方案,但没有任何效果。我最终得到了:

    function swap(n) {
    var l = n.ancestor("li.msg-box-wrapper");
    var m = n.ancestor("#doubleColumnList").all("li.msg-box-wrapper");
    var k = m.indexOf(n.ancestor("li.msg-box-wrapper"));
    if ((k%2 != 0)) {
    $(l).before( $(l).next() );
    }
    }

    最佳答案

    实现这一点的诀窍是意识到事件元素的新位置应该是从它当前位置开始的“first-in-line”

    要查找排在第一位的元素,只需查找以下元素之一:

    • 第一个 child ,或者
    • 的左偏移量小于它的前一个兄弟(至少在 ltr-context 中)。 ( candidate.offset().left < candidate.prev().offset().left )

    所以下面的将起作用:

    • 在激活(点击)时记下当前位置,并且

      • 找到下一个排在第一位的元素(包括被点击的元素)。
      • 交换这两个元素
    • 停用时只需将每个事件元素移回其原始位置即可。


    为了便于使用,我将原来的答案重写为 jquery 插件。由于找不到好听的名字,目前叫foobar .

    用法:

    // '.wrapper' is the element containing the *toggle-able* elements.
    $('.wrapper').foobar({
    // the element-selector
    elements: 'li',

    // the toggle-selector (if a *deeper* element should be used to toggle state)
    triggerOn: '.toggle',

    // indicates an active element
    activeClass: 'active',

    // get's called on activation [optional]
    onActivate: function ($el) {
    console.log('activating', $el);
    },

    // get's called on de-activation [optional]
    onDeactivate: function ($el) {
    console.log('de-activating', $el);
    }
    });

    插件:

    (function ($, pluginName) {
    'use strict';

    /**
    * Plugin behavior
    */
    $.fn[pluginName] = function (options) {
    var settings = $.extend(true, {}, $.fn[pluginName].defaults, options);

    // triggerOn-selector is required
    if (null === settings.triggerOn) {
    throw 'the `triggerOn` must be set.';
    }

    // without an element-selector
    if (null === settings.elements) {
    // use triggerOn-selector as default
    settings.elements = settings.triggerOn;
    }

    // apply behavior to each element in the selection
    return this.each(function() {
    var
    $wrapper = $(this),
    $elements = $wrapper.find(settings.elements)
    ;

    $wrapper.on(settings.event, settings.triggerOn, function () {
    var
    $el = $(this).closest(options.elements),
    isActive = $el.hasClass(settings.activeClass)
    ;

    reset($elements, settings.activeClass, settings.onDeactivate);

    if (!isActive) {
    activate($el, $elements, settings.activeClass, settings.onActivate);
    }
    });
    });
    };

    /**
    * Plugin defaults
    */
    $.fn[pluginName].defaults = {
    // required
    triggerOn: null,

    // defaults
    elements: null,
    event: 'click',
    activeClass: 'active',
    onActivate: function () {},
    onDeactivate: function () {}
    };

    /**
    * Reset all currently active elements
    *
    * @param {jQuery} $elements
    * @param {String} activeIndicator
    * @param {Function} onDeactivate
    */
    function reset($elements, activeIndicator, onDeactivate)
    {
    $elements
    .filter(function () {
    return $(this).hasClass(activeIndicator);
    })
    .each(function () {
    deactivate($(this), $elements, activeIndicator, onDeactivate);
    })
    ;
    }

    /**
    * Deactivate the given element by moving it back to it's original position and removing the active-indicator.
    *
    * @param {jQuery} $el
    * @param {jQuery} $elements
    * @param {String} activeIndicator
    * @param {Function} onDeactivate
    */
    function deactivate($el, $elements, activeIndicator, onDeactivate)
    {
    var originalIndex = $el.index();

    $el.removeClass(activeIndicator).insertBefore(
    $elements.eq(originalIndex)
    );

    onDeactivate($el);
    }

    /**
    * Activate the given element by moving it to a suitable position while applying the required indicator.
    *
    * @param {jQuery} $el
    * @param {jQuery} $elements
    * @param {String} activeIndicator
    * @param {Function} onActivate
    */
    function activate($el, $elements, activeIndicator, onActivate)
    {
    $el
    .insertAfter(
    $elements.eq(findSuitablePosition($elements, $el.index()))
    )
    .addClass(activeIndicator)
    ;

    onActivate($el);
    }

    /**
    * @param {jQuery} $elements
    * @param {Number} originalIndex
    */
    function findSuitablePosition($elements, originalIndex)
    {
    // short-circuit simple case
    if (0 === originalIndex) {
    return originalIndex;
    }

    var
    candidateIndex = originalIndex,
    lim = $elements.length,
    $candidate
    ;

    for (; candidateIndex < lim; candidateIndex += 1) {
    $candidate = $elements.eq(candidateIndex);

    if ($candidate.offset().left < $candidate.prev().offset().left) {
    return candidateIndex;
    }
    }

    throw 'could not find a suitable position.';
    }
    })(jQuery, 'foobar');

    演示:http://plnkr.co/edit/8ARXgq2pLSzm9aqHI8HL?p=preview


    原始答案:

    如果您愿意使用 jQuery,以下内容将有效。

    它比需要的要复杂一些,但这种方式也适用于多于两列。请注意代码风格,以便于遵循。

    $('.wrapper').each(function () {
    var $wrapper = $(this);

    $wrapper.on('click', 'li', function () {
    var
    $el = $(this),
    isOpen = $el.is('.open')
    ;

    reset();

    if (!isOpen) {
    open($el);
    }
    });

    function open($el)
    {
    var originalIndex = $el.index();

    // note index and move to suitable position
    $el
    .data('original-index', originalIndex)
    .insertAfter(
    $wrapper.find('li').eq(findSuitablePosition(originalIndex))
    )
    .addClass('open')
    ;
    }

    function reset()
    {
    $wrapper.find('.open').each(function () {
    var
    $el = $(this),
    originalIndex = $el.data('original-index')
    ;

    $el.removeClass('open').insertBefore(
    $wrapper.find('li').eq(originalIndex)
    );
    });
    }

    function findSuitablePosition(originalIndex)
    {
    // short-circuit simple case
    if (0 === originalIndex) {
    return originalIndex;
    }

    var
    $candidates = $wrapper.find('li'),
    candidateIndex = originalIndex,
    lim = $candidates.length,
    candidate
    ;

    for (; candidateIndex < lim; candidateIndex += 1) {
    candidate = $candidates.eq(candidateIndex);

    if (candidate.offset().left < candidate.prev().offset().left) {
    return candidateIndex;
    }
    }

    throw 'could not find a suitable position.';
    }
    });
    ul {
    list-style: none;
    margin: 0;
    padding: 5px 10px;
    width: 300px;
    border: 1px solid #ccc;
    overflow: hidden;
    font-family: sans-serif;
    margin-bottom: 5px;
    }

    li {
    float: left;
    margin: 10px 5px;
    padding: 3px;
    border: 1px solid #ccc;
    box-sizing: border-box;
    }

    ul li.open {
    width: calc(100% - 10px);
    height: 40px;
    border-color: green;
    }

    .two li {
    width: calc(50% - 10px);
    }

    .three li {
    width: calc(33% - 10px);
    }

    .four li {
    width: calc(25% - 10px);
    }
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <ul class="wrapper two">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    </ul>

    <ul class="wrapper three">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    </ul>

    <ul class="wrapper four">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
    <li>11</li>
    <li>12</li>
    </ul>

    关于javascript - 交换两个 <li> 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32453584/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com