Галантерея среднего и продвинутого уровня! Углубленный анализ схемы потока водопада

JavaScript Vue.js
Галантерея среднего и продвинутого уровня! Углубленный анализ схемы потока водопада

Чем больше вы знаете, тем больше вы не знаете
点赞Посмотри еще раз, аромат остался в руке, и слава

предисловие

В конце 2019 года в последнее время меня больше интересует контент, связанный с макетом, здесь я буду разбирать сценарии использования и различные схемы реализации, связанные с водопадным потоком.

Схема водопада

瀑布流Также известный как макет водопада, это относительно популярный метод макета страницы.Профессиональное английское название [Masonry Layouts]. В отличие от традиционного отображения страниц, визуальное представление参差不齐Многоколоночный макетPinterestИспользуйте в первую очередь.

Нет картинки, нет правды:

Как показано на рисунке, веб-страница отображается参差不齐макет в несколько столбцов, картинка等宽不等高, увеличивайте и уменьшайте масштаб в соответствии с исходным масштабом изображения, пока ширина не достигнет фиксированного требования.После заполнения каждой строки к ней последовательно добавляются следующие элементы, которые визуально кажутся разбросанными и эклектичными.

Преимущества водопадного течения

Преимущества заключаются в следующем:

  • Экономия места, красивый внешний вид и более художественный.
  • Очень удобный сенсорный экран, проведите пальцем вверх, чтобы просмотреть
  • Просмотр и размышления пользователей при просмотре не так легко прервать, и их легче удержать.

С точки зрения психологического опыта женщины — существа, которым не нужно останавливаться, когда они часами ходят по магазинам, и этой психологии соответствует бесконечный водопад. Картины водопадов подобны товарам, покупкам, подметанию. Пока женщины продолжают растягивать страницу вниз, это похоже на бесконечную торговую улицу и торговый центр без ограничений по высоте пола. Следующая страница в традиционном макете — это прерывание, как бойфренд, шепчущий ему на ухо: Отдохни, я устал... Результат налицо~

Недостатки водопада

Недостаток выглядит следующим образом:

  • Пользователи не могут знать общую длину содержимого и не имеют макроконтроля над содержимым.
  • У пользователя нет возможности узнать, где он сейчас или как далеко он от конца.
  • Нелегко определить местонахождение того, что было замечено ранее, при возврате назад.
  • Легко вызвать загрузку страницы.
  • При просмотре легко вызвать усталость пользователя, и нет короткого времени для отдыха.

Применимые сценарии потока водопада

В соответствии с преимуществами и недостатками водопадного потока нетрудно понять, когда разумно выбрать водопадный поток:

  • 内容以图片为主的时候, поток водопада является лучшим выбором. Картинки занимают много места, а скорость понимания мозгом выше, чем у текста, и есть много контента, который можно просмотреть за короткое время, поэтому, если используется пейджинг, пользователи должны часто перелистывать страницы, влияя на эффект погружения, а водопады Streams могут решить эту проблему.

  • 信息与信息之间相对独立时, поток водопада является лучшим выбором. Если информация сильно коррелирована, пользователь должен выполнить множество операций возврата, чтобы просмотреть предыдущую или последующую информацию.Наоборот, если информация относительно независима, можно использовать каскадный поток, чтобы пользователи могли принимать информацию из разных мест в одном месте. в то же время.

  • 信息与搜索匹配比较模糊时, поток водопада является лучшим выбором. Интуитивное впечатление от каскадного потока состоит в том, что информация, отображаемая в то же время, имеет примерно одинаковую степень соответствия поисковым запросам пользователя, в то время как интуитивное впечатление от пейджингового отображения состоит в том, что считается, что чем выше информация, тем больше она соответствует поисковому запросу пользователя. Таким образом, водопадный поток можно использовать, когда нет четкого различия между информационным и поисковым соответствием.

  • 用户目的性不强的时候, поток водопада является лучшим выбором. Если у пользователя есть конкретная информация, которую нужно найти, пейджинг более удобен для поиска и определения местоположения, а когда цель слаба, каскадный поток может увеличить время пребывания пользователя и неожиданные выгоды.

Многоколоночный макет с несколькими столбцами для достижения водопадного потока

как правилоMulti-columnСтолбцы для текста:

.container {
  column-count: 3;
}

multi-columnПорядок дочерних элементов в макете первый从上往下Опять таки从左至右.

В соответствии с этой функцией мы можем использовать для достижения瀑布流.

multi-columnвыполнить瀑布流В основном это зависит от следующих свойств:

  • column-count: установить количество столбцов
  • column-width: Установите ширину каждого столбца, количество столбцов определяется总宽度а также每列宽度Рассчитано
  • column-gap: Установите интервал между столбцами.

column-countа такжеcolumn-widthОба могут использоваться для определения количества столбцов, и нет четкого приоритета. Расчет приоритета зависит от конкретного сценария.

Метод расчета: расчетcolumn-countа такжеcolumn-widthИспользуется определенное количество столбцов после преобразования, в зависимости от того, что меньше.

Пример изображения и текста:

<div class="masonry">
    <div class="item">
        <img src="..."/>
        <span class="title">...</span>
    </div>
    <div class="item">
        <img src="..."/>
        <span class="title">...</span>
    </div>
    <!-- more items-->
</div>
.masonry{
    column-count: 3;
    column-gap: 10px;
}
.masonry .item{
    border:1px solid #999;
    margin-bottom: 10px;
}
.masonry .item img{
    width: 100%;
}

Нажмите, чтобы просмотреть онлайн-демонстрацию и полный код

Эффект следующий:

Мы видим, что хотя реализация瀑布流, но странно то, что последний элемент первых двух столбцов в примере имеет文本内容одеяло自动断开, часть в конце текущего столбца и часть в заголовке следующего столбца.

мое пониманиеmulti-columnМакет будет автоматически перетекать и балансировать элементы внутри него, насколько это возможно, чтобы высота каждого столбца была одинаковой, поэтому текстовая сцена внутри него будет распределена по двум столбцам.

И этот метод отображения, несомненно, то, что мы не хотим видеть.Мы хотим, чтобы каждый элемент был независимым и не отключался до и после.На данный момент нам нужно использоватьbreak-insideреализовать.

break-inside: auto | avoid

  • Авто: Элементы могут быть прерваны
  • избежать: элемент не может быть прерван

Измените предыдущий пример:

.masonry .item{
    break-inside: avoid;
}

Нажмите, чтобы просмотреть онлайн-демонстрацию и полный код

Эффект следующий:

Эффект достигается, но за счетmulti-columnПорядок дочерних элементов в макете первый从上往下Опять таки从左至右Поэтому этот метод применим только к случаю, когда данные фиксированы, и к случаю, когда данных может быть динамически добавлено больше, а данные не применяются.

оcolumnДополнительные сведения об использовании см.MDN
оcolumnсовместимость см.caniuse

Компоновка сетки реализует поток водопада

Grid布局является самой мощной схемой компоновки CSS.

Он разделяет веб-страницы в сетки, и вы можете объединить различные сетки произвольно, чтобы сделать различные макеты. То, что использовалось только с сложными каркасами CSS, теперь встроен в браузер.

Макет, подобный приведенному выше, является лучшим из макетов Grid, поэтому мы можем использоватьGridреализовать瀑布流.

достигать瀑布流Сначала введем следующие свойства:

  • display: Установить какgridУказывает, что текущий контейнерGrid布局
  • grid-template-columns: определить ширину столбца каждого столбца
  • grid-template-rows: определить высоту строки каждой строки
  • column-gap: используется для установки интервала между столбцами

grid-template-columnsа такжеgrid-template-rows, вы можете использовать абсолютные единицы или проценты. А для того, чтобы выразить пропорциональную зависимость,Gridмакет обеспечиваетfrключевое слово, если установлено1frа также2fr, что указывает на то, что последний в два раза больше первого.

Согласно приведенным выше свойствам, сначала напишите пример, чтобы увидеть эффект:

<div class="masonry">
    <div class="item"></div>
    <!-- more items-->
</div>
.masonry{
    display: grid;
    grid-template-rows: 1fr 1fr 1fr; // 分为3行
    grid-template-columns: 1fr 1fr 1fr; // 分为3列
    column-gap:5px; // 列间距5px
}

Нажмите, чтобы просмотреть онлайн-демонстрацию и полный код

Эффект следующий:

Мы видим блоки div разной высоты, распределенные внутри каждой ячейки, но еще не реализовали это瀑布流Эффект.

достигать瀑布流Еще несколько свойств:

  • grid-row-start: Уровень, на котором расположена верхняя граница网格线
  • grid-row-end: Уровень, на котором расположена нижняя граница网格线
  • grid-column-start: вертикально, где левая граница网格线
  • grid-column-end: Вертикально, где находится правая граница网格线

Так что же网格线Шерстяная ткань?

Линии, которые делят сетку, называются网格线. Горизонтальные линии сетки очерчивают строки, а вертикальные линии сетки очерчивают столбцы.

При нормальных обстоятельствах,n行имеютn + 1корневая горизонтальная линия сетки,m列имеютm + 1Одна вертикальная линия сетки, например четыре горизонтальные линии сетки в три ряда.

Изображение выше представляет собой сетку 4 x 4 с 5 горизонтальными линиями сетки и 5 вертикальными линиями сетки.

Эти 4 свойства могут получить следующие свойства:

  • auto: указывает на автоматическое размещение
  • 自定义名称: линиям сетки можно присвоить имя и указать здесь ссылку (не рассматривается в этой статье).
  • 网格线索引: представляет количество линий сетки (начиная с 1)
  • span + 数字: Указывает, сколько сеток охватывают верхняя и нижняя границы или левая и правая границы.

иди посмотри на это网格线Какая польза

Для удобства просмотра давайте изменим высоту каждого блока div в примере на 100% и изменим код стиля на:

.item{
    height:100%;
}
.item:first-child{
    grid-row-start:1;
    grid-row-end:span 2;
}

Нажмите, чтобы просмотреть онлайн-демонстрацию и полный код

МыGridПервый элемент в макете добавляетgrid-row-start:1а такжеgrid-row-end:span 2, так что его верхняя граница расположена на 1 горизонтальной линии сетки, а нижняя граница отделена от верхней границы 2 горизонтальными линиями сетки. Судя по эффекту, это немного похоже瀑布流Все кончено!

В предыдущем примере мы указали отдельноgrid-template-columnsа такжеgrid-template-rowsОн используется для определения нескольких строк и столбцов.За счет определения количества строк и столбцов определяются также ширина и высота каждой ячейки в нем, а также собственно瀑布流В макете ширина фиксированная, высота динамическая, а конкретное количество рядов нельзя определить в начале, поэтому нам нужноGridВ макете не указана высота строк (grid-template-rows).

Введите еще одно свойство:

  • grid-auto-rows: используется для установки высоты строки дополнительной сетки

В сочетании с расположением потока водопада, реализованным только что упомянутой сеткой, высота строки (grid-template-rows) не задана.grid-auto-rowsпосле того, как высота всех ячеекgrid-auto-rowsуказанное значение.

из-заgrid-row-startа такжеgrid-row-endВы можете указать положение верхнего и нижнего полей ячейки, что означает, что высота ячейки может быть растянута, а исходная высота определяетсяgrid-auto-rowsрешили, нам просто нужноgrid-auto-rowsУстановите небольшое значение, например10px, а затем растяните его, чтобы указать его высоту как реальную высоту, и выполните следующие действия для каждой ячейки, после чего реализуется поток водопада ~

Предположим, что реальная высота содержимого первой ячейки составляет 100 пикселей, так какgrid-auto-rows:10px, то мы можем установить его следующим образом:

.item1{
    grid-row-start:'auto';
    grid-row-end:span 10;
}

Предполагая, что реальная высота содержимого второй ячейки составляет 150 пикселей, из-заgrid-auto-rows:10px, то мы можем установить его следующим образом:

.item2{
    grid-row-start:'auto';
    grid-row-end:span 15;
}

Конечно, на практике瀑布流Он больше для отображения картинок, а так как картинки загружаются асинхронно, реальную ширину и высоту картинок можно получить только после завершения загрузки, поэтому приходится использовать JS для динамического растягивания высоты ячеек.

Псевдокод выглядит следующим образом:

    //image-dom
    let img = document.getElementsByTagName('img')[0];
    //image-dom 当前宽度
    let width = img.width;
    
    let image = new Image();
    image.src = 'xxxx.img';
    image.onload = function(){
        //图片原宽
        let w = image.width;
        //图片原高
        let h = image.height;
        //image-dom的真实高度(依据当前宽度及图片真实宽高)
        let height = Math.round(h * width / w)
        //设置当前跨越几个网格(每个网格10px)
        img.style.gridRowEnd = `span ${~~(height/10)}`
    }

Нажмите, чтобы просмотреть онлайн-демонстрацию и полный код

Эффект следующий:

оcolumnДополнительные сведения об использовании см.MDN
оcolumnсовместимость см.caniuse

Flexbox реализует водопадный поток

FlexboxМакет очень широко используется сегодня, и его можно рассматривать как очень зрелую функцию. я не буду представлять его здесьFlexboxДля соответствующего содержания макета, если у вас есть друзья, которые не очень хорошо знают, вы можете обратиться к Ruan Yifeng.Учебное пособие по гибкому макету: синтаксис

Тогда мы увидимFlexboxКак реализовать макет потока водопада.

На этом этапе нам нужно спроектировать html-структуру следующим образом:

<div class="masonry">
    <!-- 第一列 -->
    <div class="column">
        <div class="item"></div>
        <!-- more items-->
    </div>
    <!-- 第二列 -->
    <div class="column">
        <div class="item"></div>
        <!-- more items-->
    </div>
    <!-- 第三列 -->
    <div class="column">
        <div class="item"></div>
        <!-- more items-->
    </div>
</div>

в приведенном выше кодеdiv.masonryпредставляет текущий контейнер водопада,div.columnконтейнер, представляющий каждый столбец,div.itemПредставляет каждый элемент в каждом столбце.

мы должныdiv.masonryа такжеdiv.columnоба проходятdisplay:flexустановить его наFlexконтейнер.

разница в том瀑布流容器Направление главной оси установлено на горизонтальное направлениеflex-direction:row,列容器Направление главной оси установлено в вертикальное направлениеflex-direction:column

.masonry {
    display: flex; // 设置为Flex容器
    flex-direction: row; // 主轴方向设置为水平方向
}

.column {
    display: flex; // 设置为Flex容器
    flex-direction: column; // 主轴方向设置为垂直方向
}

Поскольку текущая структура html разделена на瀑布流容器а также列容器, а изображения общего спроса从左至右Опять таки从上到下чтобы устроить, так что вам нужно пройтиJavascriptЧтобы различать конкретные данные каждого столбца:

Предполагая, что есть три столбца, псевдокод выглядит следующим образом:

let data1 = [], //第一列
    data2 = [], //第二列
    data3 = [], //第三列
    i = 0;
while (i < data.length) {
    data1.push(data[i++]);
    if (i < data.length) {
        data2.push(data[i++]);
    }
    if (i < data.length) {
        data3.push(data[i++]);
    }
}
return {
    //第一列
    data1,
    //第二列
    data2,
    //第三列
    data3
};

Нажмите, чтобы просмотреть онлайн-демонстрацию и полный код

Эффект следующий:

Суммировать

При создании каскадного потока необходимо учитывать несколько основных факторов, таких как качество изображения, размер изображения и скорость загрузки.Если они не могут быть удовлетворены одновременно, взаимодействие с пользователем будет значительно снижено. Лично я думаю, что поток водопада будет лучше для работы с сенсорным экраном.

Эта статья обобщаетmulti-column,grid,FlexboxРеализовать водопадный поток можно тремя способами, схемы реализации разные, учитывая совместимость и простоту использования, рекомендуется использоватьFlexboxреализация макета.

Представлено в этой статье瀑布流схему компоновки, которую можно назвать по существу竖向瀑布流, место ограничено и не покрывает横向瀑布流содержание, о横向瀑布流Содержание будет продолжено в следующей статье, так что следите за обновлениями.

Ссылаться на

напиши в конце

  • Если в статье есть ошибки, исправьте их в комментариях, если статья вам поможет, добро пожаловать点赞а также关注
  • Эта статья была впервые опубликована одновременно сgithub, доступны наgithubНайдите больше отличных статей вWatch & Star ★
  • Для последующих статей см.:строить планы

Добро пожаловать в публичный аккаунт WeChat【前端小黑屋】, 1–3 высококачественные высококачественные статьи публикуются каждую неделю, чтобы помочь вам в продвижении вперед.

Также приглашаю добавить меня в друзья, ответить加群, беру тебя в группу и изучай фронтенд со мной~