首頁 > web前端 > js教程 > 如何利用js實現仿world中批註功能的效果(附程式碼)

如何利用js實現仿world中批註功能的效果(附程式碼)

不言
發布: 2018-08-15 15:15:49
原創
4587 人瀏覽過

本篇文章帶給大家的內容是關於如何利用js實現仿world中批註功能的效果(附程式碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

初入前端,最近使用word時發現有個註解功能,就想的如何用程式碼去實作一下

一、大概需求如下:

1.頁面整體分為左中右兩部分,中間為正文內容區域,右右兩側為註釋瀏覽區域
2.右側所展示的註釋內容必須與所需註釋詞彙在一條線上
3.初始時只顯示兩行內容,點擊時展開全部
4.如果兩個被註解的字距離太近,註解部分要求依序排序

#二、預設解決方案

1.在註解內容外側加入一個p,利用p的min-height屬性控制註解的位置
2.利用position: absolute絕對定位,動態的產生和改變註解的位置

三、實作過程

在實現上述兩種方法的過程中發現,第一種方案在資料量龐大的情況下,會出現bug,頁面會奔潰,果斷放棄了,選擇了第二種方式實作

1.常數部分:

1> args--------->目前文章內容中有註解的字集
2> notes -------->從庫中取得的註解文字集合
3> rightWrap---->右側部分註解區域物件
4> leftWrap----->左側部分註解區域物件

2.方法部分

1> setSite()----------------------- ------->初始介面載入時決定註解的位置
2> resetTop(elem, type)------------------->在點擊時重新設定所有註解的位置
  elem:目前被點擊的物件
  type:(open/close)全部展開或部分展示
3> bindClick(elem, type, selector, fn)-- -->綁定事件函數
  elem:綁定事件的元素
  type:綁定的事件類型,例如(click)
  selector:動態加入elem中的元素
  fn:綁定事件執行後回呼方法

3.整體程式碼

1> index.html部分程式碼

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<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部分程式碼

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

.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部分程式碼

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

;

(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 = &#39;&#39;;

                  

//              计算当前批注的高度是否被覆盖,如果被覆盖,进行处理

                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-&#39; + i + &#39;" style="top:&#39; + swdTop + &#39;">'+ 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;

})();

登入後複製

4.透過擴充方法將拖曳方法擴展到jquery的一個實例方法

1

2

3

4

5

6

7

8

9

(function($) {

  $.fn.extend({

    viewDocument: function(notes, rightWrap, leftWrap) {

      new View(this, notes, rightWrap, leftWrap);

      //  为了保证jQuery所有的方法能够实现链式访问,每个方法的最后必须返回this,即返回jquery的实例

      return  this;

    }

  })

})(jQuery);

登入後複製

5.在主介面上的呼叫方法

1

2

3

4

5

6

7

8

9

10

11

//  此内容从数据库中获取,这里只是举个例子

let notes = [

         '山不在高,有仙则名;水不在深,有龙则灵;斯是陋室,惟吾德馨',

         '东边日出西边雨,道是无晴却有晴。一蓑烟雨任平生。桃李不言下自成蹊。会当凌绝顶,一览众山小。莫道不消魂,帘卷黄花瘦。',

         '得不到的永远在骚动,被宠爱的都有恃无恐,玫瑰的红,容易受伤的梦。',

         '青青园中葵,朝露待日晞。阳春布德泽,万物生光辉。常恐秋节至,焜黄华叶衰。百川东到海,何时复西归?少壮不努力,老大徒伤悲!'

     ];

//  获取注释所在的容器

let rightWrap = $('aside.right');

let leftWrap = $('aside.left');

$('.center b').viewDocument(notes, rightWrap, leftWrap);

登入後複製

相關推薦:

用js模仿word格式刷功能實作程式碼[推薦]_javascript技巧

##PHP實作仿百度文庫,豆丁線上文件效果(word,excel,ppt轉flash),_PHP教學

#js word表格動態新增程式碼_javascript技巧

##

以上是如何利用js實現仿world中批註功能的效果(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板