SPA(SinglePageApplication)의 천적 document.write에 대항하는 ~광고 코드는 영원히~

이번에 만든 것



SPA로 페이지를 전환하지 않고 광고 삽입


document.write의 공포



SPA(SinglePageApplication)에 있어서 JavaScript의 코드 안에 천적이 존재한다. 그것은 document.write입니다. SPA는 로드가 끝난 페이지에 대해서, 각 개소의 내용을 재작성해 가는 움직임을 한다. 노드의 말미에 HTML을 강제 추가하는 document.write를 실행하면(자), 곤란했다고 밖에 말이 없는 상태가 된다.

이에 대항하는 방법을 생각해 보았다. 원래 document.write가 자신이 원하는 위치에 데이터를 삽입하면 모든 문제가 해결되는 것이다. 그렇다면 그렇게 하자.

광고 코드



'document.write'를 쏟아 오는 상대로서 라쿠텐이나 Amazon의 광고 프로그램이 있다. 거기서 생성된 코드는, 물건의 훌륭하게 document.write를 호출하고 있어 페이지가 로드되는 단계에서 코드가 그 장소에 없으면 제대로 동작하지 않는 것이다.
하지만 SPA의 보급을 원하는 것으로는,

광고를 붙일 수 없기 때문에 SPA는 사용할 수 없잖아!

라고 하는 흐름으로 SPA의 보급이 방해받고는 곤란한 것이다.

사쿠토 해결



test.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
<title>SPA広告テスト</title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded",onLoad);
function onLoad(){
    var button = document.querySelector("button")
    button.addEventListener('click',function(){
        var node = document.querySelector("div")                //広告挿入先
        var code = document.querySelector("textarea").value     //広告コード
        outputAd(node,code);
    })
}
//outputAd(広告を挿入するノード,広告コード)
function outputAd(node,code){
    //document.writeのフック
    var documentWrite = document.write;
    document.write = function(value){
        node.innerHTML = value;
        document.write = documentWrite;
    }
    //ノード内のデータを削除
    while(node.childNodes.length)
        node.removeChild(node.childNodes[0])
    //広告コードをダミーノードに設定
    var dummy = document.createElement('div');
    dummy.innerHTML = code;
    while(dummy.childNodes.length){
        var child =  dummy.childNodes[0];
        dummy.removeChild(child);
        if(child.nodeName === 'SCRIPT'){
            //SCRIPTタグなら再生成
            var script = document.createElement('SCRIPT');
            if(child.src)
                script.src = child.src;
            script.innerHTML = child.innerHTML;
            node.appendChild(script);
        }
        else
            node.appendChild(child);
    }
}
</script>
</head>
<body>
<textarea rows='10' cols="80">広告コードを挿入</textarea><br>
<button>広告の表示</button>
<div style='border:solid'>
ここに広告を表示
</div>
</body>
</html>

실행은 http 또는 https 환경하에서 실시하지 않으면 정상적으로 동작하지 않는다. 또, 애드센스의 코드를 붙여 넣을 경우는, 대상의 도메인상에서 움직일 필요가 있다.

동작 원리로서, 우선은 광고 코드를 실행하는 곳으로부터 시작된다. 다만 innerHTML로 그대로 SCRIPT 태그가 섞인 코드를 꽂아도, HTML의 사양상 동작하지 않기 때문에, SCRIPT 태그를 재작성한다고 하는 처리가 사전에 필요하게 된다. 그리고 광고 코드 실행 후 document.write에 의한 HTML의 추가가 일어나므로 그것을 훅하여 대상 노드에 전송한다.

이번 코드는 아마존, 라쿠텐, 애드센스에서 동작을 확인하고 있다. 덧붙여서 애드센스는 document.write를 사용하지 않지만, 이번 코드로 동작한다.

하지만 이 코드에는 치명적인 단점이 있다. 동시에 복수의 광고를 설정하면 document.write의 데이터 전송처를 특정할 수 없게 된다. 이건 그래도 뭔가 좋은 해결 방법이 있으면 가르쳐 주었으면 한다.

사실은



아무래도 이런 어리석은 일을 하지 않아도 IFRAME을 만들어 거기에 코드를 넣으면 동작한다. 그리고 복수 광고 문제도 발생하지 않는다. 그러나 그럼 지는 것 같아서 이번 코드를 만들어 보았다.

현재 htps : // c 납 d. jp/ 로 광고의 테스트를 실시하고 있지만, 시스템을 만들 때 광고를 생각하지 않고 만들었기 때문에, 프런트 엔드 측의 코드가 심하게 되어 버렸다. 그렇다고 하는 것으로 기능 마다 플러그인을 짜넣는 듯한 방법을 할 수 있도록 재작성하려고 생각하고 있다.

좋은 웹페이지 즐겨찾기