jQuery Selector로 iframe 제어하는 방법

jQuery를 이용해 iframe 내에서 부모 document 그리고 부모 document 내에 존재하는 다른 iframe에 접근하는 방법을 우선 정리해보고 이를 응용할 수 있는 예시를 한 번 더 정리해보겠습니다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Code Sample</title>
  </head>
  <body>
    <div id="content">Content Sample</div>
    
    <iframe id="frameA" src="[frameA]"></iframe>
    <iframe id="frameB" src="[frameB]"></iframe>
  </body>
</html>

iframe 내에서 부모 document 접근 방법

<script>
  // 부모 도큐멘트에서 #content 엘리먼트를 참조하여 hide() 처리
  var parentDocumentContent = $("#content", parent.document);
  parentDocumentContent.hide();
</script>

iframe 내에서 부모 document의 다른 iframe 접근

<script>
  // 부모 도큐멘트의 #frameB iframe 내 #frameBContent 엘리먼트를 참조하여 hide() 처리
  var frameBContent = $("#frameBContent", parent.frames["frameB"].document);
  frameBContent.hide();
</script>

응용 : iframe 내 document의 height 값을 구해 iframe의 height 값을 세팅

<script>
// This iframe name is "contentFrame"

$(document).ready(function(){
  
  // 현재 document를 불러오는 iframe의 selector를 정의한다.
  var thisFrame = $("#contentFrame", parent.document);
  
  // 현재 document의 height 값을 정의한다.
  var documentHeight = $(document).height();

  // 부모 document에서 iframe을 thisFrame에 정의된 selector로 참조하여 iframe의 height값을 css로 설정한다.
  thisFrame.css("height", documentHeight + "px");
});
</script>

jQuery를 버리고 Vanilla JS로 옮겨타고 싶지만 제 자신이 너무 오랜 시간 jQuery에 익숙해진 듯 합니다.

그래서 다음 포스팅에서는 제가 주로 사용하는 jQuery 문법들을 정리하고 이에 대응하는 Vanilla JS 표현식을 알아보도록 하겠습니다.

[jQuery] 선택된 select의 option text 가져오는 방법

예전에 선택된 radio 버튼의 값을 가져오는 방법에 대해 포스팅을 한 적이 있습니다.

조금은 성격이 비슷한 내용이지만 이번에는 select box의 value 값이 아닌 option 에 담겨 있는 텍스트를 가져오는 방법을 소개 합니다.

보통 select의 선택된 값을 가져오기 위해서는 이런 방법을 사용합니다.

select_box라는 ID를 가진 셀렉트박스의 change 이벤트. 즉, 선택을 하게 되면 콘솔 로그로 선택된 요소의 value값을 출력하는 예제입니다.

그런데 여기서 value값이 아닌 text를 가져오려면 방법이 다릅니다. text라 함은 select 안에 존재하는 option 태그를 예로 들어보겠습니다.

value에 담긴 1, 2, 3이 아닌 option 태그에 담겨진 1번, 2번, 3번을 가져오는 것입니다.

 

그럼 위 처럼 코드를 작성해보겠습니다.

코드가 조금 길어졌습니다. 우선 해석부터 하자면 “선택 된 option의 value에 해당하는 text를 가져와라” 입니다.

$(this) 뒤에 추가적인 셀렉터를 붙일 수 없기 때문에 find() 메소드를 이용해 자식요소를 찾습니다. 만약 첫번째 option을 선택했다면 셀렉터는 $(this).find(“option[value=’1′]) 이 될 것입니다. 이 선택된 요소에서 text() 메소드를 이용해 option 태그 안에 담겨진 문자열을 가져옵니다.

[jQuery] input text 클릭 시 텍스트 전체 선택하는 방법

간단하지만 단 한번의 구글링이라도 자비 없이 포스팅 합니다.

웹 페이지에서 텍스트를 입력할 수 있는 input text 상자를 클릭하면 텍스트를 모두 선택하는 간단한 내용입니다.

텍스트 복사나 선택을 구현할 때 혹은 귀찮을때 종종 사용합니다.

아래 처럼 input 박스가 있다고 가정합니다.

 

위 텍스트를 클릭하면 전체 선택이 되는 코드는 아래와 같습니다.

 

해당 요소의 텍스트를 .select() 메소드를 이용해서 선택이 가능합니다.

[jQuery] .on 이벤트에 파라미터 전달하는 방법

이벤트 처리 시 사용하고자 하는 변수가 전역변수라면 상관이 없지만 지역변수인 경우 인자로 정의를 해주어야 합니다.

전역변수를 .on 이벤트 핸들러에서 사용 시

 

지역변수를 .on 이벤트 핸들러에서 사용 시

 

이벤트 타입 인자 뒤에 JSON 형태로 파라미터를 추가해주시면 위와 같이 지역변수값을 전달받을 수 있습니다.

[jQuery] IE에서 scrollTop animate 효과 동작하지 않는 문제 해결 방법

흔히 버튼을 클릭하여 스크롤을 부드럽게 이동시키는 효과는 animate를 이용하여 scrollTop 속성을 변화시킵니다.

이때 IE에서는 코드가 동작하지 않는 경우가 있습니다. 아래 코드는 IE에서 동작하지 않습니다.

scrollTop 속성에 0을 부여해 문서를 최상단으로 이동시키는 스크립트 입니다. 크롬이나 파이어폭스에서는 동작하지만 IE에서는 동작하지 않습니다.

 

그렇다면 이 코드를 동작하도록 수정해보겠습니다.

크게 바뀐 부분은 없습니다. 셀렉터 부분이 “html body”에서 “html, body”로 변경된 것 뿐입니다. IE에서는 “html body” 셀렉터를 인식하지 못하는 문제를 가지고 있는 것으로 보입니다. 더 정확하게는 body 셀렉터를 인식하지 못합니다. 반대로 크롬에서는 html 셀렉터를 지정하지 못합니다.

따라서 html안에 body를 뜻하는 “html body”가 아닌 html과 body를 뜻하는 “html, body”로 셀렉터를 지정해주셔야 대부분의 브라우저를 커버할 수 있습니다.

[jQuery] 폼 전송시 “maximum call stack size exceeded” 에러 해결 방법

로그인 폼을 만들어 테스트하는 도중 콘솔에서 아래 에러 메세지가 출력됩니다.

“maximum call stack size exceeded” (IE에서는 “스택 공간 부족”으로 출력)

발생한 위치는 jQuery 코어 파일이었고 이 뜻은 jQuery 자체 문제라기보다는 어디선가 잘못 사용되고 있을거란 확률이 컸습니다.

일반적으로 위 에러가 출력되는 경우는 크게 2가지 입니다.

  1. 동일한 스크립트(.js) 파일을 중첩되게 호출한 경우
  2. 잘못된 코드로 인해 무한 루프를 도는 경우

두가지 문제를 점검해보았지만 정답은 아니었습니다. 검색을 해보니 로그인 폼에 사용된 submit 이벤트 문제일 것이라는 단서를 발견 했습니다.

jquery에서 사용되는 submit 이벤트는 submit이 발생할때까지 반복적으로 재귀호출을 하게 되며 이 때문에 무한 루프에 빠질 수 있습니다. 이는 일반적인 경우는 아닙니다.

제 경우에는 iframe을 이용해 다른 서버의 페이지에서 로그인 폼을 출력했고 그 iframe 내에서 submit 이벤트를 처리하면서 문제가 발생한 것이었습니다.

이 이슈에 대한 수정 전 코드와 수정 후 코드입니다.

[수정 전]

 

[수정 후]

 

위 코드에 대해 간략하게 설명하자면 Form의 submit 이벤트 대신 로그인 버튼에 click 이벤트를 패스워드 입력 필드에 keypress 이벤트를 추가한 것입니다.

submit 을 사용한다면 폼 내부에서 엔터를 치게되면 submit 버튼이 이벤트를 받아 작동하지만 click 을 사용한다면 직접 마우스로 버튼을 클릭해야 합니다. 따라서 엔터키를 쳤을때 동일하게 동작하도록 이벤트를 추가해준 것입니다.

이로써 “스택 공간 부족” 에러는 해결이 됩니다. 하지만 저처럼 iframe으로 폼을 처리하는 경우라면 추가로 처리해줄 것이 있습니다.

 

CORS (Cross-Origin Resource Sharing) 즉, 크로스 도메인 허용 처리, 그리고 제3자 쿠키(P3P) 헤더 처리입니다.

  1. CORS 처리 : HTTP 헤더에 “Access-Control-Allow-Origin” 추가
    (PHP인 경우 Header(“Access-Control-Allow-Origin: 허용할 도메인명 또는 *”); 코드 추가)
  2. P3P 헤더 (제3자 쿠키) 추가
    (PHP인 경우 Header(“p3p: CP=\”CAO DSP AND SO ON\” policyref=\”/w3c/p3p.xml\””); 코드 추가)

[jQuery] 스크립트로 select option 선택/변경하는 방법

jQuery를 이용해 select의 옵션을 원하는대로 변경하는 방법을 소개해드립니다.

이런 경우 사용이 되겠습니다.

  1. 옵션을 선택하고 다시 셀렉트 박스를 초기화 해야하는 경우
  2. 버튼을 클릭하거나 특정 이벤트가 발생하는 경우 자동으로 셀렉트 박스의 옵션을 변경해야 하는 경우

 

코드는 아래와 같습니다.

방법1. on change 이벤트 함수 내 사용하는 경우

 

방법2. 외부 스크립트에서 select의 값을 변경하는 경우

 

prop 대신 attr을 사용하는 예도 검색해보면 찾아볼 수 있는데 attr은 스크립트로 추가된 엘리먼트는 컨트롤 할 수 없습니다.

때문에 prop을 통해 컨트롤 하시는 것을 권장 합니다.

[jQuery] 팝업창으로 POST 폼 전송하는 방법

팝업창으로 폼을 전송하는 경우가 종종 있어 정리합니다.

form 구성은 위와 같습니다. 일반적으로 사용할때와 좀 다른 점은 target 을 사용한다는 것인데 이는 frame이나 iframe으로 폼 전송을 할 때도 동일합니다.

 

전송 버튼을 클릭시 popup_window라는 이름의 빈 팝업창을 띄우고 myform이라는 폼을 submit 시킵니다. form의 target 값을 읽어 popup_window라는 팝업창으로 폼 전송을 하게 됩니다.

get으로 팝업창에 폼 전송을 하는 경우는 url뒤에 파라미터를 넣어주는 것으로 간단하게 해결이 되지만 post의 경우는 이런 방법을 사용해 구현 할 수 있습니다.

자주 쓰진 않는 방법이라 참고하시면 가끔 유용할 수 있습니다.

[JS] 중첩된 문자열 제거하는 방법

한 텍스트 구문에서 중첩되는 문자열을 제거하는 함수입니다.

예를 들어 “사과;;;바나나;;파인애플;배;;;포도;” 라는 문자열이 있을때 중복된 세미콜론을 제거하고 하나의 세미콜론만 가지게 하고 싶습니다. 즉, “사과;바나나;파인애플;배;포도;” 로 변환하고자 합니다.

이 때 흔히 아래와 같이 replace를 이용해 치환합니다.

하지만 결과는 “사과;;바나나;파인애플;배;;포도;” 가 될 것입니다. replace가 한 번 더 실행되어야 원하는 결과를 얻을 수 있습니다. 중첩문자(세미콜론)이 3개 있을땐 2번, 4개 있을땐 3번 replace가 실행되어야 하는데 이 말의 의미는 반목문(loop)를 실행해야 한다는 것입니다.

중첩문자를 제거하기 위한 함수를 아래와 같이 만들어 봤습니다.

 

이 함수의 사용 예는 다음과 같습니다.

* 참고로 함수 내용안에 jQuery 셀렉터가 사용되고 있기 때문에 jQuery 라이브러리가 필요합니다.

[jQuery] draggable 스크롤바 버그 문제 해결 방법

jQuery ui에는 draggable라는 드래그 메소드가 있습니다. 아래와 같이 원하는 앨리먼트에 지정해주면 마우스 드래그로 이동이 가능하게 됩니다.

하지만 draggable 기능에 문제가 하나 발결되었습니다. 예를 들어 myDiv라는 영역안에 iframe이나 overflow:scroll 속성이 있는 요소가 존재하는 경우 스크롤바가 생성될겁니다. 문제는 이 스크롤바를 클릭하면 draggable 이 적용된 부모 앨리먼트가 드래그 상태가 풀리지 않는 상태로 마우스를 계속 따라다니게 됩니다. 이를 해제하는 방법은 새로고침이나 오른쪽 클릭을 해야만 풀립니다;;

이 문제를 원천적으로 해결하는 방법은 앨리먼트 내 draggable이 동작하는 유효한 요소를 지정해주는 것입니다.

위 처럼 구성이 되어있다고 가정했을때 가장 쉽게 생각하는 방법이 $(“#myDiv”).draggable(); 일겁니다. 하지만 이렇게되면 스크롤이 존재하는 div, iframe도 드래그 동작에 유효하여 문제가 발생합니다.

 

그렇다면 이렇게 처리합니다.

$(“#myDiv”).draggable()에 handle 속성을 추가합니다. 이후로는 myDiv를 드래그할 수 있는 주체는 dragWindowTitle이라는 클래스를 가진 요소만 존재하게 됩니다.

 

반대로 “한가지 요소만 제외하고 나머지 요소들은 드래그 동작이 되도록 하고 싶다.”라고 한다면 아래처럼 설정해주시면 됩니다.

draggable에  cancel 속성을 추가해주게 되면 cancel로 지정된 요소만 드래그를 해도 동작하지 않도록 제외시킬 수 있습니다.