본문 바로가기
📔개발자 일기 | | TIL

[20220302] 개발자 일기 & TIL

by 캔 2022. 3. 2.

휴일 전까지 해두었던 데이터 저장 기능을 동작해본 결과 저장이 잘 되었다. 이제는 연결된 상품 정보들이 여러 개일 경우에도 동작하도록 만들어야 했다. 저장 기능 자체는 쉬웠지만, 뷰에서 JS가 변화하도록 코드를 짜는 것이 골치 아팠다. 추가 버튼을 누르면 입력 폼이 추가되고, 삭제 버튼을 누르면 해당 폼만 삭제된 후 다음 폼들이 있으면 그 뒤의 폼들의 인덱스들은 하나씩 줄도록 만드는 것이었다. 다수의 폼들이 id와 name으로 구분되어 있다 보니 id와 name을 추출하고 인덱스를 변경하여 다시 합쳐주는 과정이 여러 번 반복되다 보니 번거로웠다. 너무 복잡하다 보니 이렇게 하는 것이 맞는가 하는 생각도 들었다. 추후에 다시 리뷰하면서 좋은 방법이었는지 탐구해보도록 하자.

 

jQuery의 .attr()과 .prop()의 차이점?

공식 문서를 찾아봤다.

 

.attr() | jQuery API Documentation

Description: Get the value of an attribute for the first element in the set of matched elements. The .attr() method gets the attribute value for only the first element in the matched set. To get the value for each element individually, use a looping constr

api.jquery.com

Attributes vs. Properties
The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

For example, selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, and defaultSelected should be retrieved and set with the .prop() method. Prior to jQuery 1.6, these properties were retrievable with the .attr() method, but this was not within the scope of attr. These do not have corresponding attributes and are only properties.

jQuery 1.6 버전 이후로 두 메서드의 기능이 명확해졌는데, .attr() 메서드는 html의 속성(attribute)을, .prop() 메서드는 jQuery 객체의 속성(property)을 가져오거나 설정한다. 한국어로 번역할 때, attribute와 property를 모두 속성으로 번역하기 때문에 두 메서드의 기능을 파악하기가 어렵다. 하지만, attribute와 property의 차이를 알고 나면 쉬울 것이다.

 

예를 들어보자.

<input type="checkbox" id="inputTag" name="value" />

위 HTML 코드에서 type, id, name은 input 엘리먼트(요소)의 애트리뷰트(속성)이다. 

하지만 input이라는 객체는

accept: ""​accessKey: ""​accessKeyLabel: ""​align: ""​alt: ""​assignedSlot: null​
attributes: NamedNodeMap(3) [ type="checkbox", value="HTML", name="chk_info" ]​autocomplete: ""​autofocus: false​baseURI: "http://www.homejjang.com/05/CheckBox.php"​checked: false​childElementCount: 0​
childNodes: NodeList []​
children: HTMLCollection { length: 0 }​
classList: DOMTokenList []​className: ""​clientHeight: 10​clientLeft: 2​clientTop: 2​clientWidth: 10​contentEditable: "inherit"​
dataset: DOMStringMap(0)​defaultChecked: false​defaultValue: "HTML"​dir: ""​disabled: false​draggable: false​enterKeyHint: ""​files: null​firstChild: null​firstElementChild: null​form: null​formAction: "http://www.homejjang.com/05/CheckBox.php"​formEnctype: ""​formMethod: ""​formNoValidate: false​formTarget: ""​height: 0​hidden: false​id: ""​indeterminate: false​innerHTML: ""​innerText: ""​inputMode: ""​isConnected: true​isContentEditable: false​
labels: NodeList []​lang: ""​lastChild: null​lastElementChild: null​list: null​localName: "input"​max: ""​maxLength: -1​min: ""​minLength: -1​multiple: false​name: "chk_info"​namespaceURI: "http://www.w3.org/1999/xhtml"​
nextElementSibling: <input type="checkbox" value="CSS" name="chk_info">

nextSibling: #text "HTML "
​nodeName: "INPUT"​nodeType: 1​nodeValue: null​nonce: ""​offsetHeight: 14​offsetLeft: 8​
offsetParent: <td>
​offsetTop: 7​offsetWidth: 14​onabort: null​onanimationcancel: null​onanimationend: null​onanimationiteration: null​onanimationstart: null​onauxclick: null​onbeforeinput: null​onblur: null​oncanplay: null​oncanplaythrough: null​onchange: null​onclick: null​onclose: null​oncontextmenu: null​oncopy: null​oncuechange: null​oncut: null​ondblclick: null​ondrag: null​ondragend: null​ondragenter: null​ondragexit: null​ondragleave: null​ondragover: null​ondragstart: null​ondrop: null​ondurationchange: null​onemptied: null​onended: null​onerror: null​onfocus: null​onformdata: null​onfullscreenchange: null​onfullscreenerror: null​ongotpointercapture: null​oninput: null​oninvalid: null​onkeydown: null​onkeypress: null​onkeyup: null​onload: null​onloadeddata: null​onloadedmetadata: null​onloadend: null​onloadstart: null​onlostpointercapture: null​onmousedown: null​onmouseenter: null​onmouseleave: null​onmousemove: null​onmouseout: null​onmouseover: null​onmouseup: null​onmozfullscreenchange: null​onmozfullscreenerror: null​onpaste: null​onpause: null​onplay: null​onplaying: null​onpointercancel: null​onpointerdown: null​onpointerenter: null​onpointerleave: null​onpointermove: null​onpointerout: null​onpointerover: null​onpointerup: null​onprogress: null​onratechange: null​onreset: null​onresize: null​onscroll: null​onsecuritypolicyviolation: null​onseeked: null​onseeking: null​onselect: null​onselectionchange: null​onselectstart: null​onslotchange: null​onstalled: null​onsubmit: null​onsuspend: null​ontimeupdate: null​ontoggle: null​ontransitioncancel: null​ontransitionend: null​ontransitionrun: null​ontransitionstart: null​onvolumechange: null​onwaiting: null​onwebkitanimationend: null​onwebkitanimationiteration: null​onwebkitanimationstart: null​onwebkittransitionend: null​onwheel: null​outerHTML: "<input type=\"checkbox\" value=\"HTML\" name=\"chk_info\">"​
ownerDocument: HTMLDocument http://www.homejjang.com/05/CheckBox.php​
parentElement: <td>

parentNode: <td>

part: DOMTokenList []​pattern: ""​placeholder: ""​prefix: null​previousElementSibling: null​previousSibling: null​readOnly: false​required: false​scrollHeight: 10​scrollLeft: 0​scrollLeftMax: 0​scrollTop: 0​scrollTopMax: 0​scrollWidth: 10​selectionDirection: null​selectionEnd: null​selectionStart: null​shadowRoot: null​size: 20​slot: ""​spellcheck: false​src: ""​step: ""​
style: CSS2Properties(0)​tabIndex: 0​tagName: "INPUT"​textContent: ""​textLength: 4​title: ""​type: "checkbox"​useMap: ""​validationMessage: ""​
validity: ValidityState { valueMissing: false, typeMismatch: false, patternMismatch: false, … }​value: "HTML"​valueAsDate: null​valueAsNumber: NaN​
webkitEntries: Array []​webkitdirectory: false​width: 0​willValidate: true

위에서 볼 수 있듯이 수십 개의 프로퍼티(속성)로 구성되어 있다.(위의 속성 값들은 무시하자. 참고를 위해 다른 사이트에서 input 객체를 긁어왔다.)

 

<input type="checkbox" name="value" checked>

위의 HTML 코드에서 input 태그는 체크되어 있음을 알 수 있다. 위와 같이 작성할 경우, input 객체의 checked 프로퍼티가 true이기 때문이다. checked 프로퍼티는 html 엘리먼트의 애트리뷰트는 아니지만 checked라고 쓸 경우 input 태그의 checked 프로퍼티를 true로 만들어준다. 즉 위에서 type, name은 애트리뷰트이지만, 체크 여부를 판단하는 checked 프로퍼티가 별도로 존재함을 알 수 있다. 둘을 구분할 수 있다면, .attr()과 .prop()의 사용법 차이는 명확해진다.

 

정리하면, id나 class, style, name과 같이 html의 애트리뷰트와 관련된 값을 가져오거나 사용할 때는 attr() 메서드를, checked나 required 같은 특정 객체의 프로퍼티 값(공식 문서에서는 electedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, defaultSelected 등이 언급되었다.)을 가져오거나 설정할 때는 prop을 쓰면 될 것 같다.

'📔개발자 일기 | | TIL' 카테고리의 다른 글

[20220306] 개발자 일기 & TIL  (0) 2022.03.06
[20220303] 개발자 일기  (0) 2022.03.03
[20220228] 개발자 일기 & TIL  (0) 2022.02.28
[20220224] TIL  (0) 2022.02.24
[20220223] TIL  (0) 2022.02.23