头部置顶2.0

Posted shellingfordly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了头部置顶2.0相关的知识,希望对你有一定的参考价值。

由于之前的头部置顶1.0存在一些问题。当头部上方还需要置顶一些其他东西时,比如导出案件、筛选框、搜索框、标题等等时,之前的代码不够灵活,没有设置置顶的偏移量。当页面内打开抽屉重复利用table时,也会存在问题,由于外面的滚动已经让头部置顶了,打开抽屉时,table的head依然在,并且会遮挡数据。

因此重写了置顶的js代码,通过监听对应dom的滚动,而不是监听window。

// 判断是否出现滚动条
function hasScrolled(el: htmlElement, direction = \'vertical\') {
  if (direction === \'vertical\') {
    return el.scrollHeight > el.clientHeight;
  } else if (direction === \'horizontal\') {
    return el.scrollWidth > el.clientWidth;
  }
}

// 找到有滚动条的dom
function findScrollDom(el: HTMLElement) {
  if (!el) return null;
  const isScrolled = hasScrolled(el);
  if (isScrolled) {
    return el;
  }
  const pEl = el.parentElement;
  if (pEl) {
    return findScrollDom(pEl);
  } else {
    return null;
  }
}
function useListenerScroll() {
  const containerRef = ref();
  const isFixed = ref(false);
  const width = ref(\'100%\'); // 置顶容易的宽度
  const top = ref(\'51px\'); // 默认的定位高度,导航栏高度
  const titleHeight = ref(0); // head上放的title或其他操作的容器高度

  const initEvent = async () => {
    await nextTick();

    // 如果table组件为空,递归调用
    if (!containerRef.value) {
      initEvent();
      return;
    }
    
    // 找到滚动容器
    const scrollDom = findScrollDom(containerRef.value);
    if (scrollDom) {
      const titleDom = scrollDom.getElementsByClassName(\'table-title-content\');
      // 获取title内容高度
      if (titleDom[0]) titleHeight.value = titleDom[0].clientHeight;
      else titleHeight.value = 0;
      scrollDom.addEventListener(\'scroll\', listenerScroll);
      top.value = scrollDom.offsetTop + \'px\';
    }
  };

  function listenerScroll(event: any) {
    const $el = event.target;
    if ($el) {
      const scrollTop = $el.scrollTop;
      const fixedDom = $el.getElementsByClassName(\'table-content\');
      if (fixedDom.length) {
        const dom = fixedDom[0];
        const domTop = dom.offsetTop - titleHeight.value - 51;
        
        // 滚动高度大于设定高度时,置顶头部
        if (scrollTop > domTop) {
          isFixed.value = true;
        }
        if (scrollTop < domTop) {
          isFixed.value = false;
          width.value = dom.clientWidth + \'px\';
        }
      }
    }
  }

  return {
    top,
    width,
    isFixed,
    containerRef,
    initEvent,
  };
}
<template>
  <div ref="containerRef">
    <div :style="fixedHeaderStyle">
      <div class="table-title-content" v-if="$slots[\'w1-title\'] || title">
        <span v-if="title">{{ title }}</span>
        <slot name="title" />
      </div>
      <div>
        <a-table
          :pagination="false"
          v-bind="$attrs"
          :data-source="[]"
        >
          <template #[item]="data" v-for="item in Object.keys($slots)">
            <slot :name="item" v-bind="data" />
          </template>
        </a-table>
      </div>
    </div>
    <a-table
      class="table-content"
      v-bind="$attrs"
      :dataSource="dataSource"
      v-loading="loading"
    >
      <template #[item]="data" v-for="item in Object.keys($slots)">
        <slot :name="item" v-bind="data"> </slot>
      </template>
    </a-table>
  </div>
</template>

<script lang="ts">
  import { computed, defineComponent, onMounted } from \'vue\';
  import { isFunction } from \'/@/utils/is\';
  import useListenerScroll from \'./hooks/useListenerScroll\';

  export default defineComponent({
    props: {
      dataSource: {
        type: Array,
      },
      loading: {
        type: Boolean,
      },
      title: {
        type: String,
      },
    },
    setup(props) {
      const { isFixed, containerRef, initEvent, width, top } = useListenerScroll();
      const fixedHeaderStyle = computed(() => ({
        position: isFixed.value ? \'fixed\' : \'relative\',
        top: isFixed.value ? top.value : 0,
        zIndex: isFixed.value ? 19 : 0,
        width: width.value,
      }));

      onMounted(() => {
        initEvent();
      });

      return {
        isFixed,
        containerRef,
        fixedHeaderStyle,
      };
    },
  });
</script>

以上是关于头部置顶2.0的主要内容,如果未能解决你的问题,请参考以下文章

如何使用sublime代码片段快速输入PHP头部版本声明

[置顶] SAP Fiori 2.0中文版系列视频教程(中文首发)

Javascript----实现火箭按钮网页置顶

判断元素是否在可视区域内

关于sublime自动生成头部注释

python selenium +phantomjs 怎么样伪装头部