120 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
import { w as withInstall } from "../badge/index2.js";
 | 
						|
import { defineComponent, ref, computed, onMounted, nextTick, onUnmounted, openBlock, createElementBlock, normalizeStyle, unref, renderSlot } from "vue";
 | 
						|
var index = /* @__PURE__ */ (() => ".layui-affix{display:block;z-index:999;transition:all .3s ease-in-out}\n")();
 | 
						|
const __default__ = {
 | 
						|
  name: "LayAffix"
 | 
						|
};
 | 
						|
const _sfc_main = defineComponent({
 | 
						|
  ...__default__,
 | 
						|
  props: {
 | 
						|
    offset: { default: 0 },
 | 
						|
    target: { default: () => {
 | 
						|
      return document.body;
 | 
						|
    } },
 | 
						|
    position: { default: "top" }
 | 
						|
  },
 | 
						|
  emits: ["scroll"],
 | 
						|
  setup(__props, { emit }) {
 | 
						|
    const props = __props;
 | 
						|
    const outWindow = ref(false);
 | 
						|
    const dom = ref();
 | 
						|
    let changeScrollTop = 0;
 | 
						|
    let orginOffsetLeft = 0;
 | 
						|
    let marginLeft = 0;
 | 
						|
    let marginTop = 0;
 | 
						|
    let marginBottom = 0;
 | 
						|
    let fixedOffset = 0;
 | 
						|
    const getStyle = computed(() => {
 | 
						|
      if (outWindow.value && dom.value) {
 | 
						|
        let style = {
 | 
						|
          position: "fixed !important",
 | 
						|
          top: "unset",
 | 
						|
          bottom: "unset",
 | 
						|
          left: orginOffsetLeft - marginLeft + "px"
 | 
						|
        };
 | 
						|
        if (props.position === "top") {
 | 
						|
          style.top = fixedOffset - marginTop + "px";
 | 
						|
        } else {
 | 
						|
          style.bottom = fixedOffset - marginBottom + "px";
 | 
						|
        }
 | 
						|
        return style;
 | 
						|
      }
 | 
						|
    });
 | 
						|
    const checkInWindow = () => {
 | 
						|
      var _a;
 | 
						|
      if (dom.value) {
 | 
						|
        let offsetTop = dom.value.offsetTop;
 | 
						|
        let scrollTop = (_a = props.target) == null ? void 0 : _a.scrollTop;
 | 
						|
        if (props.position === "top") {
 | 
						|
          let result = offsetTop - scrollTop + props.target.offsetTop;
 | 
						|
          if (result < fixedOffset) {
 | 
						|
            if (outWindow.value) {
 | 
						|
              if (scrollTop <= changeScrollTop) {
 | 
						|
                outWindow.value = false;
 | 
						|
              }
 | 
						|
            } else {
 | 
						|
              changeScrollTop = scrollTop;
 | 
						|
              outWindow.value = true;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          let viewHeight = props.target.offsetHeight > window.innerHeight ? window.innerHeight : props.target.offsetHeight;
 | 
						|
          let result = viewHeight + scrollTop - offsetTop - dom.value.offsetHeight;
 | 
						|
          if (outWindow.value) {
 | 
						|
            if (scrollTop >= changeScrollTop) {
 | 
						|
              outWindow.value = false;
 | 
						|
            }
 | 
						|
          } else {
 | 
						|
            if (result < fixedOffset) {
 | 
						|
              changeScrollTop = scrollTop - result + props.offset;
 | 
						|
              outWindow.value = true;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
        emit("scroll", {
 | 
						|
          targetScroll: scrollTop,
 | 
						|
          affixed: outWindow.value,
 | 
						|
          offset: !outWindow.value ? 0 : Math.abs(scrollTop - changeScrollTop)
 | 
						|
        });
 | 
						|
      }
 | 
						|
    };
 | 
						|
    const getDomStyle = (dom2, attr) => {
 | 
						|
      if (dom2.currentStyle) {
 | 
						|
        return dom2.currentStyle[attr];
 | 
						|
      } else {
 | 
						|
        return document.defaultView.getComputedStyle(dom2, null)[attr];
 | 
						|
      }
 | 
						|
    };
 | 
						|
    onMounted(() => {
 | 
						|
      nextTick(() => {
 | 
						|
        dom.value.offsetTop - props.target.offsetTop;
 | 
						|
        orginOffsetLeft = dom.value.getBoundingClientRect().left;
 | 
						|
        marginLeft = parseFloat(getDomStyle(dom.value, "marginLeft"));
 | 
						|
        marginTop = parseFloat(getDomStyle(dom.value, "marginTop"));
 | 
						|
        marginBottom = parseFloat(getDomStyle(dom.value, "marginBottom"));
 | 
						|
        fixedOffset = props.offset + props.target.offsetTop;
 | 
						|
        if (props.position === "bottom") {
 | 
						|
          fixedOffset = props.offset;
 | 
						|
        }
 | 
						|
        props.target.addEventListener("scroll", checkInWindow, true);
 | 
						|
        checkInWindow();
 | 
						|
      });
 | 
						|
    });
 | 
						|
    onUnmounted(() => {
 | 
						|
      props.target.removeEventListener("scroll", checkInWindow);
 | 
						|
    });
 | 
						|
    return (_ctx, _cache) => {
 | 
						|
      return openBlock(), createElementBlock("div", {
 | 
						|
        class: "layui-affix",
 | 
						|
        style: normalizeStyle(unref(getStyle)),
 | 
						|
        ref_key: "dom",
 | 
						|
        ref: dom
 | 
						|
      }, [
 | 
						|
        renderSlot(_ctx.$slots, "default")
 | 
						|
      ], 4);
 | 
						|
    };
 | 
						|
  }
 | 
						|
});
 | 
						|
const component = withInstall(_sfc_main);
 | 
						|
export { component as default };
 |