主要是通过定位找到需要指引的目标元素,然后再在蒙版上画一个div,设置为白色,定位到目标元素位置。思路大概就是这样。
图一:

图二:

图三:

代码如下:

<!DOCTYPE html>
<html>
<head>
    < ></ >
    <  charset=\"utf-8\">
    <  rel=\"stylesheet\" href=\"https://unpkg.com/element-ui@1.4/lib/theme-default/index.css\">
    <  src=\"https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js\"></ >
    <  src=\"http://code.jquery.com/jquery-2.1.4.min.js\"></ >
    <  src=\"https://unpkg.com/element-ui@1.4/lib/index.js\"></ >
    <  src=\"https://cdn.jsdelivr.net/npm/vue-resource@1.5.0\"></ >
    <style>
        * {
            list-style: none;
            text-decoration: none;
            padding: 0;
            margin: 0;
        }
        .wrapper {
            width: 100%;
            height: 300px;
            background: #eef2f6;
        }
        .wrapper .arc {
            width: 250px;
            height: 250px;
            border-radius: 50%;
            background: #fff;
            transform: translate(25px, 25px);
            position: relative;
            margin-left: 100px;
            float: left;
        }
        .wrapper .content {
            width: 380px;
            height: 250px;
            float: left;
            background: #fff;
            border-radius: 4px;
            border: 1px solid #ccc;
            transform: translate(25px, 25px);
            position: relative;
        }
        .wrapper .content div{
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 100px;
            height: 100px;
            border-radius: 50%;
            background: #000;
        }

        .border_content {
            width: 100px;
            height: 50px;
            border: 3px dashed #000;
            border-radius: 5px;
        }

        .wrapper_mask {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            left: 0;
            background: #000;
            opacity: 0.6;
            z-index: 999;
        }

        .wrapper_mask .mask_content {
            border-radius: 5px;
            width: 100%;
            height: 100%;
            background: #fff;
        }
        .mask_content_border {
            position: absolute;
            border: 2px dashed #fff;
            border-radius: 10px;
            z-index: 9999;
            box-sizing: content-box;
            transition: all 0.2s linear;
            padding:6px;
        }

        .cloneBtn {
            position: relative;
            /*z-index: 99999;*/
            right: -384px;
            top: 10px;
        }
        .mask1 .mask_content_border .arrow1{
            position: relative;
            top: 20px;
            left: 248px;
        }
        .mask_button{
            position: absolute;
            bottom: 20%;
            left: 50%;
            cursor: pointer;
        }
        /*禁止body滚动*/
        .html-body-overflow
        {
            overflow-x:hidden;
            overflow-y:hidden;
        }
    </style>
</head>
<body>
<div id=\"app\">
    <div class=\"wrapper\">
        <div class=\"content\" ref=\"uploadReport\">
            <div></div>
        </div>
        <div class=\"arc\" ref=\"arc\"></div>
        <el-button class=\"cloneBtn\" @click=\"start\">操作指引</el-button>
    </div>

    <div class=\"wrapper_mask\" v-show=\"showMask\" ref=\"wrapper_mask\">
        <div class=\"mask1\" v-if=\"showMaskContent == \'mask1\'\">
            <div class=\"mask_content_border\" ref=\"maskBorder\">
                <div class=\"mask_content\" ref=\"maskContent\"></div>
                <div class=\"arrow1\">
                    <img src=\"./images/reportProject/arrow_1.png\">
                </div>
            </div>
        </div>
        <div class=\"mask2\" v-if=\"showMaskContent == \'mask2\'\">
            <div class=\"mask_content_border\"  v-for=\"(item,index) in showMask2Elems\"  :ref=\"\'mask2Border\'+index\">
                <div class=\"mask_content\" :ref=\"\'mask2Content\'+index\"></div>
            </div>
        </div>
        <div class=\"mask_button\" @click=\"nextMask()\">
            <img v-if=\"showMaskContent != \'mask2\'\" src=\"./images/reportProject/next_page_1.png\">
            <img v-if=\"showMaskContent == \'mask2\'\" src=\"./images/reportProject/close_btn.png\">
        </div>
    </div>

    <el-table :data=\"data\" border ref=\"table\" :height=\"tableHeight\" ref=\"table\" style=\"width: 100%\">
        <el-table-column type=\"selection\" width=\"55\"></el-table-column>
        <el-table-column label=\"日期\" width=\"120\">
            <template scope=\"scope\">{{ scope.row.date }}</template>
        </el-table-column>
        <el-table-column prop=\"name\" label=\"姓名\" width=\"120\"></el-table-column>
        <el-table-column prop=\"address\" label=\"地址\" show-overflow-tooltip></el-table-column>

        <el-table-column label=\"操作列\" show-overflow-tooltip>
            <template scope=\"scope\">
                <el-button size=\"small\" @click=\"handleEdit(scope.$index, scope.row)\"><i class=\" el-icon-edit\">编辑</i></el-button>
                <el-button size=\"small\" type=\"danger\" @click=\"handleDelete(scope.$index, scope.row)\">
                    <i class=\"el-icon-delete2\">删除</i>
                </el-button>
            </template>
        </el-table-column>
    </el-table>



</div>
</body>
<  type=\"text/ \">
    new Vue({
        el: \'#app\',
        data: {
            data: [
                {
                    date: \'2016-05-03\',
                    name: \'王小虎\',
                    address: \'上海市普陀区金沙江路 1518 弄\'
                }, {
                    date: \'2016-05-02\',
                    name: \'王小虎\',
                    address: \'上海市普陀区金沙江路 1518 弄\'
                }, {
                    date: \'2016-05-04\',
                    name: \'王小虎\',
                    address: \'上海市普陀区金沙江路 1518 弄\'
                }, {
                    date: \'2016-05-01\',
                    name: \'王小虎\',
                    address: \'上海市普陀区金沙江路 1518 弄\'
                }, {
                    date: \'2016-05-08\',
                    name: \'王小虎\',
                    address: \'上海市普陀区金沙江路 1518 弄\'
                }],
            tableHeight: 300,
            showMask: false,
            showMaskContent:\'\',
            showMask2Elems:[]
        },
        methods: {
            start:function(){
                this.showMask = true;
                //如果当前页面数据比较多,出现了滚动条的话,需要禁用滚动条
                $(document.body).addClass(\"html-body-overflow\");
                this.showMaskContent = \'mask1\';
                this.getShowElemStyle();
            },
            //获取要显示的元素
            getShowElemStyle:function(){
                if(this.showMaskContent == \'mask1\'){
                    var uploadReport = this.$refs.uploadReport;
                    //对DOM操作,需要在DOM挂载和渲染完成之后再进行,这是需要将所进行的操作放在$nextTick()中
                    this.$nextTick(function(){
                        this.setMaskContentStyle(this.$refs.maskContent,this.$refs.maskBorder,uploadReport);
                    });
                }
                if(this.showMaskContent == \'mask2\'){
                    var table = this.$refs.table;
                    var el_table__body = table.$el.querySelector(\'.el-table__body tr\');
                    var allTd = el_table__body.querySelectorAll(\'td\');
                    //需要显示的三个元素
                    var td1 = allTd[1];
                    var td2 = allTd[3];
                    var td3 = allTd[4].querySelectorAll(\'button\');
                    this.showMask2Elems.push(td1,td2,td3[0]);
                    this.$nextTick(function(){
                        for(var i=0;i<this.showMask2Elems.length;i++){
                            var param1 = this.$refs[\'mask2Content\'+i][0];
                            var param2 = this.$refs[\'mask2Border\'+i][0];
                            this.setMaskContentStyle(param1,param2,this.showMask2Elems[i]);
                        }
                    });
                }
            },
            //元素定位
            setMaskContentStyle:function(maskContent,maskBorder,targetEle){
                //getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。
                var contentRect = targetEle.getBoundingClientRect();
                var styles = [
                    { property: \'width\', distance: \'distance\'},
                    { property: \'height\', distance: \'distance\' },
                    { property: \'left\' },
                    { property: \'top\' }
                ];
                var paddingWidth = 12;
                for(var i=0;i<styles.length;i++){
                    var finalDistance = 0;
                    if(styles[i].distance){
                        finalDistance = contentRect[styles[i].property];
                    }else{
                        finalDistance = contentRect[styles[i].property] - paddingWidth/2-2;
                    }
                    maskBorder.style[styles[i].property] = finalDistance + \'px\';
                    var borderRadius = parseInt(this.getStyle(targetEle, \'borderRadius\')) ? this.getStyle(targetEle, \'borderRadius\') : \'4px\';
                    maskBorder.style.borderRadius = borderRadius;
                    maskContent.style.borderRadius = borderRadius;
                }
            },
            getStyle:function(el,attr){
                return el.currentStyle ? el.currentStyle[attr] : getComputedStyle(el,false)[attr];
            },
            //显示下一个mask
            nextMask:function(){
                if(this.showMaskContent == \'mask1\'){
                    this.showMaskContent = \'mask2\'
                }else if(this.showMaskContent == \'mask2\'){
                    this.showMask = false;
                    this.showMaskContent = \'mask1\';
                    //恢复滚动条
                    $(document.body).removeClass(\"html-body-overflow\");
                }
                this.getShowElemStyle();
            }
        }
    });
</ >
</html>

实现效果如图二、图三所示。

收藏 打印