美文网首页IPTV机顶盒开发之不断爬坑
使用JavaScript实现Toast小组件

使用JavaScript实现Toast小组件

作者: jaimor | 来源:发表于2019-04-24 11:44 被阅读0次

    Toast的作用

    Toast在很多系统中都存在,特别是在一些后台系统和手机端特别常见。通常在后台系统中,Toast都是用来向用户报告状态、通知和小贴士的作用;而在手机端大多数是用来报告状态或者操作提示。
    现在几乎所有的前端UI框架都有Toast这中类似的组件,用法和展示基本相同。当然这不是本篇文章的重点,本篇文章的重点是使用JavaScript自己实现一个Toast。

    实现原理

    其实Toast的实现很简单。最简单的结构就是在body里边动态的添加一个div,而这个div内就是Toast组件的具体内容。至于这个div也就是这个Toast在哪里显示,以及显示的样式,就可以使用属性的形式向其内部传递,而内部就可以使用JavaScript代码进行设置,最后调用show方法展示即可。

    实现代码

    /**
     * 页面提示工具类Toast
     * 可在页面中显示一个可自动关闭的弹出层,用作提示作用
     * 具体可以传入的值,请查看类中的properties结构体
     * 用法:
        new EpgToast().show({
            content: "我是最简单用法"      //其他属性将使用默认值
        });
        new EpgToast().show({
            xPosition: "left",          //x轴位置
            yPosition: "center",
            isHTML: "yes",          //此属性可以打开插入HTML的接口
            content: "<i>我可以插入HTML</i>"
        });
        var toast = new EpgToast().show({
            duration: 0,                    //设置为0后,将不会主动关闭,需要调用close方法
            content: "我将不会主动关闭"
        });
        //toast.close();
     */
    var EpgToast = (function () {
        //横轴位置可选值
        var _XY_POSITION = {
            LEFT: "left",
            RIGHT: "right",
            CENTER: "center",
            TOP: "top",
            BOTTOM: "bottom"
        };
        //边框圆角类型可选值
        var _BORDER_RADIUS = {
            AUTO: "auto",           //根据toast高度改变边框圆角
            DISABLED: "disabled"    //关闭边框圆角
        };
        //横轴纵轴边距量px,不带单位
        var _XY = {
            x: 50, //横轴 左右距边框 50px
            y: 20  //纵轴 上下距边框 20px
        };
        //内容位置
        var _CONTENT_ALIGN = {
            LEFT: "left",
            CENTER: "center",
            RIGHT: "right"
        };
        //可以通过show方法改变默认值
        var _TDefault = {
            xyPosition: {
                x: _XY_POSITION.CENTER,
                y: _XY_POSITION.BOTTOM
            },
            xyOffset: {
                x: 0,
                y: 0
            },
            wh: {
                width: "auto",
                height: "auto"
            },
            padding: "10px 30px",
            fontSize: "24px",
            color: "white",
            bgColor: "rgba(150, 150, 150, 1)",
            borderRadius: _BORDER_RADIUS.AUTO,
            isHTML: false,
            duration: 3000,
            contentAlign: _CONTENT_ALIGN.CENTER,
            fade: {
                inTime: 1000,   //显示淡入的时间,单位毫秒,不带单位,默认1s
                outTime: 1000
            }
        };
    
        /**
         * 弹出提示信息
         */
        return function () {
            //默认使用_TDefault属性,可以从show方法中传入修改
            //具体填入的值的类型可以参照_TDefault
            var properties = {
                xPosition: _TDefault.xyPosition.x,  //横轴位置,具体查看_XY_POSITION
                yPosition: _TDefault.xyPosition.y,  //纵轴位置
                xOffset: _TDefault.xyOffset.x,      //横轴偏移量,不带单位。具体查看_XY
                yOffset: _TDefault.xyOffset.y,      //同上
                width: _TDefault.wh.width,          //toast宽度
                height: _TDefault.wh.height,        //高度
                padding: _TDefault.padding,         //内边距
                fontSize: _TDefault.fontSize,       //字体大小
                color: _TDefault.color,             //字体颜色
                bgColor: _TDefault.bgColor,         //背景色
                borderRadius: _TDefault.borderRadius,//边框圆角,或者直接设置为固定值 "20px"
                duration: _TDefault.duration,       //可以显示几秒中,传入毫秒,不带单位
                isHTML: _TDefault.isHTML,           //是否开启插入HTML模式
                content: " ",                       //内容
                contentAlign: _TDefault.contentAlign,//内容位置
                fadeInTime: _TDefault.fade.inTime,  //显示淡入的时间,单位毫秒,不带单位
                fadeOutTime: _TDefault.fade.outTime
            };
            var _div = document.createElement("div");
            /**
             * 提供的显示方法
             * @param initObj
             */
            this.show = function (initObj) {
                init(initObj);
                initDiv();
                setContent();
                showing();
                showed();
                return this;
            };
            /**
             * 提供的关闭方法
             */
            this.close = function () {   //手动关闭
                _div.style.opacity = "0";
                var fadeOutTime = properties.fadeOutTime < 0 ? 0 : properties.fadeOutTime;
                setTimeout(function () {
                    if (_div) _div.parentNode.removeChild(_div);
                }, fadeOutTime)
            };
            var close = function () {  //自动关闭
                if (properties.duration > 0) {
                    var fadeOutTime = properties.fadeOutTime < 0 ? 0 : properties.fadeOutTime;
                    setTimeout(function () {
                        _div.style.opacity = "0";
                        setTimeout(function () {
                            if (_div) _div.parentNode.removeChild(_div);
                        }, fadeOutTime);
                    }, properties.duration);
                }
            };
            var init = function (initObj) {
                for (var key in initObj) (key in properties) && (properties[key] = initObj[key]);
            };
            var initDiv = function () {
                _div.style.position = "absolute";
                _div.style.display = "flex";
                _div.style.backgroundColor = properties.bgColor;
                _div.style.color = properties.color;
                _div.style.width = properties.width;
                _div.style.height = properties.height;
                _div.style.padding = properties.padding;
                _div.style.fontSize = properties.fontSize;
                _div.style.transition = "opacity " + (properties.fadeInTime < 0 ? 0 : properties.fadeInTime / 1000) + "s";
                _div.style.opacity = "0";
            };
            var setContent = function () {
                if (properties.isHTML) {
                    _div.innerHTML = properties.content;
                } else {
                    _div.innerText = properties.content;
                }
            };
            var setPosition = function () {
                _div.style.left = computedPosition("horizontal");
                _div.style.top = computedPosition("vertical");
                // if (properties.xOffset !== _TDefault.xyOffset.x) {
                _div.style.left = _div.offsetLeft + properties.xOffset + "px";
                // }
                // if (properties.yOffset !== _TDefault.xyOffset.y) {
                _div.style.top = _div.offsetTop + properties.yOffset + "px";
                // }
            };
            var showing = function () {
                document.body.appendChild(_div);
                if (properties.borderRadius === _BORDER_RADIUS.DISABLED) {
                    _div.style.borderRadius = "0";
                } else if (properties.borderRadius === _BORDER_RADIUS.AUTO) {
                    var h = _div.offsetHeight;
                    _div.style.borderRadius = h + "px";
                } else {
                    _div.style.borderRadius = properties.borderRadius;
                }
                var regx = /<img\s+/ig;
                var imgTags = properties.content.match(regx);
                if (imgTags && imgTags.length > 0) {
                    var imgs = _div.getElementsByTagName("img");
                    var counter = 0;
                    for (var i = 0, len = imgs.length; i < len; i++) {
                        (function (i) {
                            imgs[i].onload = function () {
                                counter++;
                                if (counter === len) {
                                    setPosition();
                                    _div.style.opacity = "1";
                                }
                            }
                        })(i);
                    }
                } else {
                    setPosition();
                    _div.style.opacity = "1";
                }
            };
            var showed = function () {
                close();
            };
            var computedPosition = function (type) {
                var xy = "0px";
                if (type === "horizontal") {
                    var t = [_XY_POSITION.LEFT, _XY_POSITION.CENTER, _XY_POSITION.RIGHT];
                    switch (t.indexOf(properties.xPosition)) {
                        case 0:
                            //表示居左
                            xy = _XY.x + "px";
                            break;
                        case 1:
                            xy = (document.documentElement.clientWidth - _div.offsetWidth) / 2 + "px";
                            break;
                        case 2:
                            xy = document.documentElement.clientWidth - _XY.x - _div.offsetWidth + "px";
                            break;
                        default:
                            xy = properties.xPosition;
                    }
                } else if (type === "vertical") {
                    var t = [_XY_POSITION.TOP, _XY_POSITION.CENTER, _XY_POSITION.BOTTOM];
                    switch (t.indexOf(properties.yPosition)) {
                        case 0:
                            //表示居上
                            xy = _XY.y + "px";
                            break;
                        case 1:
                            xy = (document.documentElement.clientHeight - _div.offsetHeight) / 2 + "px";
                            break;
                        case 2:
                            xy = document.documentElement.clientHeight - _XY.y - _div.offsetHeight + "px";
                            break;
                        default:
                            xy = properties.yPosition;
                    }
                }
                return xy;
            }
        }
    })();
    

    使用方式

    var t = new EpgToast().show({
        duration: 0,
        bgColor: "rgba(0,0,0,0)",
        xPosition: "left",
        yOffset: -100,
        isHTML: true,
        content: "<img src='./2.png'/>"
    });
    setTimeout("t.close()", 3000);
    new EpgToast().show({
        xPosition: "left",
        borderRadius: "disabled",
        content: "我没有border-radius"
    });
    new EpgToast().show({
        yPosition: "top",
        duration: 0,
        content: "我不会自动关闭"
    });
    new EpgToast().show({
        xPosition: "left",
        yPosition: "center",
        isHTML: "yes",
        content: "<i>我可以插入HTML</i>"
    });
    new EpgToast().show({
        yPosition: "center",
        width: "200px",
        content: "加载中,请稍等...",
        bgColor: "black",
        duration: 0,
        borderRadius: "5px"
    });
    new EpgToast().show({
        duration: 5000,
        bgColor: "red",
        xPosition: "right",
        width: "200px",
        content: "加载中,请稍等...",
        borderRadius: "5px",
        fadeInTime: 0,
        fadeOutTime: 0
    });
    new EpgToast().show({
        content: "我是最简单用法"
    })
    

    最终效果

    Toast效果图

    相关文章

      网友评论

        本文标题:使用JavaScript实现Toast小组件

        本文链接:https://www.haomeiwen.com/subject/oncwgqtx.html