找到附加内容的正确位置

时间:2016-11-12 11:17:44

标签: javascript jquery

我的jQuery脚本:

我的jQuery脚本是一个非常大的文件,但我已将其修改为此问题的最相关部分,如下所示;

$(document).ready(function() {
    "use strict";

    $(document).on('click', function(e) {

        if (($(e.target).attr('data-action')) || $(e.target).parent().data('action')) {

            if ($(e.target).attr('data-action')) {
                action = $(e.target).data('action');
            } else {
                action = $(e.target).parent().data('action');
            }

            switch (action) {

                case 'mail-pin':
                    // Code for 'mail-pin' click
                    break;

                default:
                    return;
            }
        }
    });
});

我的HTML结构:

<!-- === INBOX LIST STARTS === -->
<div class="inbox-content clearfix">
    <div class="Head">
        <!-- Code for inbox header -->
    </div>
    <div class="Body clearfix">
        <div class="Pinned">
            <div class="Mail clearfix" data-mail-ID="1234">
                <!-- Mail Item -->
            </div>
            <div class="Mail clearfix" data-mail-ID="1235">
                <!-- Mail Item -->
            </div>
        </div>
        <div class="Standard">
            <div class="Mail clearfix" data-mail-ID="1233">
                <!-- Mail Item -->
            </div>
            <div class="Mail clearfix" data-mail-ID="1236">
                <!-- Mail Item -->
            </div>
        </div>
    </div>
</div>

问题

首先,我知道如何通过以下方式检查项目从.Pinned元素或.Standard移动到另一个元素的位置;

case 'mail-pin':
    console.log('Hello');
    if ($(e.target).closest('.Mail').parent().hasClass('Pinned')) {
        console.log('It is pinned.');
    } else {
        console.log('It is not pinned.');
    }
    break;

我不明白如何实现的目的是如何将内容附加到正确的位置,并且我参考从data-mail-ID="1233"获取的顺序,以便在点击固定或取消固定时,内容将被附加到该地点,因此如果您点击以固定邮件ID X,它将在X - 1后追加,反之亦然,如果该项目被取消固定。

重要提示:

每个列表每页只显示20个项目,点击进入下一页或上一页后,页面将获取在点击固定或取消固定时修改的内容,因此该脚本仅与这些ID相关&# 39; s可以在该页面上找到,因此意味着如果你无法找到ID 123和122,它只是被移除而且为了固定,只有在.Pinned可见时才会出现追加部分,否则该项目只是除去。

1 个答案:

答案 0 :(得分:1)

搜索具有较大ID的第一封邮件,并在其前面附加单击的元素。

(下面的函数使用closure来存储相关的DOM部分,所以我只需要查询一次DOM。它不是真的需要,但这就是我做这些事情的方式^^)

var togglePinState = (function () {
    var pinned = document.querySelector(".Pinned"),
        unpinned = document.querySelector(".Standard"),
        pinnedMails = pinned.getElementsByClassName("Mail"),
        unpinnedMails = unpinned.getElementsByClassName("Mail");
        // .getElementsByClassName() because it returns a live HTMLCollection
        // pinnedMails and unpinnedMails will always have the currently un/pinned "mails" without re-querying the DOM

    return function (mailItem) {
        var mailId = parseInt(mailItem.getAttribute("data-mail-ID"), 10),
            mailItemIsPinned = (mailItem.parentNode.className === "Pinned"),
            newParent = (mailItemIsPinned ? unpinned : pinned),
            mailsToCheck = (mailItemIsPinned ? unpinnedMails : pinnedMails),
            // variables for the loop below
            i = 0,
            l = mailsToCheck.length,
            currentId;

        for (; i < l; i++) {
            currentId = parseInt(mailsToCheck[i].getAttribute("data-mail-ID"), 10);
            if (currentId > mailId) {
                // insert before first pinned mail with a bigger id
                mailsToCheck[i].insertAdjacentElement("beforebegin", mailItem);
                return;
            }
        }

        // at this point we have not found a mail with a bigger id so we can safely append it at the end of the list
        newParent.appendChild(mailItem);
    }
}());

要在脚本中使用它,只需在mail-pin分支中调用它:

case 'mail-pin':
    togglePinState(e.target);
    break;

以下是行动中的功能:

    var togglePinState = (function() {
      var pinned = document.querySelector(".Pinned"),
        unpinned = document.querySelector(".Standard"),
        pinnedMails = pinned.getElementsByClassName("Mail"),
        unpinnedMails = unpinned.getElementsByClassName("Mail");
      // .getElementsByClassName() because it returns a live HTMLCollection
      // pinnedMails and unpinnedMails will always have the currently un/pinned "mails" without re-querying the DOM

      return function(mailItem) {
        var mailId = parseInt(mailItem.getAttribute("data-mail-ID"), 10),
          mailItemIsPinned = (mailItem.parentNode.className === "Pinned"),
          newParent = (mailItemIsPinned ? unpinned : pinned),
          mailsToCheck = (mailItemIsPinned ? unpinnedMails : pinnedMails),
          // variables for the loop below
          i = 0,
          l = mailsToCheck.length,
          currentId;

        for (; i < l; i++) {
          currentId = parseInt(mailsToCheck[i].getAttribute("data-mail-ID"), 10);
          if (currentId > mailId) {
            // insert before first pinned mail with a bigger id
            mailsToCheck[i].insertAdjacentElement("beforebegin", mailItem);
            return;
          }
        }

        // at this point we have not found a mail with a bigger id so we can safely append it at the end of the list
        newParent.appendChild(mailItem);
      }
    }());

document.querySelector("div.inbox-content")
					.addEventListener("click", function(e) {
          	if (e.target.nodeName === "DIV" && e.target.classList.contains("Mail")) {
            	togglePinState(e.target);
            }
          });
div { padding: 2px }
div.Mail {
  border: dotted 1px black;
  text-align: center;
}
.Pinned { border: solid 1px red }
.Standard { border: solid 1px blue }
<!-- === INBOX LIST STARTS === -->
<div class="inbox-content clearfix">
  <div class="Head">
    <!-- Code for inbox header -->
  </div>
  <div class="Body clearfix">
    <div class="Pinned">
      <div class="Mail clearfix" data-mail-ID="1234">1234</div>
      <div class="Mail clearfix" data-mail-ID="1237">1237</div>
    </div>
    <div class="Standard">
      <div class="Mail clearfix" data-mail-ID="1233">1233</div>
      <div class="Mail clearfix" data-mail-ID="1235">1235</div>
      <div class="Mail clearfix" data-mail-ID="1236">1236</div>
      <div class="Mail clearfix" data-mail-ID="1238">1238</div>
    </div>
  </div>
</div>