이번 내용도 자동 메타등록기를 만들어내다가 맞춰낸(?) 함수.

...

일반적으로, 블로그의 표시 구조는 구분되어 있는데,

1) jQuery 에서 자주 사용하는 $() 함수가 부분이 탐(?)나기도 했고,

2) document.getElementsbyClassName() 라는 함수가 있긴 하지만,
InternetExplorer 8 에서는 자체적으로 지원되지는 않았고,

결국... 내 입맛(?), 아니
속도에 영향을 최대한 주지않을(?) 메타등록기를 계속 만들려다 보니
할 수 있는 한 중복탐색을 최대한 줄여야겠다...라는 생각에

여러번 고생(?)끝에 만들어낸 함수 두가지.

...

하나는 해당 element 로부터
지정한 tag 와 class 를 하위 element 에서 검색해
첫번째 검색된(?) element 를 각각의 array 로 반환하는 함수,

- searchFirstStyletoArray101127_1(fromElement, 'TAG.classname0', 'TAG.classname1', ...)

또 하나는 형제(?) element 를 찾아서
자신과 유사한(= =?) tag 와 class 를 사용(?)하는 element 를
자신을 포함해 array 로 반환하는 함수.

- searchSameLevelStyletoArrays101127_1(start)

...


<SCRIPT>

function searchFirstStyletoArray101127_1() {
// useage : (fromElement, classname0, classname0, ...)
// output : [0]<=classname0, [1]<= classname1, ...
// on tag : classnameN='TAG.classname'
// no tag : classnameN='.classname'

  var receivedArguments=arguments, start=receivedArguments[0], inClassSet, classNameS='className', tagNameS='tagName',
    waitingClass=[], waitingTag=[], waitedNumber=[], searchV, searchP, i, j, k, returnObject=[], sameValue=[], topTag, topClass, nowClass, nowPoint;

  function pointPop(array, p) { array[p]=array[array.length-1]; array.length--; }

// -- getting classname & tagname
  for (i=1; i<receivedArguments.length; i++) {
    searchV=receivedArguments[i];
    if ((searchP=searchV.indexOf('.'))>=0) {
      topTag=searchV.substr(0, searchP); if (topTag=='*') topTag='';
      waitingTag.push(topTag);
      waitingClass.push(searchV.substring(searchP+1, searchV.length));
      } else {
      waitingTag.push(searchV);
      waitingClass.push('');
      }
    waitedNumber.push(i-1);
    }
// -- end of getting classname & tagname

 // if (document.getElementsByClassName) {
  if (start.getElementsByClassName) {
// start getElementsByClassName
// not graped by same classname

  for (i=0; i<waitingClass.length; i++) {
    topTag=waitingTag[i];
    topClass=waitingClass[i];

    if (topClass) searchV=start.getElementsByClassName(topClass);
      else if (topTag) searchV=start.getElementsByTagName(topTag);
      else searchV=start.getElementsByTagName('*');

    if (!topTag||!topClass) { if (searchV.length) returnObject[i]=searchV[0]; continue; } // skip search Tag

    for (j=0; j<searchV.length; j++)
      if (searchV[j][tagNameS]==topTag) { returnObject[i]=searchV[j]; break; } // pointing search Tag
    }

      }
// end of getElementsByClassName

  else {
// start of not ClassName
// graped by same tagname

  while (waitingClass.length) {
    topTag=waitingTag[0];
    topClass=waitingClass[0];

    sameValue.length=0;
    for (i=0; i<waitingClass.length; i++) if (topTag==waitingTag[i]) sameValue.push(i);

    searchV=start.getElementsByTagName(topTag?topTag:'*');
    for (i=0; i<searchV.length; i++) {
      for (j=0; j<sameValue.length; ) {
        nowPoint=sameValue[j]
        if ((!(nowClass=waitingClass[nowPoint]))||(searchV[i].className==waitingClass[nowPoint])) {
          returnObject[waitedNumber[nowPoint]]=searchV[i];
          pointPop(waitingTag, nowPoint);
          pointPop(waitingClass, nowPoint);
          pointPop(waitedNumber, nowPoint);
          pointPop(sameValue, j);
          } else j++;
        }
      if (!sameValue.length) break;
      }

    sameValue.sort();
//    for (i=0; i<sameValue.length; i++) {
    for (i=sameValue.length-1; i>=0; i--) {
      pointPop(waitingTag, sameValue[i]);
      pointPop(waitingClass, sameValue[i]);
      pointPop(waitedNumber, sameValue[i]);
      }
    }

  }
// end of not ClasName

  return returnObject;
  }

// 주변 tag 끌어들이기

function searchSameLevelStyletoArrays101127_1(start) {
  var childValue=start.parentNode.childNodes, startTag=start.tagName, startClass=start.className, returnArray=[], nowChild;

  for (i=0; i<childValue.length; i++) {
    nowChild=childValue[i];
    if ((nowChild.tagName==startTag)&&(nowChild.className==startClass)) returnArray.push(nowChild);
    }
  return returnArray;
  }
</SCRIPT>
<br />
<DIV class=d101127_1>101127_1
<DIV class=d101127_2 style="MARGIN:5px" >101127_2 </DIV></DIV>
<DIV class=d101127_1>101127_1 - 2
<DIV class=d101127_2 style="MARGIN:5px" >101127_2 - 2 </DIV></DIV>
<br />

<SCRIPT>
function sample101127_1() {
  var outv=searchFirstStyletoArray101127_1( document, 'DIV.d101127_1', 'DIV.d101127_2' ),
    outv1=searchSameLevelStyletoArrays101127_1(outv[0]),
    outv2=searchSameLevelStyletoArrays101127_1(outv[1]),
    i;

  document.write( document.all?outv[0].innerText:outv[0].textContent );
  document.write( '<'+'br/>');
  document.write( document.all?outv[1].innerText:outv[1].textContent );
  document.write( '<'+'br/>');
  document.write( '<'+'br/>');

  for (i=0; i<outv1.length; i++)
    document.write( (document.all?outv1[i].innerText:outv1[i].textContent)+',' );
  document.write( ' ['+i+']'+'<'+'br/>');

  for (i=0; i<outv2.length; i++)
    document.write( (document.all?outv2[i].innerText:outv2[i].textContent)+',' );
  document.write( ' ['+i+']'+'<'+'br/>');

  }

sample101127_1();
</SCRIPT>
<br />


...


101127_1
101127_2
101127_1 - 2
101127_2 - 2



...

* 구조설명 *

- searchFirstStyletoArray101127_1(fromElement, 'TAG.classname0', 'TAG.classname1', ...)

document.getElementsByClassName 함수가 있으면 해당 클래스 검색을 시작해서
태그가 같은 경우를 잡아내고,

함수가 없으면 document.getElementsByTagName 을 이용해서 해당 태그를 검색시작하고
클래스명이 같은 경우를 집어냈다.

... 사실, getElementsByTagName 으로 통일시켜도 되기는 했지만,
생각해보니 class 적용되는 경우가 tag 적용 되는 경우보다 적을 것 같아서...

... 추가로...
getElementsByClass 함수가 있는 경우에는 적용을 안했지만,

같은 태그가 있는 경우, 검색을 최대한 줄이려고, 같은이름 태그를 먼저 추적(?)하도록 했다.
= =;... 생각해보니... 태그명 없는 검색을 뒤로 물러놔도 좋을 걸 그랬어...

...

- searchSameLevelStyletoArrays101127_1(start)

해당 태그의 parentNode (parentElement) 에 있는 childNodes 를 이용해서
무작정(?) 너 나랑 동류냐? 를 묻고, 집어내는 함수.

이 경우에도 getElementsByClassName 이나 getElementsByTagName ... 형식으로 검색하면 좋겠지만,
= =;... 같은 레벨의 경우에는 childNode 사용하는 게 훨 빠를 것 같아서 이 방법을 선택했다.

...

만들고나니(?) 허탈했다고 해야할지, 수고했다고 해야할지 ㅎㅎ;...

뭐... 태그만 검색하기 위해 만든 함수가 아니라서...
태그만 입력하면 오류나겠지만...

(= =;)... 뭐, 그건 그렇다 치고...

...

원래 jQuery 쪽에도 있을만한 함수라
그쪽에 있는 .js 내용들을 분석하고, ...해서

getElementsByClassName 함수의 존재여부에 따른 방법론을 뽑아쓰긴 했지만,

...

그게 생각처럼 분석이 되지 않아서

$() 함수처럼 prototype 에 적용시킬 방법을 모르겠고,
= =;... 아직 prototype 쪽은 잘 몰라서,

끄적끄적 이렇게 만들어버렸다.

*참고* jQuery 에는 $('TAG.class#id') 형식의 검색이 가능한 것으로 알고있다.
(아직 안써보고 있음...) ㅜ.ㅜ... 부러워...

...

*추가수정* '11.01.27 09:05

    sameValue.sort();
//    for (i=0; i<sameValue.length; i++) {
    for (i=sameValue.length-1; i>=0; i--) {
      pointPop(waitingTag, sameValue[i]);
      pointPop(waitingClass, sameValue[i]);
      pointPop(waitedNumber, sameValue[i]);
      }
    }

처음에 for (i=0; i<sameValue.length; i++) {} 형식으로 삭제를 했는데,
pointPop 의 경우 최종값을 옮겨서 삭제하는 형식을 띄고있던 걸 깜빡하고 있었음.

결국... 소스 수정 OTL...

...

*추가수정* '11.10.30 22:35
 // if (document.getElementsByClassName) {
  if (start.getElementsByClassName) {

start 라는 element 를 받아서 적용하는 과정에
document element 에는 해당 함수가 있지만, start 라는 element 에는 함수가 없어
있는지 없는지 직접 체크하도록 적용.

...

NowMark killofki@.


Posted by killofki
,