Javascript, jQuery로 element의 index 구하기

개요

Google Analytics에서 dataLayer를 사용하는데, 제품 노출을 전달할 때 그 제품의 index를 넘겨야 한다.
하지만 tagmanager를 사용하기 위한 dataLayer는 body여는태그 바로 뒤에 삽입해서 jQuery보다 먼저 호출되고만다.

<ul class="product">
  <li class="product">
    <div class="product">
      <div class="product-image">
        <a href="/13"></a>
      </div>
      <div class="product-content">
      </div>
    </div>
  </li>
  <li class="product">...</li>
  <li class="product">...</li>
</ul>

여기서 상품번호 별 li의 index를 어떻게 가져올까?

jQuery

jQuery로는 간단하다.

var position = $('.product-image a[href='/' + {{ product.id }} + '/']&').closest('li.product').index() + 1;

하지만 jQuery를 못 쓰는게 함정

javascript

스택오버플로우에서 루프를 돌지 않고 요소의 index를 받는 함수를 올려놓은 답변을 찾았다.

function getChildNumber(node) {
  return Array.prototype.indexOf.call(node.parentNode.childNodes, node);
}

하지만 내 코드에선 1, 3, 5, 7로 찍혀 나와서 2로 나누고 반올림 해서 수정했다.

function getChildNumber(node) {
  return Math.ceil(Array.prototype.indexOf.call(node.parentNode.childNodes, node)/2);
}

그래서 완성 코드는 이렇게 되었다.

var position = getChildNumber(document.querySelector('.product-image a[href='/' + {{ product.id }} + '/']').parentNode.parentNode.parentNode);

jQuery의 closest같은 경우는 이렇게 구현할 수도 있는데 짜피 한번 쓸거라 걍 parentNode로 올라갔다.

결과

근데 html dom보다 dataLayer가 먼저 불려서 돔 위치를 파악할 수 없어서 결국 fail. 담에 더 파봐야겠다…

(+)160111 추가 내용

jQuery를 GTM 스니펫 위로 올리고, dom ready이후에 추가되는 것들은

$(function() {
 ...
});

제이쿼리로 dom이 만들어진 후에 불리도록 넣었다.

Refer

http://stackoverflow.com/questions/4649699/is-it-possible-to-get-elements-numerical-index-in-its-parent-node-without-loopi
http://stackoverflow.com/questions/22100853/dom-pure-javascript-solution-to-jquery-closest-implementation

Google Analytics 전자상거래(ecommerce) 적용하기

무엇이냐?

mind the log 자료
주문완료 되면 사이트 서버에서 해당 정보 처리 후 GA서버에 2종류 데이터 전달
1. 주문 정보
– 주문번호(ID)
– 제휴사(Affiliation)
– 총액(Revenue)
– 배송비(shipping)
– 세금(Tax)
2. 제품 정보
– 주문정보(ID): 위의 주문번호와 동일
– 제품명(Name)
– 제품코드(SKU)
– 제품가격(Price)
– 제품수량(Quantity)

향상된 전자상거래 켜기

Google Analytics사이트 > 설정원하는 앱 > Admin > Property Settings > Use enhanced link attribution을 On으로 켠다.

GA 전자상거래

  1. 설정방법
    • Google 애널리틱스에서 새로운 태그 유형을 만듭니다.
    • 태그가 실행되는 경우를 지정합니다.
    • 태그 이름, 태그 유형, 관련 추적 ID와 같은 필수 입력란에 해당 정보를 입력합니다.
    • 추적 유형을 ‘거래’로 설정합니다.
  2. 변수
    • 모든 거래 정보는 데이터 영역을 통해 전달되어야 함.
    • transactionId(필수) 고유 거래 식별자 문자열
    • transactionAffiliation(선택) 파트너 또는 상점 문자열
    • transactionTotal(필수) 거래의 총 가치 숫자
    • transactionShipping(선택) 거래의 배송비 숫자
    • transactionTax(선택) 거래에 대한 과세액 숫자
    • transactionProducts(선택) 거래에서 구매한 상품 목록 TransactionProduct 객체의 배열
  3. TransactionProduct 데이터
    • 온라인 거래에 포함되는 제품 설명하는 객체 목록
    • 이름(필수) 제품 이름 문자열
    • SKU(필수) 제품 SKU 문자열
    • 카테고리(선택) 제품 카테고리 문자열
    • 가격(필수) 단가 숫자
    • 수량(필수) 품목 수 숫자

데이터 영역 코드 구현 예

<br />dataLayer = [{
    'transactionId': '1234',
    'transactionAffiliation': 'Acme Clothing',
    'transactionTotal': 38.26,
    'transactionTax': 1.29,
    'transactionShipping': 5,
    'transactionProducts': [{
        'sku': 'DD44',
        'name': 'T-Shirt',
        'category': 'Apparel',
        'price': 11.99,
        'quantity': 1
    },{
        'sku': 'AA1243544',
        'name': 'Socks',
        'category': 'Apparel',
        'price': 9.99,
        'quantity': 2
    }]
}];

비동기때문에 GTM컨테이너 스니펫 에 이 코드를 넣어야 한다.

콘텐츠 그룹

앱 콘텐츠를 논리적 구조로 분류 가능.
남성-셔츠 여성-악세사리 이렇게 대분류 소분류 등으로 분류 가능하다.

1

admin &gt; view &gt; content grouping &gt; New에 들어가서 입력한다.

  • 이름: 유아책
  • Index: 색인 번호. 지정하는 콘텐츠 분류 이름과 연결. GTM에서 태그 만들 때 이 숫자 사용.

Universal Analytics Tracking Code (analytics.js):

ga('set', 'contentGroup1', 'My Group Name'); 

이런식으로 삽입.

2

참고
GTM에서 태그 추가 > Track Type: Page View > Configure Tag > More setting > add content group에서 위에서 지정한 최상이 콘텐츠 분류의 색인 번호를 적어준다.
Content Group에는 하위 분류를 적어둔다(e.g 셔츠)

추적코드 달기

mind the log

Intro

기본코드 외 4가지가 필요하다.
1. Ecommerce.js플러그인 호출
2. 결제정보(e.g. 주문번호, 구매액 등) 코드
3. 제품정보(e.g. 제품 아이디, 제품명) 코드
4. GA로 위 정보를 전송하는 커맨드

이 4가지가 기본 GA코드에 추가되어 구매완료(영수증) 페이지에 삽입되어야 함.

1. Ecommerce.js 플러그인 호출

페이지마다 삽입되는 기본 GA코드에

ga('require', 'ecommerce', 'ecommerce.js');

를 추가함. 구매완료 페이지에만 추가하면 된다.

2. 결제정보 코드 추가

구매완료페이지에 추가한다.

ga('ecommerce:addTransaction', { 
  'id': '1234', // 시스템에서 생성된 주문번호. 필수. 
  'affiliation': 'store.co.kr', // 제휴사이름. 선택사항. 쿠폰이름 같은거 넣어도 된다.
  'revenue': '127000', // 구매총액. 필수. 배송비 및 세금 기타 모든 비용 포함
  'shipping': '5000', // 배송비. 선택사항. 
  'tax': '2000' // 세금. 선택사항.
});

3. 제품정보 코드 추가

구매완료 페이지에 추가. for문으로 돌린다.

ga('ecommerce:addItem', { 
  'id': '1234', //시스템에서 생성된 주문번호. 필수. 
  'name': '남성용 긴팔셔츠 흰색 XL', // 제품명. 필수. 
  'sku': 'XXX56789', // SKU 또는 제품고유번호. 선택사항. 
  'category': '남성의류', // 제품 분류. 
  'price': '30000', // 제품 단가. 
  'quantity': '1' // 제품 수량.
});

4. GA로 위 정보 전송

구매완료 페이지에 추가

ga('ecommerce:send');

tagmanager로 전자상거래 추적 달기

참고링크
1. 태그매니저 사이트에 들어가서 Variables&gt;new&gt;Custom Javascript에 아래 코드를 넣는다.

function() {
  var ecommerceData = {
    'ecommerce' : {
      currencyCode : 'EUR',
      // add additional parameters as needed...
    }
  };
  return ecommerceData;
}

이 변수에서 이 데이터를 데이터 영역으로 푸시하는 데 사용하는 동일한 구문을 이용해라.

실제로 어떻게 동작하나 살펴볼 수 있는 사이트

http://enhancedecommerce.appspot.com/

환불

마찬가지로 ‘환불영수증’ 을 발행시키면 되는데요, 주문번호를 그대로 두되 같은 액수를 마이너스로 해서 마이너스 주문을 입력하는 방식입니다.

두 가지 방법을 알려드리자면,

1) 아래와 같이 구매총액 및 상품갯수를 마이너스로, 제품단가는 양수로 입력한 환불영수증 페이지를 만들어서 로드합니다.

ga('ecommerce:addTransaction', { 
'id': '1234', // 시스템에서 생성된 주문번호. 필수. 
'affiliation': 'store.co.kr', // 제휴사이름. 선택사항. 
'revenue': '-127000', // 구매총액의 마이너스 입력!!! 필수. 
'shipping': '-5000', // 배송비 마이너스 입력!!! 선택사항. 
'tax': '-2000' // 세금 마이너스 입력!!! 선택사항.
});

// 제품별 데이터
ga('ecommerce:addItem', { 
'id': '1234', //시스템에서 생성된 주문번호. 필수. 
'name': '남성용 긴팔셔츠 흰색 XL', // 제품명. 필수. 
'sku': 'XXX56789', // SKU 또는 제품고유번호. 선택사항. 
'category': '남성의류', // 제품 분류. 
'price': '30000', // 제품 단가. 양수로 입력!!! 
'quantity': '-1' // 제품 수량. 마이너스 입력!!!
});

참조: https://support.google.com/analytics/answer/1037443?hl=ko

만약 향상된전자상거래 (Enhanced Ecommerce) 를 사용중이시면, Data Import 를 통해 보다 손쉽게 일괄적으로 처리 가능합니다.

참조: https://support.google.com/analytics/answer/6014861?hl=ko

답변이 되었기를 바랍니다~
refer

공식가이드

공식가이드 링크

Ecommerce with Tag manager

공식가이드
미리 읽어야 할 Enhanced Ecommerce
tagmanager ecommerce 동영상강의

Refer

GOOGLE ANALYTICS MOOC – ECOMMERCE ANALYTICS
GOOGLE ANALYTICS MOOC – ECOMMERCE ANALYTICS 후기

git rebase후 push 에러 해결

개요

내 브랜치에서 메인 브랜치를 찝어서 rebase를 한 뒤 push하면 아래와 같은 에러가 뜰 때가 있다.

rebase Updates were rejected because the tip of your current branch is behind 어쩌구저쩌구

뭐 내 브랜치 가리키는게 뒤에 있어서 샬라샬라 같은 문제인듯 하다.
여기서 pull을 받고 push를 하거나 혹은 commit하면
merge commit이 들어가거나 혹은 rebase해서 받아온 커밋이 복제되어서 두번 반복해서 들어가는 안예쁨이 있다.

해결

git push -f origin

로 포스 푸쉬를 하면 된다.
그럼 깔끔히 rebase된 상태로 서버에 올라간다.

may the force with you.

refer

http://stackoverflow.com/questions/15143042/cant-push-to-branch-after-rebase

카카오스토리로 공유하기 간단하게 코딩하기

사이트에 공유버튼을 달아야 하는 미션.

원래 Kakao Developers 사이트에서 기본 제공하는 간단한 js와 버튼 div를 가져와서 width 0시켜 안보이게 만든 뒤
커스텀해 만든 버튼을 click이벤트로 연결하려 했다.

예상시간: 30분이면 되겠지!
삽질시간: …

iphone사파리에서만 foce한 클릭이 먹질 않는것이다.
iphone safari jquery click검색하니 나와 같은 고생을 겪는 선지자들을 보고

  • cursor: pointer로 두면 jquery가 신기하게 먹는다
  • display: none을 풀어라
  • touchstart이벤트를 넣어라
  • a태그가 아니면 먹질 않는다
  • onclick=” “과 같이 빈 액션을 넣어라

등의 삽질을 해보았지만 왠지모르게 실패. 플러그인 만지기란…

파이님이 만드신 알파카코믹스는 도대체 어떻게 한거지 하고 봤더니 걍 href에 https://story.kakao.com/share?url=를 추가하셨다.

어디서 나온 주소냐고, 플러그인 쓰지 않아도 되냐고 여쭙니 본인도 플러그인으로 고통받다가 저 주소를 야매로 알아내셨다 하심.

jquery iphone click문제는 내 지친 마음이 좀 더 회복되고 다시 봐야겠다.

무튼 코드로 마무리

<div class="teaser-social-share">
        <a class="share-kakaostory waves-effect waves-light" href="#"><i class="icon-kakao_story"></i></a>
        <a class="share-fb waves-effect waves-light" href="#"><i class="icon-facebook"></i></a>
        <a class="share-twitter waves-effect waves-light" href="#"><i class="icon-twitter"></i></a>
        <!--<a id="kakaostory-share-button"></a>-->
    </div>
var Share = {
    clickShareBtn: function() {
        var size = 'width=626 height=436';
        $('.share-kakaostory').on('click', function () {
            window.open('https://story.kakao.com/share?url=https://store.pinkfong.com/event/teaser/', '_blank', size);
        });
        $('.share-fb').on('click', function () {
            window.open('https://www.facebook.com/sharer/sharer.php?u=https%3A//store.pinkfong.com/event/teaser/', '_blank', size);
        });
        $('.share-twitter').on('click', function () {
            window.open('https://twitter.com/share?url=https://store.pinkfong.com/event/teaser/', '_blank', size);
        });
    }
}

$(function(){
    Share.clickShareBtn();
});