فهرست منبع

feat: pc端nps滚动到视口中触发曝光事件

cuiyalong 1 سال پیش
والد
کامیت
832b3292ba

+ 22 - 6
apps/bigmember_pc/src/views/article-content/components/Nps.vue

@@ -1,10 +1,5 @@
 <template>
-  <div
-    id="npsMain"
-    class="npsMain npsPc"
-    v-show="showModule"
-    @mousemove="getIsView"
-  >
+  <div id="npsMain" class="npsMain npsPc" v-show="showModule">
     <div class="gray-div"></div>
     <div class="nps-content">
       <div class="nps-head">
@@ -48,6 +43,7 @@
 
 <script>
 import { getNpsData, getSeeNps, collectionNps } from '@/api/modules/nps'
+import { isElementInScrollArea } from '@jy/util'
 
 export default {
   data() {
@@ -77,14 +73,34 @@ export default {
   created() {
     this.getNpsData()
   },
+  beforeDestroy() {
+    this.removeScrollEvent()
+  },
   methods: {
     getNpsData() {
       getNpsData().then((res) => {
         if (res && res.data) {
           this.showModule = res.data.isShowNps
+          this.bindScrollEvent()
         }
       })
     },
+    bindScrollEvent(){
+      window.addEventListener('scroll', this.onPageScroll)
+    },
+    removeScrollEvent() {
+      window.removeEventListener('scroll', this.onPageScroll)
+    },
+    checkNpsView() {
+      const target = this.$el
+      const visible = isElementInScrollArea(target)
+      if (visible) {
+        this.getIsView()
+      }
+    },
+    onPageScroll() {
+      this.checkNpsView()
+    },
     // emoji表情转为字符
     utf16toEntities(str) {
       const patt = /[\ud800-\udbff][\udc00-\udfff]/g // 检测utf16字符正则

+ 2 - 2
apps/bigmember_pc/src/views/article-content/pages/Article.vue

@@ -509,6 +509,8 @@ function doClickFreeView() {
                 </div>
               </div>
             </div>
+            <!--  nps评分  -->
+            <Nps></Nps>
             <!--  投标服务  -->
             <div
               class="content-card watch-tab-content"
@@ -554,8 +556,6 @@ function doClickFreeView() {
               />
             </div>
           </div>
-          <!--  评分  -->
-          <Nps></Nps>
           <!--  内容底部广告  -->
           <div class="article-content-footer-container">
             <adsense code="jy-pccontent-bottom"></adsense>

+ 20 - 9
packages/util/modules/dom/scroll.js

@@ -1,16 +1,27 @@
 /**
- * 判断元素是否在滚动区域内
+ * 判断某个元素是否在滚动区域的视口中(和视口重叠)
  * element: 目标元素dom
- * scrollContainer: 滚动区域
+ * scrollContainer: 滚动区域(如果是body滚动,则此参数不传)
  */
 export function isElementInScrollArea(element, scrollContainer) {
   const elementRect = element.getBoundingClientRect()
-  const containerRect = scrollContainer.getBoundingClientRect()
+  if (scrollContainer) {
+    const containerRect = scrollContainer.getBoundingClientRect()
 
-  // 判断元素的上边界和下边界是否在滚动容器的上边界和下边界之间
-  const isElementAboveContainer = elementRect.bottom < containerRect.top
-  const isElementBelowContainer = elementRect.top > containerRect.bottom
+    // 判断元素的上边界和下边界是否在滚动容器的上边界和下边界之间
+    const isElementAboveContainer = elementRect.bottom < containerRect.top
+    const isElementBelowContainer = elementRect.top > containerRect.bottom
 
-  // 如果元素在滚动容器的上下边界之间,则认为它在滚动区域内
-  return !(isElementAboveContainer || isElementBelowContainer)
-}
+    // 如果元素在滚动容器的上下边界之间,则认为它在滚动区域内
+    return !(isElementAboveContainer || isElementBelowContainer)
+  } else {
+    const viewportWidth = window.innerWidth || document.documentElement.clientWidth
+    const viewportHeight = window.innerHeight || document.documentElement.clientHeight
+    return (
+      elementRect.top < viewportHeight &&
+      elementRect.bottom > 0 &&
+      elementRect.left < viewportWidth &&
+      elementRect.right > 0
+    )
+  }
+}