成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

原生JavaScript 瀑布流 實(shí)現(xiàn) zx-waterfall

Keven / 3194人閱讀

摘要:源碼地址使用說明注意參數(shù)瀑布流外容器瀑布流寬度,如果初始化時(shí)外容器未隱藏狀態(tài)則需使用該參數(shù)默認(rèn)獲取外容器寬度子元素選擇器,比如樣式名元素間的間隔元素間垂直方向間隔,默認(rèn)使用值元素寬度默認(rèn)會(huì)根據(jù)容器寬度自動(dòng)調(diào)整強(qiáng)制元素寬度,

源碼地址: https://github.com/capricornc...

使用說明

Install zx-waterfall using npm

npm i --save zx-waterfall

ES6+

import ZxWaterfall from "zx-waterfall"

const waterfall = new ZxWaterfall({
  // HTMLElement, waterfall items"s outer container
  container: document.getElementById("zxWaterfall"),
  // children item selector, eg. ".item-container"
  itemSelector: ".item-wrapper",
  // item"s spacing, unit px
  gutter: 20,
  // item"s width
  itemWidth: 300
})
// reset
waterfall.reset()
// loaMedias
waterfall.loadMedia(["http://xx.com/aaa.jpg"]).then(_ => {
  // change
  waterfall.change()
})

browser

demo

https://capricorncd.github.io...

注意

container "s style must be style.position=relative|absolute|fixed

參數(shù)options

container: HTMLElement

瀑布流外容器.

containerWidth: Number

瀑布流寬度,如果初始化時(shí)外容器未隱藏狀態(tài)則需使用該參數(shù).

默認(rèn)獲取外容器寬度.

itemSelector: String

子元素選擇器,比如 樣式名".item-container".

gutter: Number

元素間的間隔.

verticalGutter: Number

元素間垂直方向間隔,默認(rèn)使用gutter值.

itemWidth: Number

元素寬度, 默認(rèn) 300, 會(huì)根據(jù)容器寬度自動(dòng)調(diào)整.

forceItemWidth: Boolean

強(qiáng)制元素寬度,即使用itemWidth作為寬度值,默認(rèn) false.

align: String, Optional value left|center|right

強(qiáng)制寬度時(shí),元素顯示靠邊位置,默認(rèn) center.

方法

reset()

重置瀑布流初始值

loadMeida(array)

預(yù)加載列表數(shù)據(jù)中的image媒體元素.

array: ["http://a.com/1.jpg", "http://a.com/2.jpg"]

@return promise

change()

列表數(shù)據(jù)改變后后,通知瀑布流更新元素位置.

源碼
/**
 * preload image
 * @param url
 * @param handler
 */
function loadImage (url, handler) {
  let $el = document.createElement("img")
  $el.src = url
  $el.onload = handler
  $el.onerror = handler
  $el = null
}

/**
 * to int
 * @param m
 * @returns {number}
 */
function int (m) {
  let n = parseInt(m)
  return isNaN(n) ? 0 : n
}

/**
 * convert pseudoArray to array
 * @param pseudoArray
 * @param index
 * @returns {T[]}
 */
function slice (pseudoArray, index) {
  return Array.prototype.slice.call(pseudoArray, int(index))
}

// default options
const DEF_OPTIONS = {
  // HTMLElement, waterfall items"s outer container
  container: null,
  // container"s width, container are hidden when initialized
  // default get container offsetWidth when it"s visible
  containerWidth: 0,
  // children item selector, eg. ".item-container"
  itemSelector: "",
  // item"s spacing, unit px
  gutter: 20,
  // item"s vertical spacing, default use gutter"s value
  verticalGutter: 0,
  // item"s width
  itemWidth: 300,
  // force item width
  forceItemWidth: false,
  // Horizontal align when forceItemWidth is true
  align: "center"
}

/**
 * ZxWaterfall
 */
class ZxWaterfall {
  /**
   * constructor
   * @param opts
   */
  constructor (opts) {
    opts = Object.assign({}, DEF_OPTIONS, opts)
    // check container
    if (!opts.container || opts.container.nodeType !== 1) {
      throw new TypeError(`Instancing parameter "container" is not HTMLElement.`)
    }
    // check itemSelector
    if (!opts.itemSelector || typeof opts.itemSelector !== "string") {
      throw new TypeError(`Instancing parameter "itemSelector" is null or is"t a string.`)
    }
    // check verticalGutter
    if (!opts.verticalGutter) {
      opts.verticalGutter = opts.gutter
    }
    // item number
    this.count = 0
    this.opts = opts
    this._init()
    // clone this.reset
    this._resetClone = this.reset.bind(this)
    window.addEventListener("resize", this._resetClone)
  }

  /**
   * initialization
   * @private
   */
  _init () {
    let opts = this.opts
    // container width
    let containerWidth = int(opts.containerWidth) || opts.container.offsetWidth
    // column number
    let columnNum = Math.floor(containerWidth / (opts.itemWidth + opts.gutter))
    // opts.itemWidth when opts.forceItemWidth = true
    // else use compute new width
    this.itemWidth = opts.forceItemWidth
      ? opts.itemWidth
      : (containerWidth - (columnNum + 1) * opts.gutter) / columnNum
    // column current height array
    this.columns = Array(columnNum)
    this.columns.fill(0, 0)
    // offset left when forceItemWidth=true
    this.offsetLeft = 0
    if (opts.forceItemWidth) {
      let residualSpaceWidth = containerWidth - (this.itemWidth + opts.gutter) * columnNum - opts.gutter
      switch (opts.align) {
        case "center":
          this.offsetLeft = residualSpaceWidth / 2
          break
        case "right":
          this.offsetLeft = residualSpaceWidth
          break
      }
    }
  }

  /**
   * set items position
   * @private
   */
  _setPosition () {
    let opts = this.opts
    // get new item elements
    let $childs = slice(opts.container.querySelectorAll(opts.itemSelector), this.count)
    // console.log(this.count, $childs)
    let len = $childs.length
    // reset this.count value
    this.count += len
    // handle new $item
    let i, $item
    for (i = 0; i < len; i++) {
      $item = $childs[i]
      if (!$item) continue
      $item.style.position = "absolute"
      $item.style.width = this.itemWidth + "px"
      $item.style.display = "inline-block"
      // get columns min value
      let min = Math.min.apply(null, this.columns)
      let index = this.columns.findIndex(val => val === min)
      // set $item position
      $item.style.top = `${min + opts.verticalGutter}px`
      $item.style.left = `${this.offsetLeft + (this.itemWidth + opts.gutter) * index + opts.gutter}px`
      // reset waterfall current column height value
      let itemHeight = $item.offsetHeight
      this.columns[index] = min + itemHeight + opts.verticalGutter
      // update container new min height style
      // opts.container.style.minHeight = Math.max.apply(null, this.columns) + opts.verticalGutter + "px"
    }
  }

  /**
   * container"s items number change
   */
  change () {
    // reset postion, when new item element append to container, or remove
    this._setPosition()
  }

  /**
   * reset
   */
  reset () {
    this.count = 0
    this._init()
    this._setPosition()
  }

  /**
   * preload media items
   * @param arr media source urls array
   * @returns {Promise}
   */
  loadMedia (arr) {
    return new Promise(resolve => {
      if (Array.isArray(arr) && arr.length) {
        let len = arr.length
        let count = 0
        /* eslint-disable */
        arr.forEach(url => {
          loadImage(url, () => {
            count++
            if (len === count) resolve()
          })
        })
      } else {
        resolve()
      }
    })
  }

  /**
   * destroy
   * removeEventListener window resize
   */
  destroy () {
    window.removeEventListener("resize", this._resetClone)
  }
}

export default ZxWaterfall

demo: https://github.com/capricornc...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101879.html

相關(guān)文章

  • 原生js實(shí)現(xiàn)瀑布效果

    摘要:前言最近在整理基礎(chǔ)知識(shí),接觸到了幾個(gè)常用的頁面特效,其中覺得用原生實(shí)現(xiàn)瀑布流的案例十分有趣,于是與大家分享一下。瀑布流瀑布流,又稱瀑布流式布局。通過定位的方式是我們實(shí)現(xiàn)瀑布流的最基本的原理,只要我們動(dòng)態(tài)的設(shè)置它的值值,就能讓它排列。 showImg(https://segmentfault.com/img/remote/1460000012621941?w=1052&h=542); 前...

    wangdai 評(píng)論0 收藏0
  • 原生js實(shí)現(xiàn)瀑布及微信小程序中使用左右兩列實(shí)現(xiàn)瀑布

    摘要:使用實(shí)現(xiàn)瀑布流并不實(shí)用,因?yàn)閷?shí)現(xiàn)的瀑布流都是以列來排列的,這里記錄下用實(shí)現(xiàn)瀑布流,以及微信小程序中使用左右兩列來實(shí)現(xiàn)瀑布流效果圖原生實(shí)現(xiàn)瀑布流文件圖片可以自己找點(diǎn)替換下就可以了文件添加陰影的時(shí)候,加上會(huì)顯得更加有點(diǎn)懸浮感文件計(jì)算圖片列數(shù) 使用css實(shí)現(xiàn)瀑布流并不實(shí)用,因?yàn)閏ss實(shí)現(xiàn)的瀑布流都是以列來排列的,這里記錄下用js實(shí)現(xiàn)瀑布流,以及微信小程序中使用左右兩列來實(shí)現(xiàn)瀑布流 1.效果圖...

    imingyu 評(píng)論0 收藏0
  • 原生 js 實(shí)現(xiàn)面對(duì)對(duì)象版瀑布

    摘要:一一些閑話作為一個(gè)寫靜態(tài)的切圖仔,其實(shí)日常工作中根本用不上瀑布流這種小清新,畢竟?fàn)I銷頁面都是要求搶眼吸睛高大上文案爸爸說啥都對(duì)。昨上午閑著沒事看到別人寫的瀑布流的帖子,覺得很好玩的樣子,然后決定上午就寫一個(gè)試試。。。 一、一些閑話 作為一個(gè)寫靜態(tài)的切圖仔,其實(shí)日常工作中根本用不上瀑布流這種小清新,畢竟?fàn)I銷頁面都是要求 搶眼__、__吸睛__、 __高大上 (文案爸爸說啥都對(duì))。 昨上...

    tommego 評(píng)論0 收藏0
  • 原生 JS 實(shí)現(xiàn)一個(gè)瀑布插件

    摘要:瀑布流布局中的圖片有一個(gè)核心特點(diǎn)等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模的使用,比如花瓣網(wǎng)等等。那么接下來就基于這個(gè)特點(diǎn)開始瀑布流探索之旅。 showImg(https://segmentfault.com/img/remote/1460000013059759?w=640&h=280); 瀑布流布局中的圖片有一個(gè)核心特點(diǎn) —— 等寬不定等高,瀑布流布局在國內(nèi)網(wǎng)網(wǎng)站都有一定規(guī)模...

    Alfred 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<