ll
liukangdong
2024-12-12 b6d0ad0e7e57a77d1983009494b09aa1da5fbfc4
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
export const initFn = () => {
  var iframeWin = document.getElementById("iframe1")
  {
    iframeWin.onload = function () {
      iframeWin.contentWindow.postMessage({
        action: 'sendTitle',   // 告诉子页面本页面的标题(action自行指定,但需要与子页面中监听的action保持一致
        msg: '将标题发给子页面',
        info: document.title
      }, '\*')
      iframeWin.contentWindow.postMessage({
        action: 'updateInitParam',    // 告诉子页面一些初始值,包括浏览器视窗高度与宽度、iframe偏离文档的位置、iframe相对视窗的位置
        msg: '更新子页面一些初始值',
        showSize: {                       // 浏览器视窗高度与宽度
          width: $(window).width(),
          height: $(window).height()
        },
        iframeOffset: {                   // iframe偏离文档的位置
          left: iframeWin.offsetLeft,
          top: iframeWin.offsetTop
        },
        iframeClientPos: {                // iframe相对视窗的位置
          left: iframeWin.getBoundingClientRect().left,
          right: iframeWin.getBoundingClientRect().right,
          top: iframeWin.getBoundingClientRect().top,
          bottom: iframeWin.getBoundingClientRect().bottom
        }
      }, '\*')   // '\*'表示跨域参数,请结合自身业务合理设置
    }
  }
 
  // 步骤3:监听嵌入子页面的事件
  window.addEventListener('message', function (e) {
    console.log(e.data.msg)
    if (e && e.data) {
      switch (e.data.action) {
        case 'updateTitle':        // 本页面收到子页面通知更新标题通知,更新本页面标题
          document.title = e.data.info
          break
        case 'updatePos':
          var scrollLeftValue = document.documentElement.scrollLeft
          var scrollTopValue = document.documentElement.scrollTop
          iframeWin.contentWindow.postMessage({
            action: 'updatePos',
            msg: '更新Pos',
            scrollValue: {          // 滚动条滚动的偏移量
              left: -1 * scrollLeftValue,
              top: -1 * scrollTopValue,
            }
          }, '\*')   // '\*'表示跨域参数,请结合自身业务合理设置
          break
        default:
          break
      }
    }
  })
 
  // 步骤4:兼听本页面的resize事件,并将一些状态值发送给嵌入的子页面
  var resizeTimer = null
  var resizeDate
  $(window).resize(function () {
    resizeDate = new Date()
    if (resizeTimer === null) {
      resizeTimer = setTimeout(checkResizeEndTimer, 100)
    }
  })
 
  function checkResizeEndTimer() {
    if (new Date() - resizeDate > 100) {  // resize结束后再发消息,避免残影问题
      clearTimeout(resizeTimer)
      resizeTimer = null
      postResizeEvent()
    } else {
      setTimeout(checkResizeEndTimer, 100)
    }
  }
 
  function postResizeEvent() {
    iframeWin.contentWindow.postMessage({
      action: 'resize',
      msg: 'resize事件',
      showSize: {             // 告诉嵌入的子页面视窗高度与宽度
        width: $(window).width(),
        height: $(window).height()
      },
      iframeClientPos: {        // iframe相对视窗的位置
        left: iframeWin.getBoundingClientRect().left,
        right: iframeWin.getBoundingClientRect().right,
        top: iframeWin.getBoundingClientRect().top,
        bottom: iframeWin.getBoundingClientRect().bottom
      },
      iframeOffset: {        // iframe偏离文档的位置
        left: iframeWin.offsetLeft,
        top: iframeWin.offsetTop
      }
    }, '\*')     // '\*'表示跨域参数,请结合自身业务合理设置
  }
 
  // 步骤5:兼听本页面的scroll事件,并将一些状态值发送给嵌入的子页面
  // 为性能考虑,可以在定时器中处理
  var scrollTimer = null
  var scrollDate
  $(window).scroll(function (event) {
    postScrollEvent()
    scrollDate = new Date()
    if (scrollTimer === null) {
      scrollTimer = setTimeout(checkScrollEndTimer, 100)
    }
  })
 
  function checkScrollEndTimer() {
    if (new Date() - scrollDate > 100) {  // resize结束后再发消息,避免残影问题
      clearTimeout(scrollTimer)
      scrollTimer = null
    } else {
      postScrollEvent()
      setTimeout(checkScrollEndTimer, 100)
    }
  }
 
  function postScrollEvent() {
    // 计算滚动条偏移量
    var scrollLeftValue = document.documentElement.scrollLeft
    var scrollTopValue = document.documentElement.scrollTop
    iframeWin.contentWindow.postMessage({
      action: 'scroll',
      msg: 'scroll事件',
      scrollValue: {          // 滚动条滚动的偏移量
        left: -1 * scrollLeftValue,
        top: -1 * scrollTopValue,
      },
      iframeClientPos: {      // iframe相对视窗的位置
        left: iframeWin.getBoundingClientRect().left,
        right: iframeWin.getBoundingClientRect().right,
        top: iframeWin.getBoundingClientRect().top,
        bottom: iframeWin.getBoundingClientRect().bottom
      },
      showSize: {          // 告诉嵌入的子页面视窗高度与宽度
        width: $(window).width(),    // 视窗宽度
        height: $(window).height()  // 视窗高度
      },
      iframeOffset: {      // iframe偏离文档的位置
        left: iframeWin.offsetLeft,
        top: iframeWin.offsetTop
      }
    }, '\*')       // '\*'表示跨域参数,请结合自身业务合理设置
  }
 
}