簡體   English   中英

如何檢測元素是否在其容器之外?

[英]How to detect if an element is outside of its container?

所以我創建了以下代碼和 我有一個嚴重依賴用戶輸入的 web 應用程序。 出於演示目的,我通過在 a4 格式的頁面上顯示一堆作者來保持簡單。 pagefont-size都使用vw單位來使其具有響應性。

正如您在代碼框中看到的那樣,最后幾位作者被迫離開頁面,因為它不再適合容器。 理想情況下,我想檢測不再適合頁面的內容,並生成第二個相同的 a4 頁面來顯示該特定內容。

目前在我的網絡應用程序中,我剛剛添加了overflow: scroll; 到放置所有內容的頁面div ,這樣它至少看起來有點“好”。 但這不是一個很好的用戶體驗,我想改進它。

我不知道從哪里開始,所以非常感謝任何在正確方向上的幫助。

提前致謝。

CSS

#app {
  -webkit-font-smoothing: antialiased;
  font: 12pt "Tahoma";
}

.book {
  margin: 0;
  padding: 0;
  background-color: #FAFAFA;
  font: 3vw "Tahoma";
}

* {
  box-sizing: border-box;
  -moz-box-sizing: border-box;
}

.page {
  /* overflow: scroll; */
  display: block;
  width: calc(100 / 23 * 21vw);
  height: calc(100 / 23 * 29.7vw);
  margin: calc(100 / 23 * 1vw) auto;
  border: 1px #D3D3D3 solid;
  border-radius: 5px;
  background: white;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
}

.subpage {
  margin: calc(100 / 23 * 1vw);
  width: calc(100 / 23 * 19vw);
  height: calc(100 / 23 * 27.7vw);
  line-height: 2;
  border: 1px solid red;
  outline: 0cm #FAFAFA solid;
}

.subpage-content {
  height: 100%;
}

Javascript

export default {
  name: "App",
  data() {
    return {
      authors: [
        { id: 1, name: "Smith" },
        { id: 2, name: "Johnson" },
        { id: 3, name: "Williams" },
        { id: 4, name: "Jones" },
        { id: 5, name: "Brown" },
        { id: 6, name: "Davis" },
        { id: 7, name: "Miller" },
        { id: 8, name: "Wilson" },
        { id: 9, name: "Moore" },
        { id: 10, name: "Taylor" },
        { id: 11, name: "Anderson" },
        { id: 12, name: "Thomas" },
        { id: 13, name: "Jackson" },
        { id: 14, name: "White" },
        { id: 15, name: "Harris" },
        { id: 16, name: "Martin" },
        { id: 17, name: "Thomspson" },
        { id: 18, name: "Garcia" },
        { id: 19, name: "Martinez" },
        { id: 20, name: "Robinson" },
        { id: 21, name: "Clark" },
        { id: 22, name: "Rodeiquez" },
        { id: 23, name: "Lewis" },
        { id: 24, name: "Lee" }
      ]
    };
  }
};

HTML

<template>
  <div id="app">
    <div class="container-fluid">
      <div class="book">
        <div class="page">HEADER
          <div class="subpage" id="editor-container">Authors:
            <!-- <div class="subpage-content">The real content</div> -->
            <div v-for="item in authors" :key="item.id">{{ item.name }}</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

您可以在此處查看代碼沙箱的分支

我將數據結構(和模板)更改為擁有一個pages數組,其中每個頁面都有一個authors數組,而不是一個。 最初,第一頁包含所有作者。


data() {
  return {
    pages: [
      {
        authors: [
          { id: 1, name: "Smith" },
          ...
        ]
      }
    ]
  }
}
<div class="page" v-for="(page, pageIndex) in pages" :key="pageIndex">HEADER
  <div class="subpage" id="editor-container">
    <template v-if="pageIndex < 1">Authors:</template>
    <!-- <div class="subpage-content">The real content</div> -->
    <div v-for="item in page.authors" :key="item.id" class="author">{{ item.name }}</div>
  </div>
</div>

然后,我創建了一個方法recalcPages ,在安裝組件時調用該方法:

  methods: {
    recalcPages() {
      let pageElements = this.$el.querySelectorAll(".page");
      Array.from(pageElements).some((p, pi) => {
        let authors = p.querySelectorAll(".author");
        if (authors.length) {
          return Array.from(authors).some((a, ai) => {
            let offPage = a.offsetTop + a.offsetHeight > p.offsetHeight;
            if (offPage) {
              let currentAuthors = this.pages[pi].authors;
              var p1 = currentAuthors.slice(0, ai);
              var p2 = currentAuthors.slice(ai);

              this.pages[pi].authors = p1;
              this.pages.push({ authors: p2 });
            }
            return offPage;
          });
        }
        return false;
      });
    }
  },

它迭代實際的 DOM 節點並使用offsetTop + offsetHeight來計算作者是否離開頁面。 一旦一個元素離開頁面,它和所有后續元素都會從當前頁面的authors中分離出來,並插入第二個頁面。

您還需要在更新刪除所有頁面的內容后調用this.recalcPages()並在第一個頁面上設置一個新的authors數組以再次自動拆分,除非您只添加到最后一頁。 您也可以嘗試使用updated的鈎子自動實現這一點,我沒有嘗試過。

當然這是一個相當繁重的操作,因為它渲染組件只是為了通過修改數據來再次觸發重新渲染。 但是除非你不知道每個元素的確切高度,否則沒有辦法繞過它(至少我不知道)。

順便說一句(雖然你的最終數據可能看起來不同,但只是為了這個演示的完整性)我還將你的Authors:標題包裝在<template v-if="pageIndex < 1">Authors:</template>為了僅在第一頁上顯示它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM