手動でABテストするためのコンテンツの出し分けのサンプル（Javascript+Cookie）

##はじめに

**実現したい事**はWebサイトで
特定の画像／文章／デザインなどの部品を2パターン用意し、
ランダムで表示してその結果を後で
GoogleAnalyticsなどで検証するというものです。
※コードの例ではGAのイベントトラッキングを活用します。
![rabel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/1f7da049-60e8-b9b2-f92a-3f3d41f898c5.png)
オプティマイズや別の専用ツールなどもあるのですが、
ツールの縛りがある、使い辛い、まずは気軽に試したい、
という時に不便なので作りました。（個人サイトの場合など含め）

（利用例）
**画像A / 画像B　どちらを表示したほうがCVRが良いか？**
※GA等の解析ツールにデータを送信し、後で分析をかけます。

補足：
コードは汚いので仕組みそのものや部品とりとしてご活用ください。

##仕様

**概要：**
特定のIDを持つ要素に対してA／Bパターン2種類の中身（HTML）を用意し、
それをおよそ1/2の確率でランダムで表示します。
結果はCookieに記録し、次回以降該当のCookieが存在する場合、
同じ結果を表示します。
※Cookieを消したらまた1/2の確率でどちらかが表示されます。

これらの結果を表示する度に、GAにイベントとして
データを送信するというサンプルです。
※GAじゃなくてもコードをJSやHTMLで連携する類のものなら何でも可

使う言語：javascript+html+css
補足：cookieを活用します

##Javascriptコード
※デバッグ用と記載のある関数／コードは使用しなくとも大丈夫です。

```
<script>

window.onload = function() {

const thiscookiename = 'abtest';
//Cookieの名前

const btag = "<p style='background-color:#ffffee;width:200px;'>私がオススメするのは<br>クレープです。<br>";
//Bパターンのタグをここに記載

const yosoid1 = 'abtest';
//変更対象の要素のID

const yukokigen = 7;
//Cookieの有効期限（日）

const abeventname = 'testcase2020';
//GAイベント名称

const abeventcategory = 'ABTEST';
//GAイベントカテゴリー

//初期設定
//END


//0か1の乱数生成 Math.random()で0～1の間の乱数、2倍にしたものを整数にする
let abtestran = Math.floor( Math.random() * 2 );

const expire = new Date();
expire.setTime( expire.getTime() +yukokigen *24*60*60*1000 );
//Cookie用日時と有効期限の設定

//Cookieの有無を確認
if(GetCookieABtestOnly(thiscookiename) == null){
    document.cookie = thiscookiename + '=' + abtestran + '; expires=' + expire.toUTCString();
    //存在しなかったらCookie書込み

}
else{
    abtestran = GetCookieABtestOnly(thiscookiename);
    //存在する場合はテスト判定用数値を設定する
}


if(abtestran==1){

    //Bの時の処理

    document.getElementById(yosoid1).style.display = 'inline-block';
    //要素を表示するスタイルに変更

    document.getElementById(yosoid1).innerHTML = btag;
	//Bパターンのタグを代入

    document.getElementById('kekka').innerHTML = abtestran + "が値です";
    //デバッグ用
    

//GAイベント送信
gtag('event',abeventname, {
  'event_category' :abeventcategory,
  'event_label' : 'B_PT'
});
//endGA


}

//Aの時（イベント送信以外何もしない）
else{
    document.getElementById(yosoid1).style.display = 'inline-block';
    //要素を表示するスタイルに変更

    document.getElementById('kekka').innerHTML = abtestran + "が値です";
    //デバッグ用

//GAイベント送信
gtag('event',abeventname, {
  'event_category' :abeventcategory,
  'event_label' : 'A_PT'
});
//endGA

}


}
//onload終了



//Cookie取得用の関数
function GetCookieABtestOnly( name )
{

let result = null;
const cookieName = name + '=';
const allcookies = document.cookie;

const position = allcookies.indexOf( cookieName );

if( position != -1 )
    {
        startIndex = position + cookieName.length;

        endIndex = allcookies.indexOf( ';', startIndex );
        if( endIndex == -1 )
        {
            endIndex = allcookies.length;
        }

        result = decodeURIComponent(
            allcookies.substring( startIndex, endIndex ) );
    }

return result;
}



//デバッグ用Cookie削除
function deleteCookie(cockname) {
date = new Date();
date.setTime( date.getTime() - 1 );
document.cookie = cockname + '=; expires=' + date.toUTCString();

document.getElementById('kekka').innerHTML = "削除しました";

}


</script>
```


##HTMLのコード
※デバッグ用と記載のある部分は使用せずとも大丈夫です。

```
▼変更対象の要素：<br>
<!-- Aパターンの記載 -->
<div id="abtest" style="display:none;">
<p style="width:200px;background-color:#ffeeee;">
私がオススメするのは<br>
【タピオカ】です。<br>
</p>
</div>

<br><br>

Cookieの値を表示：デバッグ用<br>
<div id="kekka">
</div>

<br>

<div>
Cookieの削除：デバッグ用<br>
<input type="button" value="Cookie削除" onclick="deleteCookie('abtest');" style="cursor:pointer;">
</div>

```

##解説（重要そうな部分）

**ランダム表示用の変数を作る：**
`let abtestran = Math.floor( Math.random() * 2 );`
ランダム表示用に0か1の乱数を生成します。
Math.random()で0～1の間の乱数を、2倍にしたものを整数にする事で、
0か1だけになります。

**判定用(cookie有無）：**

別関数としてcookieの有無を確認するものを用意し、
nullだった場合はcookieを書き込みします。
存在していた場合は、Cookieの値をAB判定用の変数に代入します。

`if(GetCookieABtestOnly(thiscookiename) == null){`
`    document.cookie = thiscookiename + '=' + abtestran + '; expires=' + expire.toUTCString();`
`}`
`else{`
`    abtestran = GetCookieABtestOnly(thiscookiename);`
` }`


**判定用：ABのどちらか**
`if(abtestran==1){}else{}`
単純に1か0でAとBを判定します

**コンテンツを表示する部分**

HTML側：
`<div id="abtest" style="display:none;">`
Bを表示する時に一瞬、Aの画像が表示されるのを防ぐため、
HTML側はスタイルdisplay:noneで要素を隠しておきます。

JS側：
`document.getElementById(yosoid1).style.display = 'inline-block';`
Javascript側でスタイルを変えて、表示します。

`document.getElementById(yosoid1).innerHTML = btag;`
特定のIDを持つ要素に、JS内で記述しておいたBパターンの
タグを挿入します。

##後述

お読みいただきありがとうございます！

ポイントは1/2ランダムで出し分けと、Cookieで記録しておくという
部分だと思います。※毎回完全ランダムだとユーザーが困るので…

また、今回AパターンはHTMLに記述しておいて、BパターンはJS内に記載しましたが、
両方display:noneにしておいて、display:blockにするやり方もありますね。

応用すればもっと便利に出来るはずですので、
参考という形にしていただければと思います。

動作サンプルも置いておきます。
http://allcountry.sakura.ne.jp/biz/code/javascript/20200709/cookieabtest.html

![pta.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/0d274b85-e3c7-72d7-16dd-f0ccf051e2ac.png)