Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

개발자입니다

[비트캠프] 32일차(7주차2일) - jQuery(자바스크립트 라이브러리 만들기2, minify) 본문

네이버클라우드 AIaaS 개발자 양성과정 1기/Javascript

[비트캠프] 32일차(7주차2일) - jQuery(자바스크립트 라이브러리 만들기2, minify)

끈기JK 2022. 12. 20. 15:43

 

메서드와 파라미터

 

그림 왼쪽 : hello() 함수 정의 = 연산자 정의

그림 오른쪽 : hello는 메서드(함수) = operator(연산자) 이다. ++a 에서 ++과 같이 작업수행 부분이다.

                      ("홍길동")은 파라미터이다. ++a 에서 a와 같이 작업을 수행할 때 사용할 데이터이다.

++a에서 ++는 연산자(operator)이고 a는 피연산자(operand)이다.

 

 

 

메서드와 객체

 

-우측 상단 그림 : let obj = new Greeting("홍길동"); 하면 new로 ① 빈 객체 생성해서 Greeting() 에 주소 200 넘겨주고, 주소 200을 obj에 저장한다. ② object() 가 초기화, ③ Greeting() 이 초기화 시킨다.

new로 인스턴스를 생성하면 그 주소가 리턴된다.

-좌측 상단 그림 : this는 생성한 인스턴스의 주소를 가리킨다.

-좌측 하단 그림 : this는 생성한 인스턴스의 주소를 가리킨다.

-우측 하단 그림 : obj.hello("평어")는 이렇게 동작한다.

obj 는 메서드가 사용할 데이터이며 주데이터(피연산자)이다. obj 주소 200이 hello(변수 this)에 전달된다.

hello는 메서드(작업수행)이며 연산자이다.

("평어")는 메서드가 작업을 수행할 때 사용할 데이터이며 보조데이터(피연산자)이다.

 

함수를 정의한다 : 자신만의 연산자를 만든다.

 

 

jQuery 만들기 - 9. click()

.on('click', () => { 를 아래와 같이 바꾼다.

$("#btn1").click(() => {
// jQuery-09.js 추가

  el.click = function (handler) {
    for (let e of el) {
      this.on('click', handler);
    }
    return this;
  }

 

전체 코드

// jQuery-09.js

function jQuery(selector) {
  let el = [];  // 생성한 태그나 찾은 태그를 담는 배열

  if (selector.startsWith("<")) {
    el[0] = document.createElement(selector.substring(1, selector.length - 1));

  } else {
    let nodeList = document.querySelectorAll(selector);
    for (let e of nodeList) {
      el.push(e);
    }
  }


  el.append = function (childBox) {
    // 자식 태그를 복제해서 각 부모 태그에 붙인다.
    for (let parent of el) {

      // 자식들이 들어있는 상자에서 자식을 한 개씩 꺼내 복제하여 각 부모의 자식으로 붙인다.
      for (let child of childBox) {
        parent.appendChild(child.cloneNode(true));
      }
    }

    // 자식 태그는 제거한다.
    for (let child of childBox) {
      if (child.parentElement != null || child.parentElement != undefined) {
        child.parentElement.removeChild(child);

      }
    }

    return el;
  };

  el.appendTo = function (parents) {
    // 자식 태그를 복제해서 각 부모 태그에 붙인다.
    for (let parent of parents) {

      // 자식들이 들어있는 상자에서 자식을 한 개씩 꺼내 복제하여 각 부모의 자식으로 붙인다.
      for (let child of el) {
        parent.appendChild(child.cloneNode(true));
      }
    }

    // 자식 태그는 제거한다.
    for (let child of el) {
      if (child.parentElement != null || child.parentElement != undefined) {
        child.parentElement.removeChild(child);

      }
    }

    return this;
  };

  el.html = function (content) {
    for (let e of el) {
      e.innerHTML = content;
    }

    return this;
  };

  el.on = function (eventName, listener) {
    for (let e of el) {
      e.addEventListener(eventName, listener);
    }

    return this;
  };

  el.click = function (handler) {
    for (let e of el) {
      this.on('click', handler);
    }
    return this;
  }


  return el;
}

var $ = jQuery;

 

 

jQuery 만들기 - 10. 리팩토링

html 수정 없이 jQuery 리팩토링 한다.

var tbody = $("tbody");

$("#btn1").click(() => {
    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = () => {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                var arr = JSON.parse(xhr.responseText);

                for (var b of arr) {
                    $("<tr>")
                        .html("<td>" + b.no + "</td>" +
                            "<td>" + b.title + "</td>" +
                            "<td>" + b.writer + "</td>" +
                            "<td>" + b.viewCnt + "</td>")
                        .appendTo(tbody);
                }
            } else {
                alert('데이터 요청 오류!');
            }
        }
    };
    xhr.open("GET", "http://localhost:3000/exam04-3", true);
    xhr.send();
});

생성자를 정의한다. jQuery 함수 호출시마다 메서드 만들지 말고 생성자의 prototype에 공통 메서드 정의한다.

// jQuery-10.js

function jQuery(selector) {
  return new ElementBox(selector);
}

function ElementBox(selector) {
  this.el = [];  // 생성한 태그나 찾은 태그를 담는 배열

  if (selector.startsWith("<")) {
    this.el[0] = document.createElement(selector.substring(1, selector.length - 1));

  } else {
    let nodeList = document.querySelectorAll(selector);
    for (let e of nodeList) {
      this.el.push(e);
    }
  }
}

ElementBox.prototype.append = function (childBox) {
  for (let parent of this.el) {
    for (let child of childBox.el) {
      parent.appendChild(child.cloneNode(true));
    }
  }

  for (let child of childBox) {
    if (child.parentElement != null || child.parentElement != undefined) {
      child.parentElement.removeChild(child);

    }
  }

  return this;
};

ElementBox.prototype.appendTo = function (parentBox) {
  for (let parentTag of parentBox.el) {
    for (let child of this.el) {
      parentTag.appendChild(child.cloneNode(true));
    }
  }

  for (let child of this.el) {
    if (child.parentElement != null || child.parentElement != undefined) {
      child.parentElement.removeChild(child);

    }
  }

  return this;
};

ElementBox.prototype.html = function (content) {
  for (let e of this.el) {
    e.innerHTML = content;
  }

  return this;
};

ElementBox.prototype.on = function (eventName, listener) {
  for (let e of this.el) {
    e.addEventListener(eventName, listener);
  }

  return this;
};

ElementBox.prototype.click = function (handler) {
  return this.on('click', handler);
};

var $ = jQuery;

jQuery('#btn1') 하면 ElementBox의 인스턴스가 생성되고 변수 btn에 주소가 전달된다.

 

 

jQuery 만들기 - 11. ajax()

jQuery로 ajax 아래처럼 구현한다.

$("#btn1").click(() => {
    $.ajax({
        url: "http://localhost:3000/exam04-3",
        method: "GET",
        dataType: "json",
        async: true,
        success: (result) => {

            for (var b of result) {
                $("<tr>")
                    .html("<td>" + b.no + "</td>" +
                        "<td>" + b.title + "</td>" +
                        "<td>" + b.writer + "</td>" +
                        "<td>" + b.viewCnt + "</td>")
                    .appendTo(tbody);
            }
        },
        error: () => {
            alert('데이터 요청 오류!')
        }
    });
});
// jQuery-11.js 추가

jQuery.ajax = function (settings) {
  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = () => {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        let result;

        if (settings.dataType == "json") {

          // json string ---> javascript object (deserialize)
          result = JSON.parse(xhr.responseText);

        } else {
          result = xhr.responseText;
        }
        settings.success(result);

      } else {
        settings.error();
      }
    }
  };
  xhr.open(settings.method, settings.url, settings.async);
  xhr.send();
};

 

 

jQuery 만들기 - 12. ajax() 코드 정리

11. 에서 method, async 미지정시 default로 "GET", true 지정하도록 jQuery-12.js 수정한다.

$("#btn1").click(() => {
    $.ajax({
        url: "http://localhost:3000/exam04-3",
        dataType: "json",
        success: (result) => {

            for (var b of result) {
                $("<tr>")
                    .html("<td>" + b.no + "</td>" +
                        "<td>" + b.title + "</td>" +
                        "<td>" + b.writer + "</td>" +
                        "<td>" + b.viewCnt + "</td>")
                    .appendTo(tbody);
            }
        }
    });
});
// jQuery-12.js 수정

jQuery.ajax = function (settings) {
  if (settings.method == undefined) settings.method = "GET";
  if (settings.async == undefined) settings.async = true;

  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = () => {
    if (xhr.readyState == 4) {
      if (xhr.status == 200) {
        if (settings.success == undefined) {
          return;
        }
        let result;

        if (settings.dataType == "json") {
          result = JSON.parse(xhr.responseText);

        } else {
          result = xhr.responseText;
        }
        settings.success(result);

      } else {
        if (settings.error == undefined) {
          return;
        }
        settings.error();
      }
    }
  };
  xhr.open(settings.method, settings.url, settings.async);
  xhr.send();
};

 

 

jQuery 만들기 - 13. get.JSON()

get 방식은 getJSON 함수를 통해 요청하도록 한다.

$("#btn1").click(() => {
    $.getJSON("http://localhost:3000/exam04-3", (result) => {
        for (var b of result) {
            $("<tr>")
                .html("<td>" + b.no + "</td>" +
                    "<td>" + b.title + "</td>" +
                    "<td>" + b.writer + "</td>" +
                    "<td>" + b.viewCnt + "</td>")
                .appendTo(tbody);
        }
    });
});
// jQuery-13.js 추가

jQuery.getJSON = function (url, success) {
  jQuery.ajax({
    url: url,
    dataType: "json",
    success: success
  })
};

 

 

jQuery 만들기 - 13. get.JSON() : forEach()로 배열 다루기

for를 forEach로 바꾼다.

$("#btn1").click(() => {
    $.getJSON("http://localhost:3000/exam04-3", (result) => {
        result.forEach((b) => {
            $("<tr>")
                .html("<td>" + b.no + "</td>" +
                    "<td>" + b.title + "</td>" +
                    "<td>" + b.writer + "</td>" +
                    "<td>" + b.viewCnt + "</td>")
                .appendTo(tbody);
        });
    });
});

 

 

jQuery 만들기 - 14. val(), html()

이메일, 암호 전송하는 html이다.

.val() 에 인자 전달하지 않으면 getter로 동작하며, 인자 전달하면 setter로 동작한다.

<form id="login-form">
    이메일: <input type="email" name="email" value="hong@gmail.com"><br>
    암호: <input type="password" name="password"><br>
    <button type="button" id="btn1">로그인</button>
    <button type="button" id="btn2">취소</button>
</form>

<script>
$("#btn1").click(() => {
    let email = $("#login-form > input[name='email']").val();
    let password = $("#login-form > input[name='password']").val();
    console.log(email, password);
});

$("#btn2").click(() => {
    let email = $("#login-form > input[name='email']").val("");
    let password = $("#login-form > input[name='password']").val("");
    console.log(email, password);
});

jQuery 함수는 값을 꺼내는 함수(getter) 따로 넣는 함수(setter) 따로 있지 않다. 한 함수에서 값을 넣고 꺼내는 일을 한다.
파라미터 값이 있으면 값을 넣는 일을 하고, 파라미터 값이 없으면 꺼내는 일을 한다.

// jQuery-14.js

ElementBox.prototype.val = function (value) {
  if (this.el.length == 0) {
    return;
  }

  if (arguments.length > 0) {
    // 값을 설정할 때는 모든 태그에 대해 수행한다.
    for (let e of this.el) {
      e.value = value;
    }
    return this;

  } else {
    // 값을 꺼낼 때는 맨 처음 태그 값만 꺼낸다.
    return this.el[0].value;
  }
};

 

 

jQuery 만들기 - 15. submit(), ajax() : POST 요청

button에 type 지정하지 않으면 기본 type은 submit이다. 취소 버튼 type은 reset으로 지정한다.

submit시 ajax() 실행되게 하며 인자로 객체에 url, method, dataType, data, success 담아 전달한다.

<form id="login-form">
    이메일: <input type="email" name="email"><br>
    암호: <input type="password" name="password"><br>
    <button>로그인</button>
    <button type="reset">취소</button>
</form>

<script>
var tbody = $("tbody");

$("#login-form").submit((e) => {
    $.ajax({
        url: "http://localhost:3000/login",
        method: "POST",
        dataType: "text",
        data: {
            email: $("#login-form > input[name='email']").val(),
            password: $("#login-form > input[name='password']").val()
        },
        success: function () { }
    })

    // 따로 AJAX 요청을 할 것이기 때문에, 웹브라우저가 서버에 요청하는 것은 막는다.
    e.preventDefault();
});

 

"POST" 방식일때 setRequestHeader 부분 추가하며, payload에 데이터 담아서 encodeURIComponent 사용해 전달한다.

// jQuery-15.js 수정

jQuery.ajax = function (settings) {

	...

  // 아래 부분 수정
  if (settings.method == "POST") {
    xhr.setRequestHeader(
      "Content-Type",
      "application/x-www-form-urlencoded");

    let payload = "";
    if (settings.data != undefined && settings.data != null) {
      for (let key in settings.data) {
        if (payload.length > 0) {
          payload += "&";
        }
        payload += key + "=" + window.encodeURIComponent(settings.data[key]);  // encodeURI 사용
      }
    }
    xhr.send(payload);

  } else {
    xhr.send();
  }

 

post 전달을 위해 서버쪽 작업을 한다.

// app.js 추가

app.post('/login', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Content-Type', 'text/plain;charset=UTF-8');

  var payload = `이메일: ${req.body.email}\n`;
  payload += `암호: ${req.body.password}\n`;

  res.send(payload);
});

Payload에 데이터 나타난다.

 

 

jQuery 만들기 - 16. post()

$.ajax() 에서 $.post(요청주소, 데이터, 성공시 실행 함수) 로 바로 POST 요청한다.

$("#login-form").submit((e) => {
    $.post("http://localhost:3000/login", {
        email: $("#login-form > input[name='email']").val(),
        password: $("#login-form > input[name='password']").val()
    }, (result) => {
        console.log(result);
    });

    e.preventDefault();
});

.post 메서드는 생성자 함수로 바로 등록한다.

// jQuery-16.js 추가

jQuery.post = function (url, data, success, dataType) {
  jQuery.ajax({
    url: url,
    method: "POST",
    dataType: dataType,
    data: data,
    success: success
  });
};

 

 

jQuery 만들기 - 17. 자바스크립트 파일 압축

minifier 사용하여 공백, 엔터, 긴 변수명 줄여서 압축 시킨다.

// jQuery-16min.js

function jQuery(e){return new ElementBox(e)}function ElementBox(e){if(this.el=[],e.startsWith("<"))this.el[0]=document.createElement(e.substring(1,e.length-1));else{let t=document.querySelectorAll(e);for(let n of t)this.el.push(n)}}ElementBox.prototype.append=function(e){for(let t of this.el)for(let n of e.el)t.appendChild(n.cloneNode(!0));for(let o of e)(null!=o.parentElement||void 0!=o.parentElement)&&o.parentElement.removeChild(o);return this},ElementBox.prototype.appendTo=function(e){for(let t of e.el)for(let n of this.el)t.appendChild(n.cloneNode(!0));for(let o of this.el)(null!=o.parentElement||void 0!=o.parentElement)&&o.parentElement.removeChild(o);return this},ElementBox.prototype.html=function(e){if(0!=this.el.length){if(!(arguments.length>0))return this.el[0].innerHTML;for(let t of this.el)t.innerHTML=e;return this}},ElementBox.prototype.on=function(e,t){for(let n of this.el)n.addEventListener(e,t);return this},ElementBox.prototype.click=function(e){return this.on("click",e)},ElementBox.prototype.val=function(e){if(0!=this.el.length){if(!(arguments.length>0))return this.el[0].value;for(let t of this.el)t.value=e;return this}},ElementBox.prototype.submit=function(e){return this.on("submit",e)},jQuery.ajax=function(e){void 0==e.method&&(e.method="GET"),void 0==e.async&&(e.async=!0);var t=new XMLHttpRequest;if(t.onreadystatechange=()=>{if(4==t.readyState){if(200==t.status){if(void 0==e.success)return;let n;n="json"==e.dataType?JSON.parse(t.responseText):t.responseText,e.success(n)}else{if(void 0==e.error)return;e.error()}}},t.open(e.method,e.url,e.async),"POST"==e.method){t.setRequestHeader("Content-Type","application/x-www-form-urlencoded");let n="";if(void 0!=e.data&&null!=e.data)for(let o in e.data)n.length>0&&(n+="&"),n+=o+"="+window.encodeURIComponent(e.data[o]);t.send(n)}else t.send()},jQuery.getJSON=function(e,t){jQuery.ajax({url:e,dataType:"json",success:t})},jQuery.post=function(e,t,n,o){jQuery.ajax({url:e,method:"POST",dataType:o,data:t,success:n})};var $=jQuery;

'javascript minify' 검색해서 사용한다.

https://www.toptal.com/developers/javascript-minifier

 

 

jQuery 만들기 - 18. 오리지널 jQuery 사용하기

HTML에 다음 script 추가하면 jQuery 사용할 수 있다.

3.x.x 버전은 2.x.x 이하 버전에 있던 메서드나 변수 중 deprecated 되어 삭제된게 있을 수 있다.

실습하며 작성했던 html 코드에 오리지널 jQuery 소스 첨부해도 잘 돌아간다.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<script>
    "use strict"
    var tbody = $("tbody");

    $("#login-form").submit((e) => {
        $.post("http://localhost:3000/login", {
            email: $("#login-form > input[name='email']").val(),
            password: $("#login-form > input[name='password']").val()
        }, (result) => {
            console.log(result);
        });

        e.preventDefault();
    });

</script>
<table border="1">
    <thead>
        <tr>
            <th>번호</th>
            <th>제목</th>
            <th>작성자</th>
            <th>조회수</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>
<button id="btn1">데이터 가져오기!</button>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script>
    "use strict"
    var tbody = $("tbody");

    $("#btn1").click(() => {
        $.getJSON("http://localhost:3000/exam04-3", (result) => {
            result.forEach((b) => {
                $("<tr>")
                    .html("<td>" + b.no + "</td>" +
                        "<td>" + b.title + "</td>" +
                        "<td>" + b.writer + "</td>" +
                        "<td>" + b.viewCnt + "</td>")
                    .appendTo(tbody);
            });
        });
    });

</script>

 

 

UI control시

jQuery는 javascript가 주도하는 방식이다.

Bootstrap은 CSS가 주도하는 방식이다.

 

 


 

조언

 

*

 

 


 

과제

 

/