初入前端,最近在使用word時發現有個批注功能,就想的如何用代碼去實現一下
1.頁面整體分為左中右兩部分,中間為正文內容區域,右右兩側為注釋瀏覽區域
2.右側展示的注釋內容必須與所需注釋詞匯在一條線上
3.初始時只顯示兩行內容,點擊時展開全部
4.如果兩個被注釋的詞距離太近,注釋部分要求依次排序
1.在注釋內容外側添加一個p,利用p的min-height屬性控制注釋的位置
2.利用position: absolute絕對定位,動態的生成和改變注釋的位置
在實現上述兩種方法的過程中發現,第一種方案在數據量龐大的情況下,會出現bug,頁面會奔潰,果斷放棄了,選擇了第二種方式實現
1> args--------->當前文章內容中有注釋的詞集合
2> notes-------->從庫中獲取到的注釋文本集合
3> rightWrap---->右側部分注釋區域對象
4> leftWrap----->左側部分注釋區域對象
1> setSite()------------------------------>初始界面加載時確定注釋的位置
2> resetTop(elem, type)------------------->在點擊時重新設置所有注釋的位置
elem:當前被點擊的對象
type:(open/close)全部展開或部分展示
3> bindClick(elem, type, selector, fn)---->綁定事件函數
elem:綁定事件的元素
type:綁定的事件類型,例如(click)
selector:動態添加到elem中的元素
fn:綁定事件執行后回調方法
1> index.html部分代碼
<p class="wrap"> <aside class="left"></aside> <article class="center"> <h3>人世</h3> <br /> <p>使其停下來</p> <p>使光影、蜉蝣</p> <p><b class="special-0 nleft">眾生</b>的所向是什么</p> <p>尤以靜止方可得出</p> <p>我不做空明的闡述</p> <p>我是凡人,且一直落在凡塵里</p> <p>使云霞似錦吧</p> <p>若產出時間的黃金</p> <p>時間的<b class="special-1">黃金</b>只能在一顆心里</p> <p>播種,<b class="special-2">萌發</b>,成為照耀</p> <p>內斂的照耀比及月亮</p> <p>我們需做輝光的同謀人</p> <p>我們依舊不能成為閃電或是驚雷</p> <p>我們只是平凡的形形色色</p> <p>為所有悸動歡呼的應該是另一群人</p> <p>那些卑微的怯懦的都給我</p> <p>我隱在暗處說——</p> <p>“這很好!”,是的,你注視我說——</p> <p>“你很好!”</p> <p>還有可以使其墮落下去使其淪陷下去的嗎</p> <p>光影、<b class="special-3">蜉蝣</b>、我和你</p> <p>和岸邊無風也要搖蕩的蘆葦</p> <p>和似乎永不休止的蟬鳴</p> <p>和流水</p> </article> <aside class="right"></aside> </p>
2> index.css部分代碼
.wrap { display: flex; position: relative; width: 100%; } article.center { flex: 1; text-align: justify; padding: 20px; border-right: 1px solid #ddd; border-left: 1px solid #ddd; } article.center p { line-height: 24px; } article.center p b { color: red; } aside.left, aside.right { width: 300px; padding: 20px 0; } .wrap aside mark { background-color: #fff; color: #afafaf; padding: 0 20px; position: absolute; top: 0; height: 44px; overflow: hidden; line-height: 20px; font-size: 12px; text-align: justify; cursor: pointer; width: 260px; }
3> index.js部分代碼
; (function() { // 構造函數 function View(elem, notes, rightWrap, leftWrap) { this.rightWrap = rightWrap; this.leftWrap = leftWrap; this.args = typeof elem === 'object' ? elem : document.getElementById(elem); this.notes = notes === undefined ? [] : notes; this.init(); } // 原型 View.prototype = { constructor: View, init: function() { var self = this; self.setSite(); self.bindClick(document.body, 'click', 'mark', function (e) { var target = e.target; if(this.style.height) { this.style.height = ''; self.resetTop(this, 'close'); return; } else { this.style.height = this.scrollHeight +'px'; self.resetTop(this, 'open'); } }); }, // 設定初始高度 setSite: function() { for(let i = 0; i < this.args.length; i++) { // 默認新建的批注距離頂部的高度 var swdTop = 0; var addMark = ''; // 計算當前批注的高度是否被覆蓋,如果被覆蓋,進行處理 if(i > 0) { if(this.args[i].offsetTop - this.args[i-1].offsetTop > $('.note-' + (i-1)).height()) { swdTop = this.args[i].offsetTop - 2 + 'px'; } else { swdTop = this.args[i-1].offsetTop + $('.note-' + (i-1)).height() - 2 + 'px'; } } else { swdTop = this.args[i].offsetTop - 2 + 'px'; } if(this.notes.length > 0) { addMark = '<mark class="note-' + i + '" style="top:' + swdTop + '">'+ this.args[i].innerHTML +':' + this.notes[i] + '</mark>'; } else { addMark = ''; } // 將得到的新標簽動態添加到容器中 if(this.args[i].classList.length > 1 && this.args[i].classList[1] === 'nleft' && this.leftWrap !== undefined) { this.leftWrap.append(addMark); } else { this.rightWrap.append(addMark); } } }, // 重新設置元素高度 resetTop: function(elem, type) { let index = parseInt(elem.className.substr(elem.className.indexOf('-')+1)); for(; index < this.args.length-1; index++) { var swdNewTop = 0; var addTop = []; if(this.args[index+1].offsetTop - this.args[index].offsetTop > $('.' + elem.className).height()) { console.log('我們不需要執行任何東西了') return } else { if(type === 'open') { swdNewTop = this.args[index].offsetTop + $('.' + elem.className).height() + 8 + 'px'; addTop[index+1] = swdNewTop; } else { swdNewTop = this.args[index].offsetTop + $('.' + elem.className).height() + 'px'; } $('.note-' + (index+1)).attr('style', 'top:' + swdNewTop); return } } }, // 綁定元素點擊事件 bindClick: function(elem, type, selector, fn) { if(fn === null) { fn = selector; selector = null; } elem.addEventListener(type, function(e) { var target = e.target; if(selector) { target = e.target; if(target.matches(selector)) { fn.call(target, e); } } else { fn(e); } }) } } // 對外公開方法 window.View = View; })();
(function($) { $.fn.extend({ viewDocument: function(notes, rightWrap, leftWrap) { new View(this, notes, rightWrap, leftWrap); // 為了保證jQuery所有的方法能夠實現鏈式訪問,每個方法的最后必須返回this,即返回jquery的實例 return this; } }) })(jQuery);
// 此內容從數據庫中獲取,這里只是舉個例子 let notes = [ '山不在高,有仙則名;水不在深,有龍則靈;斯是陋室,惟吾德馨', '東邊日出西邊雨,道是無晴卻有晴。一蓑煙雨任平生。桃李不言下自成蹊。會當凌絕頂,一覽眾山小。莫道不消魂,簾卷黃花瘦。', '得不到的永遠在騷動,被寵愛的都有恃無恐,玫瑰的紅,容易受傷的夢。', '青青園中葵,朝露待日晞。陽春布德澤,萬物生光輝。常恐秋節至,焜黃華葉衰。百川東到海,何時復西歸?少壯不努力,老大徒傷悲!' ]; // 獲取注釋所在的容器 let rightWrap = $('aside.right'); let leftWrap = $('aside.left'); $('.center b').viewDocument(notes, rightWrap, leftWrap);
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com