⛏️
공부방
  • README.md
  • 프로젝트
    • ft_transcendence
      • 설계
        • 0. 프론트 디자인
        • 1. BackboneJS 뷰 객체
        • 2. API 설계
        • 3. 레일즈 라우팅 구현
        • 4. DB 설계
        • 5. 채널 설계
    • slab-saver
    • react-payment
  • 공부
    • HTML, CSS
      • GRID
      • emmet
      • position
      • CSS Unit
        • 단위 정리
        • 기준을 정해보자
        • em의 정확한 기준은 뭐야?
      • flex
      • NAVBAR 실습
      • 유튜브 화면 만들어보기
    • SQL
      • 이론
        • 1강 데이터베이스
        • 2강 다양한 데이터 베이스
        • 3강 데이터베이스 서버
      • 명령어
        • DB 관리
        • TABLE 관리
        • Constraints
        • SQL 명령어 - 1
        • SQL 명령어 - 2
        • SQL 명령어 - 3
        • SQL 명령어 - 4
        • SQL 명령어 - 5
    • Ruby
      • 루비 객체와 클래스
      • 곡괭이
        • Chapter2. Ruby.new
        • Chapter3. 클래스, 객체, 변수
        • Chapter4. 컨테이너, 블록, 반복자
        • Chapter5. 기능 공유하기
        • Chapter6. 표준 타입
        • Chapter8. 메서드 파헤치기
    • Python
      • 유용한 링크
    • RubyOnRails
      • 아직 정리하지 못한 것들
        • RSPEC 을 이용한 테스트 완전 자동화
        • 레일즈 이니셜라이징 과정
        • 액션케이블 구체적으로 정리하기
        • 웹팩으로 자바스크립트 모듈 관리하기
      • ACTIVE JOB
        • 액티브잡의 기본
        • 실전! 액티브 잡을 이용한 스케쥴링
        • 서버를 껏다 키면 스케쥴링 된 이벤트가 사라진다!
      • ACTION CABLE
        • 액션케이블 Consumer를 이용해서 문제 해결
        • 액션케이블 연결 순서
      • ACTIVE STORAGE
      • 모델
        • validation
          • seeds 데이터 validation 스킵
          • validation 검사가 save, update, create 모든 경우에 일어난다
          • validator 클래스
          • 커스텀Validation
          • validates format(정규표현식)
        • 액티브레코드 find의 다양한 활용
        • 한 레코드에 동시 접속 막자!! with_lock
        • 레일즈 where 사용법
        • 레일즈에서 모델 관련 이슈
        • 모델이름바꿀때명심할것
        • 모델의 includes 메서드
        • 연관 모델을 다른 이름으로 설정하고 가져오기
      • 기본 상식
        • form으로 전달되는 params를 분석해보자
        • StrongParameter 쿼리 배열 받기
        • view helper로 디버깅 하는 방법
        • css 파일을 수정했는데 적용이 안된다?
        • StrongParameter 일반데이터와 객체 데이터 한번에 받기
        • wrap-parameter body가 두 번씩 날라오는 이유
        • 컬렉션 map에서 요소 스킵하는법
        • CASE를 이용해서 정렬(일반적인 정렬 X)
        • 문자열(정규표현식)
        • TIME ZONE 설정하기
        • 커스텀exception
      • RSPEC으로 모델 테스트하기
      • 한 눈에 읽는 루비 온 레일즈
      • Perfect RubyOnRails
        • Chapter1. 소개
        • Chapter2. RubyOnRails 기본
        • Chapter3. 스캐폴딩
        • Chapter7. 라우팅
        • Chapter8. 테스트
    • Javascript
      • var, let, const 차이
      • 브라우저 동작 원리
      • 디바운싱과 쓰로틀링
      • Tagged Template Literal(styled-components)
      • IntersectionObserver 를 사용해서 스크롤 이벤트의 부하 줄여주기
      • EVENT LOOP
        • 자바스크립트에서 어떻게 비동기적인 실행이 가능한걸까?
        • 이벤트 루프의 동작
        • setTimeout이 실행되면 어떤 동작이 일어날까?
        • 블록은 실행이 보장된다
        • 콜스택에 있는 블록이 보장된다는 점을 이용해서 브라우저 죽이기
        • setTimeout 무한반복으로 브라우저는 죽을까?
        • Promise 무한반복으로는 브라우저를 죽일 수 있을까?
        • RAF는 그럼 뭐야?
      • forEach는 반복도중 멈출 방법이 throw 밖에 없다!
      • 임시
        • 정리할 것 목록
          • 자바스크립트 기본 문법
        • 이벤트 임시 정리
      • 유용한 링크
      • arrow function 을 이용한 bind 이슈 해결
      • preventDefault - passive
      • CRITICAL-RENDERING-PATH
      • setInterval에 클로져 개념 사용하기
      • 오디오 문제 이슈
      • 자바스크립트의 식과 문
        • 식과 문이란 무엇인가...
        • 식
          • 1. 기본값과 래퍼객체
          • 2. 참조값과 가비지컬렉팅
        • 식을 조금 더 자세히 알아보자
      • prototype, [[Prototype]] 차이
      • export, import 학습
      • ESlint
      • 아주아주기본
        • Chatper1. 기본
        • Chapter2. 타입
        • Chapter3. 연산자
        • Chapter4. 제어문
        • Chapter5. 배열
        • Chapter6. 함수
        • Chapter7-1. 객체
        • Chapter7-2. 객체
        • Chapter8. 표준객체
        • Chapter9. DOM
      • 이벤트 위임
      • 이벤트가 버블링 되서 root 까지 가다보면... 부모의 부모의 ... 모든 click 이벤트를 발동시키는거 아니야?
      • classList
    • BackboneJS
      • Backbone Model 프로토타입에 메서드 구현하기
      • BackboneJS의 각 요소의 역할과 책임을 확실히 이해하자
      • Window 이벤트를 listenTo로 감시하기
      • 뷰 자신이 자신을 지워야 할 때를 감지하려면 어떻게 해야하는가?
      • 백본 VIEW의 remove와 jquery의 remove 는 다르다!
      • 백본 컬렉션 URL에 쿼리 붙이기
      • index.html.erb와 BackboneJS의 결합
      • 백본 모델과 컬렉션에서 fetch 를 통해 JSON 가져오기!
      • 모델은 urlRoot, 컬렉션은 url
      • ISSUE
      • Absolute Beginner
        • Part1
        • Part2
        • Part3
        • Part4
    • 문제풀이
      • 01. 유효한 팰린드롬(leetcode: 125)
      • 02. 문자열 뒤집기(leetcode: 344)
      • 03. 로그파일 재정렬(leetcode 937)
      • 04. 가장 흔한 단어(leetcode: 819)
      • 05. 그룹 애너그램(leetcode: 49)
      • 06. 가장 긴 팰린드롬 문자열(leetcode: 5)
      • 07. 두 수의 합(leetcode: 1)
      • 08. 빗물 트래핑
      • 09. 세 수의 합(leetcode: 15)
    • BlackCoffeeStudy
      • level1
        • 1주차
    • express
      • Untitled
      • 구글 애널리틱스 연결하기
      • passport를 활용한 로그인
      • express-init 명령어 사용
      • ec2와 DBeaver
      • mariadb 설치
      • sequelize 설치 및 사용법
        • sequelize 설치
        • sequelize-cli 사용법
        • 모델 간 연관관계 맺기
        • Hook 사용하기
      • express-ejs-layout 활용하기
      • Bootstrap
      • npm install로 설치한 모듈 ejs에서 사용하기
      • 미들웨어
    • cypress
      • window.alert 테스트는 어떻게 하지?
      • 상수를 어디에 저장할건가?
      • before()와 beforeEach()
    • aws
      • aws로 프로젝트를 배포해보자!
      • nginx로 리버스프록시 서버를 만들자
      • github actions 로 푸쉬되면 자동으로 업데이트 하는 기능 만들어보기
    • react
      • Drag & Drop 를 이용해서 리스트 요소 순서 바꾸기
      • CRA에서 CRACO 사용하지 않고 절대경로 import(NODE_PATH)
      • useEffect내에서 state의 dependency 문제
      • IntersectionObserverAPI로 무한스크롤 구현
      • react-testing-library
        • 기본
        • react-router-dom 에서의 에러
        • event 발생시키기
        • Integration testing하기
        • async하게 렌더링 되는 요소 잡기
        • Mocking 하기
      • CRA로 만든 앱에서 절대경로로 import 해오기(alias하기)
      • 커스텀 훅 만들기
    • 타입스크립트
      • 조건부타입 (Conditional types)
      • Generics
      • Keyof 타입 오퍼레이터
      • Indexed Access Types
      • 타입 챌린지
        • easy
          • 00. Awaited
          • 01. Concat
          • 02. Exclude
          • 03. First Of Array
          • 04. If
          • 05. Includes
          • 06. Pick
          • 07. Readonly
          • 08. Length
          • 09. Tuple to Object
        • mediun
          • 01. Absolute
    • Firebase
      • 파이어스토어 규칙
    • 기타
      • 협업 프로세스
      • UUID
      • 구글애널리틱스 설치하기
      • 드림코딩 강의
        • 포트폴리오
          • CSS
            • nth-child
            • CSS 팁
          • 자바스크립트
            • 1. 스크롤에 따른 navbar 의 색 변경하기
            • 2. navbar 버튼을 누르면 해당 페이지로 스크롤링 되게 만들자
            • 3. 스크롤 다운 하면 arrow-up 버튼 나오게 하기
            • 4. project 필터링 구현
            • 5. project 필터링에 transition 효과 넣기
      • GIT
        • 기본 사용법 정리
        • git remote update - remote 브랜치 가져오기
  • 기타
    • 이것저것
      • 독서
        • 클린코드
          • Chapter0. 나는 왜 클린코드 책을 읽는가?
          • Chapter1. 클린코드
          • Chapter2. 의미있는 이름
          • Chapter3. 함수
          • Chapter4. 주석
          • Chapter5. 형식 맞추기
      • 용어
      • IDE
        • RubyMine
          • 실전이 중요!
          • 1. Editor Basic
          • 2. Navigation
          • 3. Completion
          • 4. Refactoring
          • 5. Code Assistance
      • MAC에서 살아남기
        • Alfred - Spotlight 업그레이드
        • Vimium
        • BetterTouchTool - 트랙패드
        • 구름 입력기 - ESC, `
        • Spectacle - 화면 분할
    • 원티드 프리온보딩
      • 1주차
        • 월요일
        • 목요일
      • 2주차
      • 3주차
      • 4주차
      • 5주차
      • 6주차
    • 일기장
      • 2020
        • December
          • 20201208(화)
          • 20201209(수)
          • 20201210(목)
          • 20201211(금)
          • 20201214(월)
          • 20201215(화)
          • 20201216(수)
          • 20201217(목)
          • 20201218(금)
          • 20201219(토)
          • 20201221(월)
          • 20201222(화)
          • 20201223(수)
          • 20201224(목)
          • 20201226(토)
          • 20201228(월)
          • 20201229(화)
          • 20201230(수)
          • 20201231(목)
      • 2021
        • January
          • 20210101(금)
          • 20210102(토)
          • 20210105(화)
          • 20210106(수)
          • 20210107(목)
          • 20210108(금)
          • 20210109(토)
          • 20210112(화)
          • 20210113(수)
          • 20210114(목)
          • 20210115(금)
          • 20210117(일)
          • 20210118(월)
          • 20210119(화)
          • 20210120(수)
          • 20210121(목)
          • 20210125(월)
          • 20210126(화)
          • 20210127(수)
          • 20210128(목)
          • 20210129(금)
        • February
          • 20210201(월)
          • 20210202(화)
          • 20210203(수)
          • 20210204(목)
          • 20210205(금)
          • 20210207(일)
          • 20210208(월)
          • 20210209(화)
          • 20210217(수)
          • 20210218(목)
          • 20210219(금)
          • 20210220(토)
          • 20210222(월)
          • 20210223(화)
          • 20210224(수)
          • 20210226(금)
          • 20210228(일)
        • March
          • 20210302(화)
          • 20210303(수)
          • 20210304(목)
          • 20210305(금)
          • 20210306(토)
          • 20210308(월)
          • 20210309(화)
          • 20210310(수)
          • 20210311(목)
          • 20210312(금)
          • 20210313(토)
          • 20210315(월)
          • 20210316(화)
          • 20210317(수)
          • 20210318(목)
          • 20210319(금)
          • 20210322(월)
          • 20210323(화)
          • 20210324(수)
          • 20210325(목)
          • 20210327(토)
          • 20210329(월)
          • 20210330(화)
          • 20210331(수)
        • April
          • 20210406(화)
          • 20210407(수)
          • 20210408(목)
          • 20210409(금)
          • 20210410(토)
          • 20210412(월)
          • 20210413(화)
          • 20210414(수)
          • 20210415(목)
          • 20210416(금)
          • 20210417(토)
          • 20210419(월)
          • 20210420(화)
          • 20210421(수)
          • 20210422(목)
        • July
          • 20210728(수)
Powered by GitBook
On this page
  • DOM
  • DOM
  • Document 객체
  • Document 객체
  • Document 메서드
  • HTML 요소의 선택
  • HTML 요소의 생성
  • HTML 이벤트 핸들러 추가
  • HTML 객체의 선택
  • DOM 요소
  • DOM 요소의 선택
  • HTML 태그 이름을 이용한 선택
  • ID를 이용한 선택
  • 클래스를 이용한 선택
  • name 속성을 이용한 선택
  • CSS 선택자를 이용한 선택
  • HTML 객체 집합을 이용한 선택
  • 노드
  • 노드란
  • 노드의 종류
  • 노드간의 관계
  • 노드로의 접근
  • getElementsByTagName()
  • 노드 간의 관계를 이용하여 접근하는 방법(메서드)
  • 노드에 대한 정보(메서드)
  • 노드 리스트
  • 노드리스트(node list)
  • 노드의 관리
  • 노드의 추가
  • appendChild() 메서드
  • insertBefore() 메서드
  • insertData() 메서드
  • 노드의 생성
  • 노드의 복제 - cloneNode() 메서드
  • 노드의 조작
  • 노드의 값 변경
  • 요소 노드의 텍스트
  • 속성 노드의 값 변경
  • 요소 노드의 교체

Was this helpful?

  1. 공부
  2. Javascript
  3. 아주아주기본

Chapter9. DOM

PreviousChapter8. 표준객체Next이벤트 위임

Was this helpful?

DOM

  • 이상한 TCP를 보지 말고 를 보자

  • [MDN 공식 문서]()

DOM

  • DOM 이란 문서 객체 모델(Document Object Model)의 약자다.

  • DOM은 XML이나 HTML 문서에 접근하기 위한 일종의 인터페이스다.

  • 이 객체 모델은 문서 내의 모든 요소를 정의하고, 각각의 요소에 접근하는 방법을 제공한다.

  • DOM은 W3C의 표준 객체 모델이고 계층 구조료 표현이 된다.

  • 모든 HTML 태그는 객체다

  • 태그 하나가 감싸고 있는 자식 태그는 중첩 태그라고 부른다.

    • 태그 내의 문자(text) 역시 객체다.

Document 객체

Document 객체

  • Document 객체는 웹 페이지 그 자체를 의미한다

  • 웹 페이지에 존재하는 HTML 요소에 접근하고자 할 때는 반드시 Document 객체부터 시작해야 한다.

Document 메서드

  1. HTML 요소의 선택

  2. HTML 요소의 생성

  3. HTML 이벤트 핸들러 추가

  4. HTML 객체의 선택

HTML 요소의 선택

  • 메소드

    설명

    document.getElementsByTagName(태그이름)

    해당 태그 이름의 요소를 모두 선택함.

    document.getElementById(아이디)

    해당 아이디의 요소를 선택함.

    document.getElementsByClassName(클래스이름)

    해당 클래스에 속한 요소를 모두 선택함.

    document.getElementByName(name속성값)

    해당 name 속성값을 가지는 요소를 모두 선택함.

    document.querySelectorAll(선택자)

    해당 선택자로 선택되는 요소를 모두 선택함.

HTML 요소의 생성

  • 메소드

    설명

    document.createElement(HTML요소)

    지정된 HTML 요소를 생성함.

    document.write(텍스트)

    HTML 출력 스트림을 통해 텍스트를 출력함.

HTML 이벤트 핸들러 추가

  • 메소드

    설명

    document.getElementById(아이디).onclick = function(){ 실행할 코드 }

    마우스 클릭 이벤트와 연결될 이벤트 핸들러 코드를 추가함.

HTML 객체의 선택

  • 객체 집합

    설명

    DOM Level

    document.anchors

    name 속성을 가지는 요소를 모두 반환함.

    1

    document.applets

    applet 요소를 모두 반환함. (HTML5에서 제외됨)

    1

    document.body

    요소를 반환함.

    1

    document.cookie

    HTML 문서의 쿠키(cookie)를 반환함.

    1

    document.domain

    HTML 문서가 위치한 서버의 도메인 네임(domain name)을 반환함.

    1

    document.forms

    요소를 모두 반환함.

    1

    document.images

    요소를 모두 반환함.

    1

    document.links

    href 속성을 가지는 요소와 요소를 모두 반환함.

    1

    document.referrer

    링크(linking)되어 있는 문서의 URI를 반환함.

    1

    document.title

    요소를 반환함.

    1

    document.URL

    HTML 문서의 완전한 URL 주소를 반환함.

    1

    document.baseURI

    HTML 문서의 절대 URI(absolute base URI)를 반환함.

    3

    document.doctype

    HTML 문서의 문서 타입(doctype)을 반환함.

    3

    document.documentElement

    요소를 반환함.

    3

    document.documentMode

    웹 브라우저가 사용하고 있는 모드를 반환함.

    3

    document.documentURI

    HTML 문서의 URI를 반환함.

    3

    document.domConfig

    HTML DOM 설정을 반환함. (더는 사용하지 않음)

    3

    document.embeds

    요소를 모두 반환함.

    3

    document.head

    요소를 반환함.

    3

    document.implementation

    HTML DOM 구현(implementation)을 반환함.

    3

    document.inputEncoding

    HTML 문서의 문자 인코딩(character set) 형식을 반환함.

    3

    document.lastModified

    HTML 문서의 마지막 갱신 날짜 및 시간을 반환함

    3

    document.readyState

    HTML 문서의 로딩 상태(loading status)를 반환함.

    3

    document.scripts

    요소를 모두 반환함.

    3

    document.strictErrorChecking

    오류의 강제 검사 여부를 반환함.

    3

DOM 요소

DOM 요소의 선택

  • HTML 요소를 다루기 위해서는 우선 해당 요소를 선택 해야만 한다.

    1. HTML 태그 이름을 이용한 선택

    2. id 속성 을 이용한 선택

    3. class 속성 을 이용한 선택

    4. name 속성을 이용한 선택

    5. CSS 선택자 를 이용한 선택

    6. HTML 객체 집합 을 이용한 선택

HTML 태그 이름을 이용한 선택

  • getElementsByTagName() 메서드

    • var selected = document.getElementsByTagName('a')
      for (var i = 0; i < selected.length; i++)
        selected.item(i).style.color = 'red';
    • 태그 이름에 해당하는 모든 객체를 선택하는거니까 리턴값은 배열...?

    • item 메서드로 구해진 각 요소에 접근할 수 있는듯.

ID를 이용한 선택

  • getElementById()

    • ID는 유일한 값이므로 하나만을 선택한다

클래스를 이용한 선택

  • getElementsByClassName()

    • tag name과 비슷하게 여러개를 한번에 선택한다

name 속성을 이용한 선택

  • getElementsByName()

    • 여러개를 한번에 선택

CSS 선택자를 이용한 선택

  • querySelectorAll()

HTML 객체 집합을 이용한 선택

  • HTML DOM에서 제공하는 객체 집합을 이용하여 HTML 요소를 선택

  • var test = document.body; // <body> 요소를 선택함

노드

노드란

  • HTML DOM 은 노드 라고 불리는 계층적 단위에 정보를 저장한다.

  • DOM 은 이러한 노드들을 정의하고 그들 사이의 관계를 설명해 주는 역할을 한다.

  • HTML 문서의 정보는 노드 트리 라고 불리는 계층적 구조에 저장된다.

  • 노드 트리는 노드들의 집합이며, 노드 간의 관계를 보여준다.

노드의 종류

HTML 문서의 모든 것은 노드다

  • 대표적인 노드는 아래와 같다.

  • 노드

    설명

    문서 노드(document node)

    HTML 문서 전체를 나타내는 노드임.

    요소 노드(element node)

    모든 HTML 요소는 요소 노드이며, 속성 노드를 가질 수 있는 유일한 노드임.

    속성 노드(attribute node)

    모든 HTML 요소의 속성은 속성 노드이며, 요소 노드에 관한 정보를 가지고 있음.하지만 해당 요소 노드의 자식 노드(child node)에는 포함되지 않음.

    텍스트 노드(text node)

    HTML 문서의 모든 텍스트는 텍스트 노드임.

    주석 노드(comment node)

    HTML 문서의 모든 주석은 주석 노드임.

노드간의 관계

  • 노드 트리의 가장 상위에는 단 하나의 루트 노드가 존재한다.

  • 루트 노드를 제외한 모든 노드는 단 하나의 부모 노드만을 가진다.

  • 모든 요소 노드는 자식 노드를 가질 수 있다.

노드로의 접근

  1. getElementsByTagName() 메서드를 이용하는 방법

  2. 노드 간의 관계를 이용하여 접근하는 방법

getElementsByTagName()

  • 특정 태그 이름을 가지는 모든 요소를 노드 리스트의 형태로 반환한다.

노드 간의 관계를 이용하여 접근하는 방법(메서드)

  1. parentNode

  2. childNodes

  3. firstChild

  4. lastChild

  5. nextSibling

  6. previousSibling

노드에 대한 정보(메서드)

  1. nodeName

  2. nodeValue

  3. nodeType

노드 리스트

노드리스트(node list)

  • 노드 리스트는 getElementsByTagName() 메서드나 childNodes 프로퍼티의 값으로 반환되는 객체다.

    • getElementById 처럼 하나가 아닌 여러개를 받을 때 리턴되는 객체

  • 배열처럼 []로 접근하거나 item 메서드로 접근하면 된다.

  • var lis = document.getElementsByTagName('li')
    var first_li = list.item(0)

노드의 관리

노드의 추가

  1. appendChild()

  2. insertBefore()

  3. insertData()

appendChild() 메서드

  • 새로운 노드를 해당 노드의 자식 노드 리스트의 맨 마지막에 추가한다.

  • body = document.body;
    a = document.createElement('a'); // <a> </a>
    text = document.createTextNode('This is link');
    attr = document.createAttribute('href')
    attr.value = 'www.naver.com'
    
    a.appendChild(text);
    a.setAttributeNode(attr);
    
    body.appendChild(a)

insertBefore() 메서드

  • 새로운 노드를 특정 자식 바로 앞에 추가한다.

  • parentNode.insertBefore(새로운 노드, 기준 자식 노드)

insertData() 메서드

  • 텍스트 노드의 텍스트 데이터에 새로운 텍스트를 추가한다.

  • text_node.insertData(offset, new_data);
    
    var a = document.getElementsByTagName('a')[0].childNodes[0];
    a.insertData(0, "haha! "); // offset이 기존 길이를 넘어서면 예외발생

노드의 생성

  1. createElement()

  2. createAttribute()

  3. createTextNode()

body = document.body;
a = document.createElement('a'); // <a> </a>
text = document.createTextNode('This is link');
attr = document.createAttribute('href')
attr.value = 'www.naver.com'

a.appendChild(text);
a.setAttributeNode(attr);

body.appendChild(a)

노드의 복제 - cloneNode() 메서드

  • 대상.cloneNode(자식노드 복제 여부)

노드의 조작

노드의 값 변경

  • nodeValue 프로퍼티를 사용하면 특정 노드의 값을 변경할 수 있다.

  • setAttribute 메서드는 속성 노드의 속성값을 변경할 수 있게 해준다

요소 노드의 텍스트

  • 요소 노드는 자신이 직접 텍스트값을 가지지 않는다.

  • 자식 노드인 텍스트 노드에 저장이 된다.

    • 따라서 텍스트 값을 변경하려면 텍스트 노드에 접근해야한다.

속성 노드의 값 변경

  • 속성 노드는 nodeValude 프로퍼티 뿐만 아니라 setAttribute() 메서드를 사용하여 값을 변경할 수 있다.

  • 속성이 존재하지 않으면, 먼저 해당 속성을 생성한 후에 값을 설정한다.

요소 노드의 교체

  • replaceChild 메서드를 사용하여 교체할 수 있다.

  • 교체할노드 = 부모노드.replaceChild(새로운 자식 노드, 기존 자식)

여기
모던 자바스크립트 듀토리얼 DOM
https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/%EC%86%8C%EA%B0%9C
노드 트리