반응형

1. 개요

 Table 생성 후 셀마다 셀 테두리를 설정하였으나, 셀 테두리 사이 간격이 생기는 현상이 발생하고 있음.

셀 테두리가 벌어짐


2. 해결

 table 태그에 대한 css로 border-collapse : collapse 설정을 적용하면 표의 테두리 및 셀간 테두리 간격을 없애고, 겹치는 부분은 한줄로 표시.

1
2
3
4
5
6
7
8
9
10
table{
    border : 1px solid black;
    border-collapse : collapse;
}
 
td,th{
    border : 1px solid black;
    width : 100px;
    height : 30px;
}
cs

3. 결과

border-collapse : collapse 적용

반응형

'프론트엔드 > CSS' 카테고리의 다른 글

[CSS] !important 란?  (1) 2019.07.26
CSS의 등장배경  (0) 2019.06.19
반응형

ajax 통신 시 한글이 물음표(???)나 특수문자로 깨지는 현상을 경험하였다.

삽질하지 마시라고 해결책을 올린다.

 

1. html 파일의 charset을 utf-8로 설정한다.

1
<meta charset="utf-8">

 

2. 통신할 Servlet 파일의 doGet 또는 doPost 함수의 상단에 아래의 코드를 추가한다.

1
response.setContentType("application/x-json; charset=UTF-8");

 

3. WAS(tomcat)의 server.xml 파일(Servers 디렉터리 - Tomcat v7.0 Server - server.xml)의 65번째(바뀔 수도 있음) 줄에 코드를 아래의 코드로 수정한다.

1
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

 

필자는 3번을 통해 문제를 해결하였다.

반응형
반응형

목차

1. Ajax란

2. 실습 환경

3. 웹 페이지 생성

4. Servlet 생성

5. web.xml 설정

6. 정리

7. 출력 화면


1. Ajax란 (출처 - 위키백과)

 기존의 웹 애플리케이션은 폼을 채우고 이를 제출(submit)하면 웹 서버는 요청된 내용에 따라서 데이터를 가공하여 새로운 웹 페이지를 작성하고 응답으로 되돌려준다. 이때 최초에 폼을 가지고 있던 페이지와 결과물로써 되돌려 받은 페이지는 일반적으로 유사한 내용을 가지고 있는 경우가 많다. 결과적으로 중복되는 HTML 코드를 다시 한번 전송을 받음으로써 많은 대역폭을 낭비하게 된다. 이는 금전적 손실을 야기할 수 있으며 사용자와 대화하는 서비스를 만들기 어렵게도 한다.

 반면에 Ajax는 필요한 데이터만을 웹 서버에 요청해서 받은 후 클라이언트에서 데이터에 대한 처리를 할 수 있다. 웹 서버에서 전적으로 처리되던 데이터 처리의 일부분이 클라이언트 쪽에서 처리되므로 웹 브라우저와 웹 서버 사이에 교환되는 데이터량과 웹 서버의 데이터 처리량도 줄어들기 때문에 애플리케이션의 응답성이 좋아진다.

 

 장점

  - 페이지 이동없이 고속으로 화면을 전환할 수 있다.

  - 서버 처리를 기다리지 않고, 비동기 요청이 가능하다.

  - 수신하는 데이터 양을 줄일 수 있고, 클라이언트에게 처리를 위임할 수도 있다.

 

 단점

  - Ajax를 쓸 수 없는 브라우저에 대한 문제가 있다.

  - HTTP 클라이언트의 기능이 한정되어 있다.

  - 동일-출처 정책으로 인해 다른 도메인과는 통신이 불가능하다.


2. 실습 환경

 - 이클립스

 - jquery-3.4.1

 - tomcat 7.0

  프로젝트 생성 및 tomcat 서버 설정을 마쳤다는 가정 하에 ajax 통신을 하였다.


3. 웹 페이지 생성

 먼저 사용자가 어떠한 입력을 수행할 수 있도록 html과 javascript를 사용하여 웹 페이지를 생성한다. 아래와 같이 ajax폴더에 파일들을 넣어줬다.

웹 페이지 생성

 

 3.1) ajaxCommunication.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
<script type="text/javascript" src = "ajax/jquery-3.4.1.js"></script>
<script type="text/javascript" src = "ajax/ajaxCommunication.js"></script>
</head>
<body>
    <h2>Ajax Communication</h2>
    이름 : <input type="text" id = "ajaxConName"/>
    나이 : <input type="text" id = "ajaxConAge"/>
    <br>
    <input type="button" id = "ajaxConGetButton" value ="Get통신">
    <input type="button" id = "ajaxConPostButton" value ="Post 통신">
    <div id="myDiv"></div>
</body>
</html>
 

 Get, Post 방식의 통신을 구현하기 위해 두 개의 버튼을 생성하였다.

 

 3.2) ajaxCommunication.js

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
$(document).ready(function(){
    $('#ajaxConGetButton').click(function(){
        AjaxConGet();
    })
    
    $('#ajaxConPostButton').click(function(){
        AjaxConPost();
    })
    
})
 
function AjaxConGet(){
    var url = "http://localhost:8080/test/ajaxCon";
    $.ajax({
        type:"GET",
        url:url,
        dataType:"html",
        data:{
            name : $('#ajaxConName').val(),
            age : $('#ajaxConAge').val()
        },
        success : function(data){
            alert('ajax GET 통신 성공');
            var $div = $('<div></div>');
            var text = document.createTextNode(data);
            $div.append(data);
            $div.appendTo($('#myDiv'))
        
        },
        error : function(request,status,error){
            alert('code:'+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error); //에러 상태에 대한 세부사항 출력
            alert(e);
        }
    })
    
}
 
function AjaxConPost(){
    var url = "http://localhost:8080/test/ajaxCon";
    $.ajax({
        type:"POST",
        url:url,
        dataType:"html",
        data:{
            name : $('#ajaxConName').val(),
            age : $('#ajaxConAge').val()
        },
        success : function(data){
            alert('ajax POST 통신 성공');
            var $div = $('<div></div>');
            var text = document.createTextNode(data);
            $div.append(data);
            $div.appendTo($('#myDiv'))
        },
        error : function(request,status,error){
            alert('code:'+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error); //에러 상태에 대한 세부사항 출력
            alert(e);
        }
    })
    
}
 

 1 ~ 10 : 페이지가 로드되면 위에서 생성했던 두 개의 버튼에 대해 click 이벤트를 부여한다.

 

 12 : Get 방식으로 Ajax와 통신을 시도하는 함수이다.

 

 13 : 통신을 하고자하는 url을 입력한다. ~~test/ajaxCon으로 설정했는데, ajaxCon은 web.xml에서 설정한 서블릿의 url이다.

 

 15 ~ 21 : 통신 방식과 통신할 url, 수신할때의 데이터 타입, Servlet으로 보낼 데이터 정보를 넣어준다. dataType은 서블릿에서 객체 형식이나 두개 이상의 데이터를 송신할 경우 "json"을, 하나의 문장으로 송신할 경우 "html"을 넣어준다. 필자는 out.print()로 하나만 보내기 때문에 html로 해주었다.

 

 22 ~ 27 : Servlet과의 모든 통신이 정상적으로 끝나면 메서드의 매개변수 안에 Servlet이 response 한 데이터가 있게 된다. 이를 출력하기 위해 div태그에 응답 정보가 들어있는 textNode를 상속시키고, 이를 초기 HTML 코드로 생성했던 div 태그에 상속시킨다.

 

 30 ~ 32 : Servlet과의 통신 실패 시 에러 코드 및 내용에 대한 세부사항을 출력시킨다. 만일 에러 코드가 200이 나올 경우 dataType에 대한 수정이 필요하다.

 

 38 ~ 57 : type을 GET에서 POST로만 변경한 코드이다.


4. Servlet 생성

 패키지를 myServlet으로 설정하고 Servlet 이름은 Serv로 하였다. web.xml에서 url과 Servlet을 매핑할 것이기 때문에 WebServlet()을 주석처리하였다.

 

Serv.java

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package myServlet;
 
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
 * Servlet implementation class Serv
 */
//@WebServlet("/ajaxCon")
public class Serv extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Serv() {
        super();
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.setContentType("application/x-json; charset=UTF-8");
        PrintWriter out = response.getWriter();
        String name = request.getParameter("name");
        String age = request.getParameter("age");    
        
        System.out.println("doget :"+name);
        System.out.println("deget :"+age);
            
        out.print("Get 통신 : 안녕 내 이름은 "+name+"이고 나이는 "+age+"란다"); //response    
    }
 
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.setContentType("application/x-json; charset=UTF-8");
        PrintWriter out = response.getWriter();
        String name = request.getParameter("name");
        String age = request.getParameter("age");    
        
        System.out.println("doget :"+name);
        System.out.println("deget :"+age);
            
        out.println("Post통신 : 안녕 내 이름은 "+name+"이고 나이는 "+age+"란다"); //response
    }
}
 

 9 : ajax로 데이터를 전송하기 위한 메서드인 java.io.PrintWrite를 import 하였다.

 

 28 : GET 방식으로 통신할 때의 함수이다.

 

 30 : ajax로 보낼 데이터의 charset을 utf-8로 설정한다. 이 부분이 없을 시 한글이 깨져서 출력될 수 있다.

 

 32 ~ 33 : ajax에서 보낸 name과 age를 읽어 들인다.

 

 38 : 위와 같은 형태로 데이터를 가공하여 ajax에게 전송한다.

 

 44 ~ 54 : POST 방식으로 통신할 때의 함수이다.


5. web.xml 설정

 web.xml은 루트 경로로 진입 시 가장 먼저 읽어오는 파일을 설정하거나 WAS에게 줄 Servlet 정보를 설정하고 url을 매핑하는 역할을 한다.

 

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>test</display-name>
  <welcome-file-list>
    <welcome-file>ajax/ajaxCommunication.html</welcome-file>  <!-- 루트경로 진입시 가장먼저 읽어오는 파일 -->
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
  <!-- 서블릿을 불러오기 위해 WAS에게 주는 정보 -->
  <!-- 1. 배포할 Servlet 2. 해당 Servlet 매핑 URL -->
      <servlet-name>ajaxCon</servlet-name>
      <servlet-class>myServlet.Serv</servlet-class>
  </servlet>
  
  <servlet-mapping>
      <servlet-name>ajaxCon</servlet-name>
      <url-pattern>/ajaxCon</url-pattern>
  </servlet-mapping>
</web-app>
 

 

 5 : <welcome-file> 태그는 루트 경로 진입 시 가장 먼저 읽어오는 파일이다. 읽어올 수 없을 시 순차적으로 아래 입력된 파일을 읽어온다. root경로에서 서버를 돌릴 시 ajaxCommunication.html 파일이 가장 처음 로드되도록 하였다. 그 아래는 기본적으로 입력되어 있는 파일이다.

 

 13 ~ 18 : WAS가 Servlet을 정상적으로 로드하기 위해 WAS에게 주는 Servlet과 url 정보이다. <servlet-name>은 <servlet-mapping>에서 동일한 name을 가진 정보와 매핑시키기 위한 이름이다. 현재 myServlet.Serv(클래스명.서블릿명) 파일을 '/ajaxCon' 이라는 url과 매핑시켰다. 이로써 '~~test/ajaxCon' url로 접속할 시 Serv 파일이 로드된다.


6. 정리

 이렇게 설정하면 ajax 통신이 정상적으로 이루어진다. 과정을 정리하자면

 

 1) 서버를 실행하면 web.xml에서 정의한 파일인 'ajax/ajaxCommunication.html'를 로드하고, WAS에게 서블릿 파일과 url 정보를 알려준다.

 

 2) HTML 파일에서 버튼을 클릭하게 되면 입력한 url과 ajax 통신을 시도하게 된다. url이 web.xml에서 설정한  ~~test/ajaxCon로 설정되었기 때문에 '/ajaxCon'과 매핑된 Serv 서블릿과 통신을 시도하게 된다.

 

 3) Servlet에서 데이터를 받은 후 가공하여 송신한다.

 

 4) ajax는 웹 페이지에 가공된 데이터를 출력시킨다.


 7. 출력 화면

통신 성공 화면

 

반응형
반응형

목차

1. 개요

2. 생성

3. 조회

4. 수정

5. 삭제


1. 개요

 Javascript의 가장 기본이 되는 개념인 객체의 생성, 조회, 수정, 삭제 방법에 대해 알아본다.


2. 생성

1
var foo = { name : 'ssk' };

중괄호 '{ }' 안에 key : value 형식으로 프로퍼티를 저장한다.

프로퍼티란 객체에 속한 데이터를 뜻한다.

 

※ key point

 foo라는 변수가 {name : 'ssk'} 라는 객체 자체에 대한 데이터를 가지고 있는 것이 아닌 객체의 주소를 가지고 있다.

var foo 는 해당 객체의 주소를 저장하고 있다.

 

  예를 들어, var foo2 = foo 라고 초기화시키면 foo2 또한 foo와 동일한 객체를 가리키게 된다.


3. 조회

 객체를 조회하는 방법은 크게 두 가지이다.

 1) 참조 연산자 (.) 사용

 2) 대괄호 ([]) 사용

1
2
3
console.log(foo.name); // 'ssk'
console.log(foo['name']); // 'ssk'
console.log(foo[name]); //undefined

  foo.name은 foo객체의 주소를 참조하고 그 안에 있는 name 값을 조회한다라는 의미이다. 'ssk'가 출련된다.

 

 foo['name']도 직관적으로 해석하면 foo객체의 key가 name인 value값을 조회한다인데, foo['name']과 foo[name]이 자꾸 헷갈려서 메커니즘을 찾아 이해해보았다.

 

 먼저 대괄호란 녀석은 배열에서 값을 참조할 때 쓰는 형식이다.

 javascript에서는 number, boolean, undefined, string, null이라는 기본 타입을 제외하고 모두 객체 타입이다. foo['name']은  객체 타입인 배열과 형식이 같은 것을 알 수 있다. (물론! 차이는 존재한다.)

쉽게 생각하면 foo['name']은 처럼 'name'이라는 key값(index)를 참조한다고 생각하면 이해가 쉽다. 객체의 key값은 String 값이기 때문에 작은 따옴표(')와 함께 입력해 준 것이다. 작은 따옴표가 없으면 name이라는 값은 String이 아닌 하나의 변수로 인식되고, name 변수 안에 있는 값을 참조하게 된다. name 변수는 호출이 된 최상위 객체인 window에 존재하지 않기 때문에 당연히 undefined가 출력된다.

 추가적으로 javascript는 대괄호 안에 데이터가 문자열이 아닐 경우 자동적으로 toString() 메소드를 적용시킨다. toString() 메소드는 어떠한 데이터를 문자열로 변환해주며, 변수.toString() 형식으로 사용할 경우 해당 변수에 들어있는 데이터를 문자열로 변환해주는 역할을 한다.

 즉, 대괄호 안에 있는 name이라는 데이터를 문자열이 아닌 변수로 인식하게 되면 name이라는 변수는 호출된 객체 영역 내에서 정의되지 않았기 때문에 문자열로 변환한들 당연히 값은 존재하지 않는다.

 

1
2
3
4
5
var name = 'name';
 
console.log(foo.name); // 'ssk'
console.log(foo['name']); // 'ssk'
console.log(foo[name]); // 'ssk'

 때문에 변수에 객체의 key값을 넣어 조회할때 위의 방식을 사용한다.

 간단히 name이라는 변수에 'name'이라는 key값을 넣었지만 key값이 많을 경우 반복문과 결합하여 사용할 수 있다.

 

foo['name']과 foo[name]의 차이를 정확히 알았으니 더이상 헷갈리는 일은 없겠지.


4. 수정, 추가

1
2
foo['name'= 'hky';
console.log(foo['name']) //hky

foo.name = 'hky' 라고 해도 동일하다. 

1
2
foo['age'= 25;
console.log(foo['age']) //25

추가도 수정과 동일한 방식이다.


5. 삭제

1
2
delete foo['age'];
console.log(foo['age']); //undefined

 삭제하고자 하는 객체의 키 값을 입력하며, 객체의 프로퍼티를 삭제할 때 사용한다.

 객체 자체를 삭제할 순 없다.

반응형
반응형

목차

1. 정규 표현식이란

2. 정규식 패턴

3. 정규식 메소드

4. 예제


1. 정규 표현식이란

 정규 표현식이란 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다.

 형식 언어를 사용하여 특정한 규칙을 가진 문자열의 패턴을 파악한다면 텍스트 편집, 포맷팅, 검색, 치환 등의 문자열 작업이 가능하게 된다. 기본적으로 패턴은 두 개의 '/(슬래시)' 사이에 작성한다. 

 

 예를 들어 '20190809'라는 문자열에서 패턴을 파악하여 '2019''08''09' 형태로 나누고, 그 사이에'-' 문자열을 삽입하여 '2019-08-09' 형태로 만들 수 있고, 저렇게 만든 날짜형 데이터에서 사용 가능한 메소드인 getDay(), getFullYear() 등을 사용할 수 있게 된다. 표현을 위한 포맷팅뿐 아니라 메소드의 사용까지도 가능하게 해주는 좋은 녀석이다.


2. 정규식 패턴

 그렇다면 이 패턴은 어떻게 만들까? 패턴을 만드는 방법은 크게 두 가지이다.

 첫째, 단순 패턴 사용

 둘째, 특수 문자 사용

 

 2.1 단순 패턴 사용

  단순 패턴은 단순히 문자열을 대응시킬 때 사용한다. 예를 들어 /hi/라는 패턴은 문자열에서 hi라는 문자열이 그대로 나타나야 대응된다. "hi, hellow"에서 hi라는 문자열이 대응된다.

 연습이 필요하다고 생각한다면 정규식을 테스트할 수 있는 사이트(https://regexr.com)를 들어가 보길 권한다. 참고로 끝에 있는 'g'는 패턴 속성으로 대상 문자열의 처음부터 끝까지 해당 패턴을 적용시키는 것이다. 이 속성이 없다면 'hi hi hi' 문자열의 대응 부분은 처음의 'hi' 하나뿐이다.

regexr.com

 

 2.2 특수 문자 사용

  단순 패턴을 사용하여 대응하기 힘든 것을 대응시키고자 할 경우 패턴에 특수 문자를 사용한다. 예를 들어, /^hi/ 패턴은 문자열의 시작이 'hi' 문자로 시작되는 것에 대응한다. 만약 'hi, hellow' 문자열에 이 패턴을 적용시킨다면 'hi'가 대응되며, 'oh, hi'라는 문자열에 적용시킨다면 대응되는 문자는 아무것도 없다.

 

특수문자의 종류와 기능이다.

특수 문자 기능 예시
^ 입력의 시작 부분과 대응된다. /^시작/ 시작했다 시작
$ 입력의 끝 부분과 대응된다.  /끝$/ → 끝났다 
* 표현식이 0회 이상 연속으로 반복되는 부분과 대응된다.

/ab*c/ → cbbabbbbcdebc, acbd

+ 표현식이 1회 이상 연속으로 반복되는 부분과 대응된다. /ab+c/ → cbbabbbbcdebc, acbd
? 표현식이 0 또는 1회 등장하는 부분과 대응된다. {0,1} 과 같다. 있어도 ok, 없어도 ok 이라고 생각하면 편하다 /010?/ 01, 010, 011
. 개행 문자를 제외한 모든 단일 문자와 대응된다. /hi./ → hi, hi1, hi2, hi12, hi 
(x) 패턴의 부분을 나누는 것. 포맷팅에 유용하게 쓰인다.

/(a)(b)/ ab

replace(/(a)(b)/,'$1-$2') → a-b

x|y | 는 or 와 동일한 기능을 하며, 하나라도 있을 시 대응된다. /fuck|suck|dick/ fuckyou, suckyou
{n} 표현식이 n번 나타나는 부분에 대응된다. /(hi){2}/ → hi, hihi, hi hi
{n,m} 표현식이 n번~m번 나오는 부분과 대응된다. /(hi){2,3}/ → hi,hihi,hihihi,hihihihi
[abc] 대괄호 안의 문자가 하나라도 있을시 대응된다. /[abc]/g a,ab,abc

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D

 

정규 표현식

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 RegExp의 exec 메소드와 test 메소드  ,그리고 String의  match메소드 , replace메소드 , search메소드 ,  split 메소드와 함께 쓰입니다 . 이 장에서는 자바스크립트의 정규식에 대하여 설명합니다.

developer.mozilla.org

더 많은 특수 문자에 대해 알아보고 싶다면 위의 링크로 들어가 보길 권한다.


3. 정규식 메소드

 정규식을 만들어 적용시키기 위해서는 정규식 메소드를 사용해야 한다.

 메소드 또한 위의 링크에서 잘 정리되어있기 때문에 많이 사용되는 메소드만 정리하겠다.

메소드 명 사용 방법 기능
exec pattern.exec(String) 패턴을 String에 적용하여 실행시킨다.
test pattern.test(String) 패턴을 String에 적용시킨 결과가 존재하는지 true와 false로 출력시킨다
replace String.replace(pattern,'type') 패턴을 String에 적용시키고 type으로 치환한다.

특정 문자를 제거하고 싶다면 String.replace(/\-/g, '')

 

반대로 String에 구역을 나눠 해당 구역 간격으로 '-' 문자를 넣어주고 싶다면 

 

번호에 '-' 기호 삽입

참고로 replace의 두 번째 인자인 $1, $2, $3는 정규식에서 대응되는 각각의 부분이다.


4. 예제

 입력받은 두 날짜의 시간 차이 계산하기

 

 4.1) 소스코드

  4.1.1) html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page Title</title>
    <script type="text/javascript" src="3js.js"></script>
</head>
<body>
    <input type="text" id = "date1">
    <input type="text" id = "date2">
    <input type="button" id = "dateButton" value="계산">
</body>
</html>

 

  4.1.2) Script

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
31
32
33
34
35
36
window.onload = function(){  
    document.getElementById("dateButton").addEventListener("click",dateCalcul);
    function dateCalcul(){
        var date1 = document.getElementById("date1").value;
        var date2 = document.getElementById("date2").value;
        var pattern = /(^(19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$/
        if(pattern.test(date1) && pattern.test(date2)){
            var formatDate1 = date1.replace(/(\d{4})(\d{2})(\d{2})/,'$1-$2-$3'); //YYYYMMDD 형태
            var formatDate2 = date2.replace(/(\d{4})(\d{2})(\d{2})/,'$1-$2-$3');
            var checkDate1 = new Date(formatDate1).getDate(); //1,2,3,4 형태, 메소드 적용 데이터
            var checkDate2 = new Date(formatDate2).getDate();
            checkDate1 = zeroFormat(checkDate1); //D 형태일때 0 추가 = DD형태
            checkDate2 = zeroFormat(checkDate2);
            var formatDate1Date = formatDate1.split('-')[2]; //DD 추출, 순수 입력 데이터
            var formatDate2Date = formatDate2.split('-')[2];
            
            if(formatDate1Date != checkDate1 || formatDate2Date != checkDate2){ //DD 형태 비교
                alert("입력한 날짜는 존재하지 않습니다");
                return;
            }
            var convertDate1 = new Date(formatDate1).getTime();
            var convertDate2 = new Date(formatDate2).getTime();
            var absDate = Math.abs(convertDate1-convertDate2);
            var result = absDate/(24*60*60*1000);
            alert(formatDate1+" 과 "+formatDate2+" 의 사이 날짜는 "+result+"일 입니다.");          
        }else{
            alert("19~20년도 사이의 정확한 날짜를 입력해주세요");
        }
    }
}
function zeroFormat(input){
    if(input<10){
        input = "0"+input;
    }
    return input;
}
 

 2번 라인 - dateButton Click 이벤트 추가 및 함수 실행

 

 4~5번 라인 - 날짜 데이터인 date1, date2의 value 값을 가져옴

 

 6번 라인 - 정규식 패턴 생성(사용자가 YYYYMMDD 형태로 입력했는지 검사)

 (^(19:20)\d{2}) - 제일 앞이 19 아니면 20, 그 뒤 숫자 2개 : 1900~2099

 (0[1-9]|1[0-2]) - '0 다음 1부터 9 사이 값' 또는 '1 다음 0부터 2 사이 값 : 01~12

 (0[1-9]|[12][0-9]|3[01])$ - '0 다음 1부터 9 사이' 또는 '1 또는 2 다음 0부터 9 사이' 또는 '3 다음 0 또는 1' : 01~31

 $ - (YYYYMMDDD와 같이 형식을 오버했을 때 검출함)

 

 7번 라인 - 입력한 두 텍스트 박스의 value에 패턴을 적용시키고 대응 여부를 확인(true or false)

 

 8~9번 라인 - Date 객체를 생성하기 위한 데이터 형식인 (YYYY-MM-DD)를 맞춰주기 위한 포매팅

 

 10-11번 라인 - 객체의 메소드를 적용하여 날짜를 가져옴

 

 12-13번 라인 - 날짜가 1일, 2일 과 같이 한 자리 수일 때 형식이 DD가 아닌 D가 됨. 즉 비교가 안되므로 DD형태로 변경해주기 위한 메소드인 zeroFormat() 호출

 

 ※ DD 형태로 변형해야 하는 이유

   사용자의 입력 날짜가 윤월일 인지 판별하기 위함 (2월 30일처럼 없을 수도 있는 날짜 판별)

   Date 객체의 getDate() 메서드는 입력한 날짜의 '일자'를 받아옴. 그런데 만약 2018년 2월 30일의 일자를 받아오면

   3일이 나오게 됨. 즉, 없는 일자만큼 카운트를 계산하여 가까운 있는 날짜에 더해줌. 2월 31일의 가장 가까운 날짜는

   3월 1일이며, 2월 28일에서 초과된 2일만큼 증가시키면 3월 3일이 나옴. = 계산 오류 발생.

   이러한 오류를 막기 위해 DD 형태로 변형하여 사용자가 입력한 날짜의 일자와 메소드를 적용시킨 일자를 비교하여

   일치할 경우 존재하는 날짜로 판별하고, 불일치할 경우 존재하지 않은 날짜로 판별하기 위함 

 

 14-15번 라인 - split 메소드를 사용하여 '-' 기준으로 나눈 배열의 3번째인 일자가 저장된 값을 읽어옴.

 

 17번 라인 - 사용자가 입력한 일자와 메소드를 적용시킨 일자를 비교

 

 21번 라인 - 입력 날짜에 문제가 없으면 해당 시간의 날짜를 시간으로 변환(milis)

 

 23번 라인 - 밀리 초로 변환된 두 날짜의 시간을 빼고 그 데이터를 절댓값으로 변환

 

 24번 라인 - 밀리초를 날짜로 변환하기 위해 각각의 단위를 곱 연산 후(1000*60*60*24 = 1일) 앞의 계산 결과와 나눔

 

4.2) 실행결과

실행결과 1
실행결과 2
실행결과 3

반응형
반응형

목차

1. 개요

2. important

3. 예제 및 실행 화면


1. 개요

 css의 속성 중 !important가 있다. 단어의 뜻처럼 굉장히 중요해보이기에 포스팅을 한다.


2. !important

 !important는 말 뜻 그대로 '중요한 속성' 을 의미하고, 해당 속성이 변경되지 않도록 하는 역할을 한다.

 만약 변경하고 싶다면 똑같이 속성에 !important 속성을 삽입해주면 된다.

 


3. 예제 및 실행 화면

3.1) 예제 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>?</title>
        <style>
            p{
                background-color : red !important;
                float : left;                    
            }
 
            p{
                background-color : blue;
                float : left
            }
        </style>
    </head>
    <body>
        <p>!important</p>
    </body>
</html>
 

 7번 라인과 12번 라인에 <p> 태그의 css를 정의하였다.

 !important 속성이 없다면 <p> 태그의 내용은 12번

 라인에 의해 파란색이 되어야 하지만

 !important 속성에 의해 수정이 되지 않는 것을 확인할 수 있다.

 

실행 화면 1

 

3.2) 예제 2

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
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>?</title>
        <style>
            p{
                background-color : red !important;
                float : left;                    
            }
 
            p{
                background-color : blue;
                float : left
            }
 
            p{
                background-color : green !important;
                float : left
            }
        </style>
    </head>
    <body>
        <p>!important</p>
    </body>
</html>

17번 라인에 !important 속성을 삽입하였더니 <p> 태그의 내용의 배경색이 바뀐것을 확인할 수 있다.

실행 화면 2

 

반응형
반응형

목차

1. 개요

2. 예제

3. 실행 화면


1. 개요

 기본적인 css문법과 JQuery 문법의 간단한 사용법을 복습하기 위해 li태그 클릭 시 글자색과 배경색이 바뀌도록 하는 예제를 작성해보았다.


2. 예제

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
31
32
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>?</title>
    <style>
        ul{
            float:left;
            list-style: none;
        }
        .change_back{
            background-color: red;
            color:white;
        }
    </style>
</head>
<body>
    <ul class = 'lang_list'>
        <li>HTML</li>
        <li>CSS</li>
        <li>bootstrap</li>
        <li>Javascript</li>
        <li>JQuery</li>
    </ul>
    <script>
        $('ul.lang_list li').click(function(){
            $(this).addClass('change_back');
        });
    </script>
</body>
</html>

 css를 적용시키려면 <style>태그를 사용해야 한다.

 css를 적용시키려는 대상에 따라 그 문법이 약간 달라진다.

 

1) 대상이 태그(< >)일 경우

 태그명{

      속성 : 속성값;

 }

 

 2) 대상이 클래스일 경우

 .클래스명{

     속성 : 속성값;

 }

 

 3) 대상이 태그의 클래스일 경우

 태그명.클래스명{

     속성 : 속성값;

 }

 

 4) 태그의 클래스의 태그일 경우

 태그명.클래스명 태그명{

     속성 : 속성값;

 }

 

 클래스는 하나의 객체이기 때문에 .을 붙이는 것이라고 생각하면 편하다.

 

 7번 라인은 ul에 대한 css를, 11번 라인은 change_back 클래스에 대한 css를 정의하였다.

 

 19번 라인에 ul의 class를 lang_list로 정의하였고

 

 27번 라인에 ul 태그 중 lang_list라는 클래스를 찾고 해당클래스의 li 태그를 클릭하면, 클릭한 li 태그에 대한 클래스를 change_back으로 정의하였다.

 

 11번 라인에 change_back은 배경을 빨간색, 색을 흰색으로 만드는 것으로 정의하였기 때문에 그에 맞게 색이 변하게 된다.

 

 그 외 사용한 속성은 아래와 같다

속성 설명
float : left 공백을 제거하고 좌측정렬
list-style : none <li> 태그의 기호를 제거
background-color 배경색
color 글자색

 


3. 실행 화면

click event

 

반응형
반응형

목차

1. 개요

2. __proto__

3. 정리


1. 개요

prototype에 대한 내용이 생각보다 많아 내용을 정리해나가며 공부를 하고 있다.

지금까지의 내용을 다시 정리하면

 

 1) 함수가 정의되면 prototype을 참조 가능한 prototype 프로퍼티, __proto__ 메서드가 생성된다.

 2) prototype은 constructor(생성자)를 참조 가능하다.

 3) 함수의 생성자로 생성되는 객체들이 prototype 객체를 상속받는다.

 4) prototype의 내용을 변경하면 생성자로 생성된 객체는 변경된 내용을 상속받게 된다. (당연한 얘기)

 5) prototype 객체를 참조하는 것은 생성한 객체의 __proto__ 메서드이다.

 

function - __proto__ - prototype 간의 관계


 

 그렇다면 __proto__에 대해 알아보도록 하자.


2. __proto__

 __proto__란 prototype link라고 불리며 객체가 생성될 때 조상이었던 함수의 prototype 객체를 가리킨다.

 

간단한 실험을 통해 알아보자

 

 1) function a(){} - 함수를 생성한다.

 2) a.prototype.a_val = 1; - 해당 함수의 prototype 객체에 a_val = 1이라는 값을 추가한다.

 3) b = new a(); - 생성자를 통해 b라는 객체를 생성한다.

 4) b.__proto__를 확인한다!

 5) __proto__에는 조상 함수의 prototype 객체인 a.prototype을 나타낸다.

 6) 이러한 관계를 b가 a를 상속받았다고 한다. 왜냐고? b.a_val를 출력하면 1이 나오니까!

b.__proto__ 객체

 

b를 출력하면 알 수 있겠지만 b객체 자체는 a_val를 가지고 있지 않는다.

__proto__ 객체밖에 없다. 바로 이 객체가 a_val 속성을 찾을 때까지 조상 prototype을 참조해나간다!

b 객체

최상위인 Object의 prototype 객체까지 찾지 못했을 경우 undefined를 리턴한다.

이렇게 __proto__ 속성을 통해 상위 프로토타입과 연결되어있는 형태를 prototype Chain이라고 한다.


3. 정리

 1) 함수가 정의되면 메모리에 함수와 생성자를 생성할 수 있는 prototype 객체가 생성된다.

 

 

 2) 함수에는 prototype 객체를 참조 가능한 prototype 프로퍼티__proto__ 객체가 생성된다. 

 

 3) 1)에서 생성된 prototype 객체 안에는 constructor 프로퍼티가 있고 이는 자신을 생성한 생성자 함수를 가리킨다.

 

 4) 함수의 생성자(new)로 생성되는 객체들은 __proto__ 객체를 상속받는다.

 

 5) __proto__ 객체는 자신의 조상 prototype 객체를 가리킨다.

 

 6) 상속된다.

 

 이 정리가 이해가 가지 않는다면 __proto__ 실험 과정과 맨 위의 그림을 번갈아가며 과정을 따라가다 보면 prototype, 즉 상속의 원리와 과정을 이해할 수 있을 것이다. 

 

 이로써 prototype을 마무리하도록 하겠다.

반응형
반응형

목차

1. $('document').ready(function){} 란?

2. 예제 및 실행화면

 

1. $('document').ready(function){} 란?

 결론부터 말씀드리자면 'html문서의 로딩이 다 끝나면' 을 의미합니다.

 

 문장을 해석해보면 'document'라는 객체의 준비가 끝나면 즉, 로드가 완료되면 함수를 실행한다' 입니다.

 여기서 document는 하나의 html 파일을 나타내는 트리의 루트 노드 객체라고 생각하시면 편할 것 같습니다.

 

HTML DOM Tree (출처 - W3C)

 

 그렇다면 이 코드는 왜 있는것일까요? 예제를 통해 알아보면 이해가 쉽습니다.

 

2. 예제 및 실행화면

 2.1) 예제 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>$('document').ready(function(){})</title>
</head>
<body>
    <script>
        $('p').click(function(){
            $(this).hide();
        })    
    </script>
    <p>
        $('document').ready(function(){})을 쓰는 이유를 알고싶다면 클릭하세요!
    </p>
</body>
</html>

위의 예제는 p 태그를 클릭할 시 this 즉, 해당 p 태그를 hide 시키는 것입니다.

 

 2.2) 실행화면 1

 실행화면_1

실행 결과, 클릭을 해도 <p>태그의 내용이 사라지질 않습니다.

이유는 컴파일과 관련이 있습니다.

컴파일은 일반적으로 위에서 아래방향으로 이루어지는데, <p>태그가 나오기 전에 script문이 호출되었기 때문에 결과적으로 JQuery문법이 p태그를 찾지 못했고, 쿼리에 대한 함수 또한 적용시키지 못했습니다.

 

그렇다면 script문을 아래로 옮겨보겠습니다.


 2.3) 예제 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>$('document').ready(function(){})</title>
</head>
<body>
    
    <p>
        $('document').ready(function(){})을 쓰는 이유를 알고싶다면 클릭하세요!
    </p>
    <script>
        $('p').click(function(){
            $(this).hide();
        })    
    </script>
</body>
</html>

 script문이 </body> 바로 위에 위치합니다.

 

 2.4) 실행화면 2

실행화면_2

 <p> 태그에 해당하는 부분을 클릭하니 오른쪽 사진과 같이 텍스트가 사라진 것을 볼 수 있습니다.

 

 예제 1과 다르게 script문이 <p> 태그 아래 있기때문에 JQuery 문법이 p라는 태그를 찾을 수 있고 함수를 적용시킬 수 있습니다.

 

 HTML은 기본적으로 위에서 아래로 컴파일이 됩니다.

 컴파일러가 script문을 만날 경우 로드되던 HTML 작업이 중단되고 script문을 처리합니다.

 만약 script문이 길다면 페이지 로드가 중단되는 시간이 길어지고, 사용자가 웹페이지를 기다리는 시간이 길어집니다.

 

예를들어 눈에보이는 정보가 HTML이고 기능을 입히는 것이 script라고 한다면

1) 사용자에게 보이는 HTML 로드 -> script문 로드

2) 사용자에게 안보이는 script문 로드 -> 사용자에게 보이는 HTML 로드

이 둘 중 1번 상황이 웹 정보를 사용자가 먼저 파악할 수 있기 때문에 효율적이라는 것을 알 수 있습니다.

 

 이 외에도 여러가지 이유때문에 script문을 </body>태그 바로 위에 위치시키는 것을 선호한다고 합니다.

 

 하지만 예제 1처럼 script문이 위에 위치하더라고 페이지 로드가 끝난 후 script문을 실행시키도록 하는 코드가 있습니다. 그게 바로 오늘의 주제인 $('document').ready(function){}입니다.


 2.5) 예제 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>$('document').ready(function(){})</title>
</head>
<body>
    <script>
        $('document').ready(function(){
            $('p').click(function(){
                $(this).hide();
            })
        })    
    </script>
    <p>
        $('document').ready(function(){})을 쓰는 이유를 알고싶다면 클릭하세요!
    </p>
</body>
</html>

작성했었던 script문을 $('document').ready(function){} 코드 안에 넣어줬습니다.

이로써 위의 script문은 HTML 코드에 대한 페이지 로드가 끝난 후 실행이 되고, <p> 태그를 찾아 함수를 적용시킬 수 있습니다.

 

2.6) 실행화면 3

실행화면_3

 실행화면_2와 동일한 결과를 출력합니다.

반응형
반응형

목차

1. 개요

2. 사전 정보

3. 예제

4. 실행화면


1. 개요

 jQuery의 click 이벤트를 사용하여 어떤 태그를 클릭시 클릭했다는 것을 알 수 있게 색을 입히는 기능을 구현해보았다.


2. 사전 정보

 2.1) css 문법

  - id에 css 적용하기

   #id{ 속성 : 속성값; }

  

  - id의 태그에 css 적용하기

   #id tag{ 속성 : 속성값; }

 

  - id의 클래스에 css 적용하기

   #id .class{ 속성 : 속성값; }

 

 2.2) cursor 속성

  - css 속성 중 하나인 cursor은 지점에 커서를 이동시켰을 경우 나타나는 커서의 모양을 지정하는 속성이다.

속성값 설명
default 기본
crosshair 십자가 표시
pointer 손가락 표시
help 물음표
wait 초시계

 

 2.3) float 속성

  - css 속성 중 하나인 '뜨다' 라는 의미를 가진 float는 '머리만 떠있는 것 같다' 처럼 어떤 내용의 content만 떠있고 나머지 여백은 없애는 속성이다.(약 뇌피셜) 

속성값 설명
left 왼쪽 정렬
right 오른쪽 정렬

 


3. 예제

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>click event</title>
        
        <style>
            #navigation li{
                list-style: none;
                float:left;
                padding:10px;
                border: 3px bisque inset;
            }
            #navigation{
                cursor:pointer;
            }
            #navigation .selected{
                background-color:red;
                color:white;
            }
            #id
 
            #id .class{
                background-color: red;
            }
        </style>
    </head>
    <body>
            
        <ul id="navigation">
            <li>1번 list</li>
            <li>2번 list</li>
            <li>3번 list</li>
            <li>4번 list</li>
        </ul>
        <script>
                $('#navigation li').click(function(){
                    $('#navigation li').removeClass('selected');
                    $(this).addClass('selected')
                })
        </script>
    </body>
</html>

 6번 라인.

  CDN 방식으로 jquery를 로드한다.

 

 7번 라인.

  navigation의 li 태그

  - list-style:none - 기본값인 · ' 을 없애기 위한 속성

  - float:left - 아래로 정렬되어야 할 li 속성이지만 공백을 제거하여 li속성 옆에 바로 li속성이 붙도록 하고 왼쪽정렬 시킴

  - padding:10px - 태그와 텍스트 사이의 여백

  - border - 테두리 설정

 

 15번 라인. 

  - cursor:pointer 커서를 댈 시 손가락 모양

 

 38번 라인.

  $('#navigation li').click(function(){내용} - 아이디가 navigation인 태그의 li 태그를 클릭 시 함수를 실행한다.

  $('#navigation li').removeClass('selected') - 아이디가 navigation인 태그의 li에서 'selected' 클래스를 제거한다.

  $(this).addClass('selected') - 클릭한 태그에 selected라는 클래스를 넣어준다.


4. 실행화면

1번 클릭시
2번 클릭시
3번 클릭시

 

반응형

+ Recent posts