Day03 自製收費廣告版位 - 使用 react-intersection-observer


Day03  自製收費廣告版位 - 使用 react-intersection-observer

前言

聽到 收費廣告版位 最常想到的就是 Google Adsense,開發者可以在自己的網站上找區塊串接 API,串機後到後台選擇曝光廣告,當有使用者看到廣告時開發者可以獲取收益,那你有思考過服務背後是如何觸發計價收費的,自己如果自建站內廣告該如何實作呢,讓我們利用本篇一起來探索吧。

本篇的小調整

這篇是說明 IntersectionObserver 應用的尾篇,為了更接近工作方式,所以改採用現成的 Component 套件來嘗試實作,並配置 Code Sandbox 來更接近真實使用 webpack import module 的開發環境。接下來分享搜集資料過程中看到兩個套件的實作方式。

react-intersection-observer

latest 版本 => 2019/11 Published
Weekly Downloads:42,528
Unpacked Size:114 kB
Issue 處理程度:這禮拜作者還有回覆呢

另外發現此 Component README 寫得超級詳細的,甚至連 Intersection Observer 技術都有詳細圖解,看到心裡總是想著那我幹嘛還寫那麼多這世上很溫暖呢

安裝

npm i @researchgate/react-intersection-observer

引入

import Observer from '@researchgate/react-intersection-observer';

可用參數(Options)
root: HTMLElement|string | default window viewport
rootMargin: string | default 0px 0px 0px 0px
threshold: number|Array | default: 0
disabled:boolean | default: false
onChange (required):接觸發 callback 取得 IntersectionObserverEntry
children: React.Element<*>|null

解說案例:可見度百分比( threshold 偵測)

參數設定

  • root:未指定,使用預設裝置 viewport
  • rootMargin:未指定,使用當前 viewport 邊界
  • threshold:設定 [0, 0.25, 0.5, 0.75, 1] 五個 step,顯示達到這些數值則觸發事件
  • disabled:未指定,預設不封鎖
  • onChnage:變更 Nav 顏色及取得 intersectionRatio 顯示比例
  • children:填入會被 Observe 的元件(畫面黑色區塊)
import React, { Component } from "react";
import Observer from "@researchgate/react-intersection-observer";
import "./styles.css";

export default class Default extends Component {
  constructor(props) {
    super(props);
    this.state = {
      visibility: "hidden",
      visibleRate: 0
    };
  }
  handleChange = ({ isIntersecting, intersectionRatio }) => {
    this.setState({
      visibility: isIntersecting ? "visible" : "invisible",
      visibleRate: intersectionRatio * 100
    });
  };

  render() {
    const observerConfig = {
      onChange: this.handleChange,
      threshold: [0, 0.25, 0.5, 0.75, 1]
    }
    return (
      <div>
        <div className={`nav ${this.state.visibility}`}>
          {this.state.visibleRate}%
        </div>
        <div className="body">
          <section className="hint">往下滑動</section>
          <Observer {...observerConfig}>
            <section className="target">
              <div /><div /><div /><div />
            </section>
          </Observer>
          <section className="hint">往上滑動</section>
        </div>
      </div>
    );
  }
}

特性一:threshold 與 intersectionRatio

這個不是套件的特定,是 IntersectionOberser 原生的實作就會有的問題,原因是滾動 scrollbar 一個單位是不會無限切割的,多顯示或少顯示的元件比例不一定會剛好等於 threshold 的設定值,而是當 intersectionRatio 越過這個值時,去觸發事件。

特性二:Observer元件不會出現 DOM 物件

<div className="body">
  <section className="hint">往下滑動</section>
  <Observer {...observerConfig}>
    <section className="target">
      <div /><div /><div /><div />
    </section>
  </Observer>
  <section className="hint">往上滑動</section>
</div>

收費廣告版位應用

需求:判定曝光計價的兩常見邏輯

  • 曝光多少百分比
  • 曝光秒數

規劃 Component 介面

Props

  • src:圖片連結
  • keepSecond:計價停留秒數條件
  • threshold:計價顯示比例條件

State

  • track:是否已計價
import React, { Component } from "react";

class AdImage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      tracked: false
    };
  }

  handleChange = ({ isIntersecting, intersectionRatio }) => {
    const { keepSeconds } = this.props;
    if (isIntersecting && intersectionRatio >= 0.5) {
      this.recordedTimeout = setTimeout(() => {
        this.setState({ tracked: true });
      }, keepSeconds * 1000);
      return;
    }
    clearTimeout(this.recordedTimeout);
  };

  render() {
    const { src, threshold } = this.props;
    const adTrackedSrc = "https://fakeimg.pl/300x100?text=Tracked";
    let imageSrc = src;
    if (this.state.tracked === true) {
      imageSrc = adTrackedSrc;
    }
    return (
      <Observer onChange={this.handleChange} threshold={threshold}>
        <img className="adImage" src={imageSrc} />
      </Observer>
    );
  }
}

串接成畫面測試看看

import React, { Component } from "react";
class Default extends Component {
  render() {
    return (
      <div>
        <section className="hint">往下滑動</section>
        <section className="target">
          <AdImage
            src="https://fakeimg.pl/300x100/?text=keep1s"
            keepSeconds={1}
            threshold={0.5}
          />
          <AdImage
            src="https://fakeimg.pl/300x100/?text=keep2s"
            keepSeconds={2}
            threshold={0.5}
          />
          <AdImage
            src="https://fakeimg.pl/300x100/?text=showAll"
            keepSeconds={0}
            threshold={1}
          />
        </section>
        <section className="hint">往上滑動</section>
      </div>
    );
  }
}

小結

希望對花時間看完的你有幫助,這是第一篇我用 React 寫範例程式,使用 IntersectionObserver 現有的套件製作收費廣告的版位 Component,在這樣一層一層的往上打造更便利的 API 就讓程式碼更方便的被管理,讓廣告廠商可以明確的填入圖片連結、顯示比例、顯示時間來的計價條件,但間接的也讓大家更不知道底層是 IntersectionObserver API 的實作。

最初我知道 IntersectionObserver 時它是被一層類似 ViewMonitor 包住的 Component,介面只有 100% 顯示跟 0% 消失的觸發填充事件,在研究底層利用 IntersectionObserver API 後才發現可以有這麼多參數可以運用,這也是覺得在看 Web APIs 文件時最大的收穫,會把原本好像我們已經懂的東西又提升了一個層次,而明天將會換另一個 API 繼續來跟大家分享,希望大家一起看下去囉。

參考資料

#Web #javascript #Web API #IntersectionObserver #advertising
近期正式轉職成為一個前端工程師 在工作的 Code Base 看多許多從未使用過的 Web API 想透過此次黑客松來翻翻文件 並把感覺實用、有趣的學習並紀錄起來 ~






Related Posts

使用 Prometheus 和 Grafana 打造 Flask Web App 監控預警系統

使用 Prometheus 和 Grafana 打造 Flask Web App 監控預警系統

[ 筆記 ] 網路基礎 - HTTP, Request, Response

[ 筆記 ] 網路基礎 - HTTP, Request, Response

白話的 Hash Table 簡介

白話的 Hash Table 簡介

Leetcode 刷題 pattern - Merge Intervals

Leetcode 刷題 pattern - Merge Intervals

Day00-Lavarel新手接觸

Day00-Lavarel新手接觸

[Day 1] JS in Pipeline - DevOps for Local Development Environment (1)

[Day 1] JS in Pipeline - DevOps for Local Development Environment (1)



Comments