實現用戶操作指引功能

来源:https://www.cnblogs.com/fangnianqin/archive/2018/11/05/9909040.html
-Advertisement-
Play Games

主要是通過定位找到需要指引的目標元素,然後再在蒙版上畫一個div,設置為白色,定位到目標元素位置。思路大概就是這樣。 圖一: 圖二: 圖三: 代碼如下: 實現效果如圖二、圖三所示。 ...


主要是通過定位找到需要指引的目標元素,然後再在蒙版上畫一個div,設置為白色,定位到目標元素位置。思路大概就是這樣。
圖一:

圖二:

圖三:

代碼如下:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/lib/theme-default/index.css">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://unpkg.com/[email protected]/lib/index.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
    <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>
<script type="text/javascript">
    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();
            }
        }
    });
</script>
</html>

實現效果如圖二、圖三所示。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 表格: 表格由 <table> 標簽來定義。每個表格均有若幹行(由 <tr> 標簽定義),每行被分割為若幹單元格(由 <td> 標簽定義)。字母 td 指表格數據(table data),即數據單元格的內容。數據單元格可以包含文本、圖片、列表、段落、表單、水平線、表格等等。border是邊框屬性。 ...
  • 使用div構造簡單的信息圖片 html: <!DOCTYPE html><html><head><meta charset="utf-8"><title>zhwTest</title><link rel="stylesheet" href="../css/zhwCommon.css"></head> ...
  • $.ajax({ url: '../Handler.ashx?action=GetsyxhByIdCardAndxtbz',//指向處理地址 type: 'POST',//get post兩種 data: { xyxh: syxh, xtbz: xtbz },//傳遞方法的參數,以{參數名:參數值; ...
  • 實現一個日期組件,如圖: components.js代碼如下: ...
  • 第一章 的介紹 1.CSS:“層疊樣式表”,它是cascading style sheets的縮寫,作用就是給HTML標簽加表現形式(樣式-顯示),如:字體,圖片,列表,位置等。 在瀏覽器中可以看到部分: HTML:“超文本標記語言”,主要作用把內容(文字、圖片、視頻等)放入網頁中--結構 CSS: ...
  • 列表有三種類型: 有序列表:列表項使用數字來標記 無序列表:列表項使用粗體圓點(典型的小黑圓圈)進行標記。 自定義列表:自定義列表以 <dl> 標簽開始。每個自定義列表項以 <dt> 開始。每個自定義列表項的定義以 <dd> 開始。 一、有序列表格式: 運行結果: 不同類型的有序列表: 1.編號列表 ...
  • 用css畫一個如下圖的提示框: 代碼如下: ...
  • 一 概述 JavaScript數組同後端語言一樣,具有它自己的數據結構,歸根結底,這種數據結構,本質就是一種集合。 在後端語言中(如java,.net等),數組是這樣定義的:數組是用來存儲相同數據類型的集合。這個定義,“相同數據類型”6個字限制了數據只能存儲相同的數據類型,如int[]數組只能存儲數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...