作過web項目開發的人對layer彈層組件確定不陌生,做爲layUI的一個重要組件,使用簡單、接口參數豐富,功能健壯,深受廣大開發者的喜好,做爲一個熱(經)愛(常)工(劃)做(水),喜歡鑽研探索技術的程序員(狗),咱們本身來實現一個web彈窗/層,一窺layer的本源(/手動滑稽臉),進步,從模仿開始。css
首先,模仿layer的部分功能,咱們先肯定下咱們要實現的功能:html
msgjquery
一、居中彈出、延時銷燬、自適應寬高、支持參數配置程序員
dialogweb
一、可拖動數組
二、可最小化、最大化、關閉瀏覽器
三、右下角可對窗口進行縮放app
四、支持多個參數配置、擴展dom
大部分的思路都在代碼註釋裏post
css樣式
/* web彈窗 */ .tip-msg { background-color: rgba(61, 61, 61, 0.93); color: #ffffff; opacity: 0; max-width: 200px; position: fixed; text-align: center; line-height: 25px; border-radius: 30px; padding: 5px 15px; display: inline-block; } .tip-shade { z-index: 9999; background-color: rgb(0, 0, 0); opacity: 0.6; position: fixed; top: 0; left: 0; width: 100%; height: 100%; } .tip-dialog { z-index: 10000; position: fixed; display: block; background: #e9e9e9; border-radius: 5px; opacity: 0; border: 1px solid #dad8d8; box-shadow: 0px 1px 20px 2px rgb(255, 221, 221); } .tip-title { cursor: move; padding: 5px; position: relative; height: 25px; border-bottom: 1px solid #dad8d8; user-select: none; } .tip-title-text { margin: 0; padding: 0; font-size: 15px; } .tip-title-btn { position: absolute; top: 5px; right: 5px; } .tip-content { padding: 8px; position: relative; word-break: break-all; font-size: 14px; overflow-x: hidden; overflow-y: auto; } .tip-resize { position: absolute; width: 15px; height: 15px; right: 0; bottom: 0; cursor: se-resize; }
js
/** * 自定義web彈窗/層:簡易風格的msg與可拖放的dialog * 依賴jquery * 做者:https://www.cnblogs.com/huanzi-qch/ * 出處:https://www.cnblogs.com/huanzi-qch/p/10082116.html */ var tip = { /** * 初始化 */ init: function () { var titleDiv = null;//標題元素 var dialogDiv = null;//窗口元素 var titleDown = false;//是否在標題元素按下鼠標 var resizeDown = false;//是否在縮放元素按下鼠標 var offset = {x: 0, y: 0};//鼠標按下時的座標系/計算後的座標 /* 使用 on() 方法添加的事件處理程序適用於當前及將來的元素(好比由腳本建立的新元素)。 問題:事件綁定在div上出現div移動速度跟不上鼠標速度,致使鼠標移動太快時會脫離div,從而沒法觸發事件。 解決:把事件綁定在document文檔上,不管鼠標在怎麼移動,始終是在文檔範圍以內。 */ //鼠標在標題元素按下 $(document).on("mousedown", ".tip-title", function (e) { var event1 = e || window.event; titleDiv = $(this); dialogDiv = titleDiv.parent(); titleDown = true; offset.x = e.clientX - parseFloat(dialogDiv.css("left")); offset.y = e.clientY - parseFloat(dialogDiv.css("top")); }); //鼠標移動 $(document).on("mousemove", function (e) { var event2 = e || window.event; var eveX = event2.clientX; // 獲取鼠標相對於瀏覽器x軸的位置 var eveY = event2.clientY; // 獲取鼠標相對於瀏覽器Y軸的位置 // var height = document.body.clientHeight;//表示HTML文檔所在窗口的當前高度; // var width = document.body.clientWidth;//表示HTML文檔所在窗口的當前寬度; var height = window.innerHeight;//瀏覽器窗口的內部高度; var width = window.innerWidth;//瀏覽器窗口的內部寬度; //在標題元素按下 if (titleDown) { //處理滾動條 if (tip.hasXScrollbar()) { height = height - tip.getScrollbarWidth(); } if (tip.hasYScrollbar()) { width = width - tip.getScrollbarWidth(); } //上邊 var top = (eveY - offset.y); if (top <= 0) { top = 0; } if (top >= (height - dialogDiv.height())) { top = height - dialogDiv.height() - 5; } //左邊 var left = (eveX - offset.x); if (left <= 0) { left = 0; } if (left >= (width - dialogDiv.width())) { left = width - dialogDiv.width() - 5; } dialogDiv.css({ "top": top + "px", "left": left + "px" }); } //在縮放元素按下 if (resizeDown) { //避免undefined.XXX報錯 dialogDiv[0].resize = dialogDiv[0].resize ? dialogDiv[0].resize : {}; var newWidth = (dialogDiv[0].resize.width + (eveX - offset.x)); if (dialogDiv[0].resize.initWidth >= newWidth) { newWidth = dialogDiv[0].resize.initWidth; } var newHeight = (dialogDiv[0].resize.height + (eveY - offset.y)); if (dialogDiv[0].resize.initHeight >= newHeight) { newHeight = dialogDiv[0].resize.initHeight; } dialogDiv.css("width", newWidth + "px"); dialogDiv.find(".tip-content").css("height", newHeight + "px"); } }); //鼠標彈起 $(document).on("mouseup", function (e) { //清空對象 titleDown = false; resizeDown = false; titleDiv = null; dialogDiv = null; offset = {x: 0, y: 0}; }); //阻止按鈕事件冒泡 $(document).on("mousedown", ".tip-title-min,.tip-title-max,.tip-title-close", function (e) { e.stopPropagation();//阻止事件冒泡 }); //最小化 $(document).on("click", ".tip-title-min", function (e) { // var height = document.body.clientHeight;//表示HTML文檔所在窗口的當前高度; // var width = document.body.clientWidth;//表示HTML文檔所在窗口的當前寬度; var height = window.innerHeight;//瀏覽器窗口的內部高度; var width = window.innerWidth;//瀏覽器窗口的內部寬度; var $parent = $(this).parents(".tip-dialog"); //顯示瀏覽器滾動條 document.body.parentNode.style.overflowY = "auto"; //當前是否爲最大化 if ($parent[0].isMax) { $parent[0].isMax = false; $parent.css({ "top": $parent[0].topMin, "left": $parent[0].leftMin, "height": $parent[0].heightMin, "width": $parent[0].widthMin }); } //當前是否爲最小化 if (!$parent[0].isMin) { $parent[0].isMin = true; $parent[0].bottomMin = $parent.css("bottom"); $parent[0].leftMin = $parent.css("left"); $parent[0].heightMin = $parent.css("height"); $parent[0].widthMin = $parent.css("width"); $parent.css({ "top": "", "bottom": "5px", "left": 0, "height": "30px", "width": "95px" }); $parent.find(".tip-title-text").css("display", "none"); $parent.find(".tip-content").css("display", "none"); } else { $parent[0].isMin = false; $parent.css({ "top": $parent[0].topMin, "bottom": $parent[0].bottomMin, "left": $parent[0].leftMin, "height": $parent[0].heightMin, "width": $parent[0].widthMin }); $parent.find(".tip-title-text").css("display", "block"); $parent.find(".tip-content").css("display", "block"); } }); //最大化 $(document).on("click", ".tip-title-max", function (e) { // var height = document.body.clientHeight;//表示HTML文檔所在窗口的當前高度; // var width = document.body.clientWidth;//表示HTML文檔所在窗口的當前寬度; var height = window.innerHeight;//瀏覽器窗口的內部高度; var width = window.innerWidth;//瀏覽器窗口的內部寬度; var $parent = $(this).parents(".tip-dialog"); //當前是否爲最小化 if ($parent[0].isMin) { $parent[0].isMin = false; $parent.css({ "top": $parent[0].topMin, "bottom": $parent[0].bottomMin, "left": $parent[0].leftMin, "height": $parent[0].heightMin, "width": $parent[0].widthMin }); $parent.find(".tip-title h2").css("display", "block"); } //當前是否爲最大化 if (!$parent[0].isMax) { //隱藏瀏覽器滾動條 document.body.parentNode.style.overflowY = "hidden"; $parent[0].isMax = true; $parent[0].topMin = $parent.css("top"); $parent[0].leftMin = $parent.css("left"); $parent[0].heightMin = $parent.css("height"); $parent[0].widthMin = $parent.css("width"); $parent.css({ "top": 0, "left": 0, "height": height - 5 + "px", "width": width - 5 + "px" }); } else { //顯示瀏覽器滾動條 document.body.parentNode.style.overflowY = "auto"; $parent[0].isMax = false; $parent.css({ "top": $parent[0].topMin, "left": $parent[0].leftMin, "height": $parent[0].heightMin, "width": $parent[0].widthMin }); } }); //縮放 $(document).on("mousedown", ".tip-resize", function (e) { var event1 = e || window.event; dialogDiv = $(this).parent(); resizeDown = true; offset.x = e.clientX; offset.y = e.clientY; //點擊時的寬高 dialogDiv[0].resize.width = dialogDiv.width(); dialogDiv[0].resize.height = dialogDiv.find(".tip-content").height(); }); //關閉 $(document).on("click", ".tip-title-close", function (e) { $(this).parents(".tip-dialog").parent().remove(); //顯示瀏覽器滾動條 document.body.parentNode.style.overflowY = "auto"; }); //點擊窗口優先顯示 $(document).on("click", ".tip-dialog", function (e) { $(".tip-dialog").css("z-index","9999"); $(this).css("z-index","10000"); }); }, /** * 是否存在X軸方向滾動條 */ hasXScrollbar: function () { return document.body.scrollWidth > (window.innerWidth || document.documentElement.clientWidth); }, /** * 是否存在Y軸方向滾動條 */ hasYScrollbar: function () { return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight); }, /** * 計算滾動條的寬度 */ getScrollbarWidth: function () { /* 思路:生成一個帶滾動條的div,分析獲得滾動條長度,而後過河拆橋 */ var scrollDiv = document.createElement("div"); scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'; document.body.appendChild(scrollDiv); var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth; document.body.removeChild(scrollDiv); return scrollbarWidth; }, /** * tip提示 * tip.msg("哈哈哈哈哈"); * tip.msg({text:"哈哈哈哈哈",time:5000}); */ msg: function (setting) { var time = setting.time || 2000; // 顯示時間(毫秒) 默認延遲2秒關閉 var text = setting.text || setting; // 文本內容 //組裝HTML var tip = "<div class='tip tip-msg'>" + text + "</div>"; //刪除舊tip $(".tip-msg").remove(); //添加到body $("body").append(tip); //獲取jq對象 var $tip = $(".tip-msg"); //動畫過渡 $tip.animate({opacity: 1}, 500); //計算位置瀏覽器窗口上下、左右居中 // var height = document.body.clientHeight;//表示HTML文檔所在窗口的當前高度; var width = document.body.clientWidth;//表示HTML文檔所在窗口的當前寬度; var height = window.innerHeight;//瀏覽器窗口的內部高度; // var width = window.innerWidth;//瀏覽器窗口的內部寬度; width = ((width / 2) - ($tip.css("width").replace("px", "") / 2)) / width; height = ((height / 2) - ($tip.css("height").replace("px", "") / 2)) / height; $tip.css({ "top": (height * 100) + "%", "left": (width * 100) + "%" }); //延遲刪除 setTimeout(function () { //動畫過渡 $tip.animate({opacity: 0}, 500, function () { $tip.remove(); }); }, time); }, /** 可拖放窗口 tip.dialog({title:"測試彈窗標題",content:"測試彈窗內容"}); tip.dialog({ title:"測試彈窗標題", class:"myClassName", content:"<h1>測試彈窗內容</h1>", offset: ['100px', '50px'], area:["200px","100px"], shade:0, callBack:function(){ console.log('彈窗已加載完畢'); }, closeCallBack:function(){ console.log('你點擊了關閉按鈕'); } }); */ dialog: function (setting) { var title = setting.title || "這裏是標題"; // 標題 var clazz = setting.class || ""; // class var content = setting.content || "這裏是內容"; // 內容 var area = setting.area; // 寬高 var offset = setting.offset || "auto"; // 位置 上、左 var shade = setting.shade !== undefined ? setting.shade : 0.7;//遮陰 爲0時無遮陰對象 //組裝HTML var tip = "<div>\n" + " <!-- 遮陰層 -->\n" + " <div class=\"tip tip-shade\"></div>\n" + " <!-- 主體 -->\n" + " <div class=\"tip tip-dialog " + clazz + "\">\n" + " <!-- 標題 -->\n" + " <div class=\"tip tip-title\">\n" + " <h2 class=\"tip tip-title-text\"></h2>\n" + " <div class=\"tip tip-title-btn\">\n" + " <button class=\"tip tip-title-min\" title=\"最小化\">--</button>\n" + " <button class=\"tip tip-title-max\" title=\"最大化\">O</button>\n" + " <button class=\"tip tip-title-close\" title=\"關閉\">X</button>\n" + " </div>\n" + " </div>\n" + " <!-- 窗口內容 -->\n" + " <div class=\"tip tip-content\"></div>\n" + " <!-- 右下角改變窗口大小 -->\n" + " <div class=\"tip tip-resize\"></div>\n" + " </div>\n" + "</div>"; var $tip = $(tip); //添加到body $("body").append($tip); //設置遮陰 $tip.find(".tip-shade").css("opacity", shade); if (shade === 0) { $tip.find(".tip-shade").css({ "width": "0", "height": "0" }); } //獲取dialog對象 $tip = $tip.find(".tip-dialog"); //標題 $tip.find(".tip-title-text").html(title); //內容 $tip.find(".tip-content").append(content); //設置初始寬高 if (area) { $tip.css({ "width": area[0], }); $tip.find(".tip-content").css({ "height": area[1] }); } //動畫過渡 $tip.animate({opacity: 1}, 500); //計算位置瀏覽器窗口上下、左右居中 if (offset === "auto") { // var height = document.body.clientHeight;//表示HTML文檔所在窗口的當前高度; var width = document.body.clientWidth;//表示HTML文檔所在窗口的當前寬度; var height = window.innerHeight;//瀏覽器窗口的內部高度; // var width = window.innerWidth;//瀏覽器窗口的內部寬度; width = ((width / 2) - ($tip.css("width").replace("px", "") / 2)) / width; height = ((height / 2) - ($tip.css("height").replace("px", "") / 2)) / height; $tip.css({ "top": (height * 100) + "%", "left": (width * 100) + "%" }); } else if (Array.isArray(offset)) { $tip.css({ "top": offset[0], "left": offset[1] }); } //初始值寬高 //避免undefined.XXX報錯 $tip[0].resize = $tip[0].resize ? $tip[0].resize : {}; $tip[0].resize.initWidth = $tip.width(); $tip[0].resize.initHeight = $tip.find(".tip-content").height(); //綁定關閉按鈕回調 if(setting.closeCallBack){ $(".tip-title-close").click(function (e) { setting.closeCallBack(); }); } //執行回調 setting.callBack && setting.callBack(); }, //生成目錄彈窗,錨點信息數組 navCategoryAnchor : [], /** * 生成目錄彈窗,支持到二級目錄 * { * list1:$('#cnblogs_post_body h2'),//目錄的一級標題集合(如何找到一級目錄) * list2:"$list1.nextAll('h3')",//目錄的二級標題集合,(如何從每一個一級目錄節點$list1下面找到二級目錄) * offset: ['40%', '10%'],//彈窗位置 * area:["156px","250px"]//彈窗大小 * } */ generateContentList : function(setting){ setting.offset ? setting.offset : setting.offset = ['40%', '10%'];//彈窗位置 setting.area ? setting.area : setting.area = ["156px","250px"];//彈窗大小 //點擊章節,滾動帶動畫效果 $("body").on("click","#navCategory a",function() { $("html, body").animate({ scrollTop: $($(this).attr("href")).offset().top - 100 + "px" }, 800); return false; }); //監聽鼠標滾動事件 window.addEventListener('scroll', function () { //無需頻繁的進行遍歷判斷 if(new Date().getTime() % 2 == 0){ var scrolled = document.documentElement.scrollTop || document.body.scrollTop for(var i = 0;i<tip.navCategoryAnchor.length;i++){ if((i==0) ? (tip.navCategoryAnchor[i+1].offset >= scrolled) : (tip.navCategoryAnchor[i].offset <= scrolled && ((i == tip.navCategoryAnchor.length - 1) ? true : tip.navCategoryAnchor[i + 1].offset >= scrolled))){ $("#"+tip.navCategoryAnchor[i].a).css("color","#519cea"); }else{ $("#"+tip.navCategoryAnchor[i].a).css("color",""); } } } }); //生成目錄索引列表 var h2_list = setting.list1;//目錄的一級標題,找到全部h2 if(h2_list.length>0){ //返回頂部,元素以前追加 $("body").prepend('<a name="_labelTop"></a>'); var content = '<div id="navCategory">'; content += '<ul>'; //一級標題 for(var i =0;i<h2_list.length;i++){ var h2_id = "_label_h2" + i; var h2_text = $(h2_list[i]).text(); //去左右空格; h2_text = h2_text.replace(/(^\s*)|(\s*$)/g, ""); $(h2_list[i]).attr("id",h2_id); //錨點位置 tip.navCategoryAnchor.push({a:h2_id+"_a",offset:$(h2_list[i]).offset().top}); content += '<li><a id="'+h2_id+'_a" href="#' + h2_id + '">' + h2_text + '</a></li>'; //目錄的二級標題,找到全部的h3 var h3_list = eval(setting.list2.replace("$list1","$(h2_list[i])")); for(var j=0; j<h3_list.length; j++){ var h3_id = "_label_h3_" + i + "_" + j; var h3_text = $(h3_list[j]).text(); //去左右空格; h3_text = h3_text .replace(/(^\s*)|(\s*$)/g, ""); $(h3_list[j]).attr("id",h3_id); //錨點位置 tip.navCategoryAnchor.push({a:h3_id+"_a",offset:$(h3_list[j]).offset().top}); content += '<li style="padding-left: 25px"><a id="'+h3_id+'_a" href="#' + h3_id + '">' + h3_text + '</a></li>'; } } content += '</ul>'; content += '</div>'; //生成目錄拖拽彈窗 tip.dialog({title:"目錄",content:content,offset: setting.offset,area:setting.area,shade:0}); } } }; $(function(){ //初始化 tip.init(); });
調用
// tip提示 tip.msg("哈哈哈哈哈"); tip.msg({text:"哈哈哈哈哈",time:5000}); //可拖放窗口 tip.dialog({title:"測試彈窗標題",content:"測試彈窗內容"}); tip.dialog({title:"測試彈窗標題",content:"<h1>測試彈窗內容</h1>",offset: ['100px', '50px'],area:["200px","100px"],shade:0});
實時效果請看個人博客裏面的目錄、點贊功能、返回頂部(點擊火箭)
msg
彈出、銷燬有動畫效果,設置了一個max-width,超出會換行,支持參數配置
dialog
可拖動、可最小化、最大化、關閉,右下角可進行縮放,支持參數配置,發光特效
實現拖拽、縮放功能,主要是監聽了document的mousedown,mousemove,mouseup事件,並對特殊元素進行特殊處理,一波騷操做,玩出了花(滑稽),從而實現咱們想要的效果。
參考:
http://www.17sucai.com/pins/demo-show?id=4218
http://www.javashuo.com/article/p-ucavgype-cw.html
咱們利用這個彈窗,生成博客園的博文目錄。
一、咱們須要向博客園官方申請js權限(我的主頁 --> 設置 --> 博客設置);
二、把咱們上面的代碼添加進去
頁首、頁腳的意思就是咱們的代碼是嵌在頁首仍是頁腳
三、生成目錄索引,把下面的代碼也添加進去
//錨點信息數組 var navCategoryAnchor = []; //點擊章節,滾動帶動畫效果 $("body").on("click","#navCategory a",function() { $("html, body").animate({ scrollTop: $($(this).attr("href")).offset().top - 100 + "px" }, 800); return false; }); //監聽鼠標滾動事件 window.addEventListener('scroll', function () { //無需頻繁的進行遍歷判斷 if(new Date().getTime() % 2 == 0){ var scrolled = document.documentElement.scrollTop || document.body.scrollTop for(var i = 0;i<navCategoryAnchor.length;i++){ if((i==0) ? (navCategoryAnchor[i+1].offset >= scrolled) : (navCategoryAnchor[i].offset <= scrolled && ((i == navCategoryAnchor.length - 1) ? true : navCategoryAnchor[i + 1].offset >= scrolled))){ $("#"+navCategoryAnchor[i].a).css("color","#519cea"); }else{ $("#"+navCategoryAnchor[i].a).css("color",""); } } } }); //生成目錄索引列表 function GenerateContentList(){ var h2_list = $('#cnblogs_post_body h2');//目錄的一級標題,找到全部h2 if(h2_list.length>0){ //返回頂部,元素以前追加 $("body").prepend('<a name="_labelTop"></a>'); var content = '<div id="navCategory">'; content += '<ul>'; //一級標題 for(var i =0;i<h2_list.length;i++){ var h2_id = "_label_h2" + i; var h2_text = $(h2_list[i]).text(); //去左右空格; h2_text = h2_text.replace(/(^\s*)|(\s*$)/g, ""); $(h2_list[i]).attr("id",h2_id); //錨點位置 navCategoryAnchor.push({a:h2_id+"_a",offset:$(h2_list[i]).offset().top}); content += '<li><a id="'+h2_id+'_a" href="#' + h2_id + '">' + h2_text + '</a></li>'; //目錄的二級標題,找到全部的h3 var h3_list = $(h2_list[i]).nextAll("h3"); for(var j=0; j<h3_list.length; j++){ var tmp = $(h3_list[j]).prevAll('h2').first(); if(!tmp.is(h2_list[i])){ break; } var h3_id = "_label_h3_" + i + "_" + j; var h3_text = $(h3_list[j]).text(); //去左右空格; h3_text = h3_text .replace(/(^\s*)|(\s*$)/g, ""); $(h3_list[j]).attr("id",h3_id); //錨點位置 navCategoryAnchor.push({a:h3_id+"_a",offset:$(h3_list[j]).offset().top}); content += '<li style="padding-left: 25px"><a id="'+h3_id+'_a" href="#' + h3_id + '">' + h3_text + '</a></li>'; } } content += '</ul>'; content += '</div>'; //生成目錄拖拽彈窗 tip.dialog({title:"目錄",content:content,offset: ['40%', '10%'],area:["156px","250px"],shade:0}); } } $(function($){ //執行代碼 GenerateContentList(); })
咱們這裏一級標題對應的是h2,二級標題對應的是h3,並且目前只有兩個標題;生成目錄的簡單思路是:在每一個h二、h3標籤都添加一個惟一id,而後生成對應的a標籤連接過去,例如:
<h2 id="_label_h20"> 前言</h2>
<a id="_label_h20_a" href="#_label_h20">前言</a>
最後將拼接成的HTML字符串傳入咱們的tip.dialog方法,生成目錄彈窗
我把js代碼跟css代碼單獨寫成tip.js,tip.css,並上傳到博客的文件管理那裏,而且擴展了generateContentList方法:生成目錄彈窗,支持到二級目錄,如今想使用咱們這個可拖動彈窗就很簡單了,引入咱們的文件便可使用tip對象,調用對應的方法
<!-- 自定義web彈窗 CSS 文件 --> <link href="https://files.cnblogs.com/files/huanzi-qch/tip.css" rel="stylesheet"/> <script src="https://files.cnblogs.com/files/huanzi-qch/tip.js"></script>
封裝
var tip = { 省略其餘代碼... //生成目錄彈窗,錨點信息數組 navCategoryAnchor : [], /** * 生成目錄彈窗,支持到二級目錄 * { * list1:$('#cnblogs_post_body h2'),//目錄的一級標題集合(如何找到一級目錄) * list2:"$list1.nextAll('h3')",//目錄的二級標題集合,(如何從每一個一級目錄節點$list1下面找到二級目錄) * offset: ['40%', '10%'],//彈窗位置 * area:["156px","250px"]//彈窗大小 * } */ generateContentList : function(setting){ setting.offset ? setting.offset : setting.offset = ['40%', '10%'];//彈窗位置 setting.area ? setting.area : setting.area = ["156px","250px"];//彈窗大小 //點擊章節,滾動帶動畫效果 $("body").on("click","#navCategory a",function() { $("html, body").animate({ scrollTop: $($(this).attr("href")).offset().top - 100 + "px" }, 800); return false; }); //監聽鼠標滾動事件 window.addEventListener('scroll', function () { //無需頻繁的進行遍歷判斷 if(new Date().getTime() % 2 == 0){ var scrolled = document.documentElement.scrollTop || document.body.scrollTop for(var i = 0;i<tip.navCategoryAnchor.length;i++){ if((i==0) ? (tip.navCategoryAnchor[i+1].offset >= scrolled) : (tip.navCategoryAnchor[i].offset <= scrolled && ((i == tip.navCategoryAnchor.length - 1) ? true : tip.navCategoryAnchor[i + 1].offset >= scrolled))){ $("#"+tip.navCategoryAnchor[i].a).css("color","#519cea"); }else{ $("#"+tip.navCategoryAnchor[i].a).css("color",""); } } } }); //生成目錄索引列表 var h2_list = setting.list1;//目錄的一級標題,找到全部h2 if(h2_list.length>0){ //返回頂部,元素以前追加 $("body").prepend('<a name="_labelTop"></a>'); var content = '<div id="navCategory">'; content += '<ul>'; //一級標題 for(var i =0;i<h2_list.length;i++){ var h2_id = "_label_h2" + i; var h2_text = $(h2_list[i]).text(); //去左右空格; h2_text = h2_text.replace(/(^\s*)|(\s*$)/g, ""); $(h2_list[i]).attr("id",h2_id); //錨點位置 tip.navCategoryAnchor.push({a:h2_id+"_a",offset:$(h2_list[i]).offset().top}); content += '<li><a id="'+h2_id+'_a" href="#' + h2_id + '">' + h2_text + '</a></li>'; //目錄的二級標題,找到全部的h3 var h3_list = eval(setting.list2.replace("$list1","$(h2_list[i])")); for(var j=0; j<h3_list.length; j++){ var h3_id = "_label_h3_" + i + "_" + j; var h3_text = $(h3_list[j]).text(); //去左右空格; h3_text = h3_text .replace(/(^\s*)|(\s*$)/g, ""); $(h3_list[j]).attr("id",h3_id); //錨點位置 tip.navCategoryAnchor.push({a:h3_id+"_a",offset:$(h3_list[j]).offset().top}); content += '<li style="padding-left: 25px"><a id="'+h3_id+'_a" href="#' + h3_id + '">' + h3_text + '</a></li>'; } } content += '</ul>'; content += '</div>'; //生成目錄拖拽彈窗 tip.dialog({title:"目錄",content:content,offset: setting.offset,area:setting.area,shade:0}); } } };
直接調用生成目錄彈窗方法
//生成目錄彈窗 tip.generateContentList({ list1:$('#cnblogs_post_body h2'),//目錄的一級標題集合(如何找到一級目錄) list2:"$list1.nextAll('h3')",//目錄的二級標題集合,(如何從每一個一級目錄節點$list1下面找到二級目錄) offset: ['40%', '10%'],//彈窗位置 area:["156px","250px"]//彈窗大小 });
一、2019-05-17;bug復現:當有多個彈窗且大小不一致,拖動其中一個彈窗進行縮放,會影響到其餘彈窗,而且寬度變成跟最大的那個同樣
問題分析:代碼中咱們使用 dialogDiv = titleDiv.parent(),是jq對象,經過一個小測試發現,$獲取到的jq對象每次都是新的,jq對象裏面的DOM對象纔是惟一不變
因此咱們把數據寫在jq裏面的dom對象就好了,可是若是更開始resize沒有值的時候,undefined.width就會報錯,這一點要注意
bug解決:使用jq對象裏面的jsDOM對象,且在用的對象以前進行非空判斷便可,我tip.js已經替換成最新代碼,bug已經解決;
//避免undefined.XXX報錯 dialogDiv[0].resize = dialogDiv[0].resize ? dialogDiv[0].resize : {};
建立彈窗時初始化最小寬高哪裏也要改一下,同時也要先進行非空判斷
//初始值寬高 //避免undefined.XXX報錯 $tip[0].resize = $tip[0].resize ? $tip[0].resize : {}; $tip[0].resize.initWidth = $tip.width(); $tip[0].resize.initHeight = $tip.find(".tip-content").height();
效果
代碼
首先樣式.tip-title取消邊框,改爲.tip-content給個上下邊框
border-bottom: 1px solid #dad8d8;
border-top: 1px solid #dad8d8;
接下來是js代碼,先克隆一個這個對象,而後在生成目錄彈窗後進行樣式處理、追加
//推薦、關注、收藏 let $clone = $("#green_channel").clone(); $clone.css({ "margin-top": "4px", "margin-bottom": "4px", "font-size": "12px", "width": "164px", "text-align": "center", "border": "#c0c0c0 0px dashed" }); $clone.find("#green_channel_digg").text("推薦"); $clone.find("#green_channel_follow").text("關注"); $clone.find("#green_channel_favorite").text("收藏"); $clone.find("#green_channel_weibo").remove(); $clone.find("#green_channel_wechat").remove(); $(".tip-dialog").append($clone);
而後效果就出來了