当前位置: 首页 > 工具软件 > ScrollTo > 使用案例 >

vue项目引入vue-scrollTo

欧照
2023-12-01

vue项目引入vue-scrollTo插件的完整步骤:

使用npm安装则如下:
1、安装vue-scrollto

npm install --save vue-scrollto

2、项目根目录src文件夹下创建scroll文件夹(文件夹名字自定义,我习惯创建名为scroll),并在scroll文件夹内部创建scrollTo.js(该js文件名自定义,我习惯创建名为scrollTo.js,方便理解),将下面的js复制并粘贴到scrollTo.js中

import BezierEasing from "bezier-easing";
import easings from "./easings";
import _ from "./utils";

const abortEvents = [
    "mousedown",
    "wheel",
    "DOMMouseScroll",
    "mousewheel",
    "keyup",
    "touchmove"
];

let defaults = {
    container: "body",
    duration: 500,
    easing: "ease",
    offset: 0,
    force: true,
    cancelable: true,
    onStart: false,
    onDone: false,
    onCancel: false,
    x: false,
    y: true
};

export function setDefaults(options) {

    defaults = Object.assign({}, defaults, options);
}

export const scroller = () => {
    let element; // element to scroll to
    let container; // container to scroll
    let duration; // duration of the scrolling
    let easing; // easing to be used when scrolling
    let offset; // offset to be added (subtracted)
    let force; // force scroll, even if element is visible
    let cancelable; // indicates if user can cancel the scroll or not.
    let onStart; // callback when scrolling is started
    let onDone; // callback when scrolling is done
    let onCancel; // callback when scrolling is canceled / aborted
    let x; // scroll on x axis
    let y; // scroll on y axis

    let initialX; // initial X of container
    let targetX; // target X of container
    let initialY; // initial Y of container
    let targetY; // target Y of container
    let diffX; // difference
    let diffY; // difference

    let abort; // is scrolling aborted

    let abortEv; // event that aborted scrolling
    let abortFn = e => {
        if (!cancelable) return;
        abortEv = e;
        abort = true;
    };
    let easingFn;

    let timeStart; // time when scrolling started
    let timeElapsed; // time elapsed since scrolling started

    let progress; // progress

    function scrollTop(container) {
        let scrollTop = container.scrollTop;

        if (container.tagName.toLowerCase() === "body") {
            // in firefox body.scrollTop always returns 0
            // thus if we are trying to get scrollTop on a body tag
            // we need to get it from the documentElement
            scrollTop = scrollTop || document.documentElement.scrollTop;
        }

        return scrollTop;
    }

    function scrollLeft(container) {
        let scrollLeft = container.scrollLeft;

        if (container.tagName.toLowerCase() === "body") {
            // in firefox body.scrollLeft always returns 0
            // thus if we are trying to get scrollLeft on a body tag
            // we need to get it from the documentElement
            scrollLeft = scrollLeft || document.documentElement.scrollLeft;
        }

        return scrollLeft;
    }

    function step(timestamp) {
        if (abort) return done();
        if (!timeStart) timeStart = timestamp;
        timeElapsed = timestamp - timeStart;

        progress = Math.min(timeElapsed / duration, 1);
        progress = easingFn(progress);

        topLeft(
            container,
            initialY + diffY * progress,
            initialX + diffX * progress
        );

        timeElapsed < duration ? window.requestAnimationFrame(step) : done();
    }

    function done() {
        if (!abort) topLeft(container, targetY, targetX);
        timeStart = false;

        _.off(container, abortEvents, abortFn);
        if (abort && onCancel) onCancel(abortEv, element);
        if (!abort && onDone) onDone(element);
    }

    function topLeft(element, top, left) {
        if (y) element.scrollTop = top;
        if (x) element.scrollLeft = left;
        if (element.tagName.toLowerCase() === "body") {
            // in firefox body.scrollTop doesn't scroll the page
            // thus if we are trying to scrollTop on a body tag
            // we need to scroll on the documentElement
            if (y) document.documentElement.scrollTop = top;
            if (x) document.documentElement.scrollLeft = left;
        }
    }

    function scrollTo(target, _duration, options = {}) {
        if (typeof _duration === "object") {
            options = _duration;
        } else if (typeof _duration === "number") {
            options.duration = _duration;
        }

        element = _.$(target);

        if (!element) {
            return console.warn(
                "[vue-scrollto warn]: Trying to scroll to an element that is not on the page: " +
                    target
            );
        }

        container = _.$(options.container || defaults.container);
        duration = options.duration || defaults.duration;
        easing = options.easing || defaults.easing;
        offset = options.offset || defaults.offset;
        offset = offset - 60
        force = options.hasOwnProperty("force")
            ? options.force !== false
            : defaults.force;
        cancelable = options.hasOwnProperty("cancelable")
            ? options.cancelable !== false
            : defaults.cancelable;
        onStart = options.onStart || defaults.onStart;
        onDone = options.onDone || defaults.onDone;
        onCancel = options.onCancel || defaults.onCancel;
        x = options.x === undefined ? defaults.x : options.x;
        y = options.y === undefined ? defaults.y : options.y;

        var cumulativeOffsetContainer = _.cumulativeOffset(container);
        var cumulativeOffsetElement = _.cumulativeOffset(element);

        if (typeof offset === "function") {
            offset = offset();
        }

        initialY = scrollTop(container);
        targetY = cumulativeOffsetElement.top -
            cumulativeOffsetContainer.top +
            offset;

        initialX = scrollLeft(container);
        targetX = cumulativeOffsetElement.left -
            cumulativeOffsetContainer.left +
            offset;

        abort = false;

        diffY = targetY - initialY;
        diffX = targetX - initialX;

        if (!force) {
            const containerTop = initialY;
            const containerBottom = containerTop + container.offsetHeight;
            const elementTop = targetY;
            const elementBottom = elementTop + element.offsetHeight;
            if (elementTop >= containerTop && elementBottom <= containerBottom) {
                return;
            }
        }

        if (typeof easing === "string") {
            easing = easings[easing] || easings["ease"];
        }

        easingFn = BezierEasing.apply(BezierEasing, easing);

        if (!diffY && !diffX) return;
        if (onStart) onStart(element);

        _.on(container, abortEvents, abortFn, { passive: true });

        window.requestAnimationFrame(step);

        return () => {
            abortEv = null;
            abort = true;
        };
    }

    return scrollTo;
};

const _scroller = scroller();
export default _scroller;

并在当前文件夹内部创建easings.js,(这个文件在scrollTo.js中引入,可查看上面的代码示例)

export default {
    ease: [0.25, 0.1, 0.25, 1.0],
    linear: [0.00, 0.0, 1.00, 1.0],
    "ease-in": [0.42, 0.0, 1.00, 1.0],
    "ease-out": [0.00, 0.0, 0.58, 1.0],
    "ease-in-out": [0.42, 0.0, 0.58, 1.0]
};

以及创建utils.js,(这个文件在scrollTo.js中引入,可查看上面的代码示例)

// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection
let supportsPassive = false;
try {
    let opts = Object.defineProperty({}, "passive", {
        get: function() {
            supportsPassive = true;
        }
    });
    window.addEventListener("test", null, opts);
} catch (e) {}

export default {
    $(selector) {
        if (typeof selector !== "string") {
            return selector;
        }
        return document.querySelector(selector);
    },
    on(element, events, handler, opts = { passive: false }) {
        if (!(events instanceof Array)) {
            events = [events];
        }
        for (let i = 0; i < events.length; i++) {
            element.addEventListener(
                events[i],
                handler,
                supportsPassive ? opts : false
            );
        }
    },
    off(element, events, handler) {
        if (!(events instanceof Array)) {
            events = [events];
        }
        for (let i = 0; i < events.length; i++) {
            element.removeEventListener(events[i], handler);
        }
    },
    cumulativeOffset(element) {
        let top = 0;
        let left = 0;

        do {
            top += element.offsetTop || 0;
            left += element.offsetLeft || 0;
            element = element.offsetParent;
        } while (element);

        return {
            top: top,
            left: left
        };
    }
};

3、将scrollTo.js引入到main.js中

//因为scrollTo是一个方法所以要用{}包裹
import {scroller} from '@/scroll/scrollTo.js'

4、将scrollTo这个方法挂载到vue原型上,全局可用

//把scrollTo挂载到vue原型上,想用就用(为什么叫$scrollTo,这个是自定义的,喜欢叫什么就定义什么,本人出于自己的习惯喜欢加个$+方法名)
Vue.prototype.$scrollTo = scroller()

5、在页面的使用方法

//下面简单说一下用法,直接使用this.$scrollTo('id+dom元素的id名字');就可以实现类似于锚点的点击效果,点击导航并滚动到某个位置
//这是一个点击事件的回调
handleClick() {
   this.$scrollTo('#condition');
}

 类似资料: