innerHTML에 비해 createElement의 장점은 무엇입니까?
실제로 innerHTML보다 createElement를 사용하면 어떤 이점이 있습니까? innerHTML을 사용하는 것이 성능과 코드 가독성 / 유지 보수 측면에서 더 효율적이라고 확신하기 때문에 질문하고 있지만 팀원들은 코딩 접근 방식으로 createElement를 사용하기로 결정했습니다. createElement가 어떻게 더 효율적일 수 있는지 이해하고 싶습니다.
Pekka가 이미 언급했듯이 안전 외에도 createElement
수정 innerHTML
(이미있는 것을 버리고 교체하는 것과는 반대로) 대신 사용 하는 데는 몇 가지 이점이 있습니다 .
요소를 추가 할 때 DOM 요소에 대한 기존 참조를 유지합니다.
에 추가 (또는 수정) 할 때 innerHTML
해당 요소 내의 모든 DOM 노드를 다시 구문 분석하고 다시 만들어야합니다. 노드에 대한 참조를 저장하면 더 이상 표시되지 않기 때문에 본질적으로 쓸모가 없습니다.
DOM 요소에 연결된 이벤트 핸들러를 보존합니다.
이것은 마지막 사례의 특별한 경우 (일반적이지만)에 불과합니다. 설정 innerHTML
은 생성 된 새 요소에 이벤트 핸들러를 자동으로 다시 연결하지 않으므로 직접 추적하고 수동으로 추가해야합니다. 이벤트 위임은 경우에 따라이 문제를 해결할 수 있습니다.
어떤 경우에는 더 간단하고 빠를 수 있습니다.
많은 추가 작업을 수행하는 경우, innerHTML
단순한 변경의 경우 더 빠르지 만 반복적으로 다시 구문 분석하고 요소를 만드는 속도가 더 느리기 때문에 재설정을 계속하고 싶지는 않습니다 . 이를 해결하는 방법은 HTML을 문자열로 작성하고 innerHTML
완료되면 한 번 설정 하는 것입니다. 상황에 따라 문자열 조작은 단순히 요소를 만들고 추가하는 것보다 느릴 수 있습니다.
또한 문자열 조작 코드가 더 복잡 할 수 있습니다 (특히 안전을 원하는 경우).
사용하기 더 편리하게 만드는 기능이 있습니다 createElement
.
function isArray(a) {
return Object.prototype.toString.call(a) === "[object Array]";
}
function make(desc) {
if (!isArray(desc)) {
return make.call(this, Array.prototype.slice.call(arguments));
}
var name = desc[0];
var attributes = desc[1];
var el = document.createElement(name);
var start = 1;
if (typeof attributes === "object" && attributes !== null && !isArray(attributes)) {
for (var attr in attributes) {
el[attr] = attributes[attr];
}
start = 2;
}
for (var i = start; i < desc.length; i++) {
if (isArray(desc[i])) {
el.appendChild(make(desc[i]));
}
else {
el.appendChild(document.createTextNode(desc[i]));
}
}
return el;
}
다음과 같이 부르면 :
make(["p", "Here is a ", ["a", { href:"http://www.google.com/" }, "link"], "."]);
다음과 같은 HTML을 얻을 수 있습니다.
<p>Here is a <a href="http://www.google.com/">link</a>.</p>
innerHTML
더 빠를 수 있지만 가독성이나 유지 관리 측면에서 더 좋다는 데 동의하지 않습니다. 모든 것을 하나의 문자열에 넣는 것이 더 짧을 수 있지만 코드가 짧다고 항상 유지 관리가 더 쉬운 것은 아닙니다.
문자열 연결은 더하기 '와 따옴표 열기 및 닫기를 추적하기 어려워 지므로 동적 DOM 요소를 만들어야하는 경우에만 확장되지 않습니다. 다음 예를 고려하십시오.
결과 요소는 콘텐츠가 동적 인 두 개의 내부 범위가있는 div입니다. 첫 번째 범위 내의 클래스 이름 (전사) 중 하나도 동적입니다.
<div>
<span class="person warrior">John Doe</span>
<span class="time">30th May, 2010</span>
</div>
다음 변수가 이미 정의되어 있다고 가정합니다.
var personClass = 'warrior';
var personName = 'John Doe';
var date = '30th May, 2010';
innerHTML 만 사용하고 모든 것을 단일 문자열로 매싱하면 다음을 얻을 수 있습니다.
someElement.innerHTML = "<div><span class='person " + personClass + "'>" + personName + "</span><span class='time'>" + date + "</span></div>";
위의 혼란은 매번 문자열을 열고 닫지 않도록 문자열 교체를 사용하여 정리할 수 있습니다. 간단한 텍스트 교체의 경우에도 replace
문자열 연결 대신 사용 하는 것을 선호합니다 .
이것은 키와 대체 값의 객체를 가져와 문자열에서 대체하는 간단한 함수입니다. 키가 $
특수 값임을 나타 내기 위해 접두사가 붙는 것으로 가정합니다 . $
대체 값 등에 나타나는 이스케이프 또는 가장자리 케이스를 처리하지 않습니다 .
function replaceAll(string, map) {
for(key in map) {
string = string.replace("$" + key, map[key]);
}
return string;
}
var string = '<div><span class="person $type">$name</span><span class="time">$date</span></div>';
var html = replaceAll(string, {
type: personClass,
name: personName,
date: date
});
someElement.innerHTML = html;
This can be improved by separating the attributes, text, etc. while constructing the object to get more programmatic control over the element construction. For example, with MooTools we can pass object properties as a map. This is certainly more maintainable, and I would argue more readable as well. jQuery 1.4 uses a similar syntax to pass a map for initializing DOM objects.
var div = new Element('div');
var person = new Element('span', {
'class': 'person ' + personClass,
'text': personName
});
var when = new Element('span', {
'class': 'time',
'text': date
});
div.adopt([person, when]);
I wouldn't call the pure DOM approach below to be any more readable than the ones above, but it's certainly more maintainable because we don't have to keep track of opening/closing quotes and numerous plus signs.
var div = document.createElement('div');
var person = document.createElement('span');
person.className = 'person ' + personClass;
person.appendChild(document.createTextNode(personName));
var when = document.createElement('span');
when.className = 'date';
when.appendChild(document.createTextNode(date));
div.appendChild(person);
div.appendChild(when);
The most readable version would most likely result from using some sort of JavaScript templating.
<div id="personTemplate">
<span class="person <%= type %>"><%= name %></span>
<span class="time"><%= date %></span>
</div>
var div = $("#personTemplate").create({
name: personName,
type: personClass,
date: date
});
User bobince puts a number of cons very, very well in his critique of jQuery.
... Plus, you can make a div by saying $(''+message+'') instead of having to muck around with document.createElement('div') and text nodes. Hooray! Only... hang on. You've not escaped that HTML, and have probably just created a cross-site-scripting security hole, only on the client side this time. And after you'd spent so long cleaning up your PHP to use htmlspecialchars on the server-side, too. What a shame. Ah well, no-one really cares about correctness or security, do they?
jQuery's not wholly to blame for this. After all, the innerHTML property has been about for years, and already proved more popular than DOM. But the library certainly does encourage that style of coding.
As for performance:
InnerHTML is most definitely going to be slower, because it needs to be parsed and internally converted into DOM elements (maybe using the
createElement
method).
InnerHTML is faster in all browsers according to the quirksmode benchmark provided by @Pointy.
As for readability and ease of use, you will find me choosing innerHTML
over createElement
any day of the week in most projects. But as you can see, there are many points speaking for createElement
.
You should use createElement if you want to keep references in your code. InnerHTML can sometimes create a bug that is hard to spot.
HTML code:
<p id="parent">sample <span id='test'>text</span> about anything</p>
JS code:
var test = document.getElementById("test");
test.style.color = "red"; //1 - it works
document.getElementById("parent").innerHTML += "whatever";
test.style.color = "green"; //2 - oooops
1) you can change the color
2) you can't change color or whatever else anymore, because in the line above you added something to innerHTML and everything is re-created and you have access to something that doesn't exist anymore. In order to change it you have to again getElementById.
You need to remember that it also affects any events. You need to re-apply events.
InnerHTML is great, because it is faster and most time easier to read but you have to be careful and use it with caution. If you know what you are doing you will be OK.
참고URL : https://stackoverflow.com/questions/2946656/advantages-of-createelement-over-innerhtml
'Nice programing' 카테고리의 다른 글
Android 애플리케이션의 성능을 테스트하는 방법은 무엇입니까? (0) | 2020.10.24 |
---|---|
hg에서 파일의 변경 사항을 제거하는 방법 (0) | 2020.10.24 |
NHibernate Linq 공급자에서 Fetch 대 FetchMany (0) | 2020.10.24 |
텍스트 파일의 문자 인코딩을 감지하는 방법은 무엇입니까? (0) | 2020.10.24 |
Internet Explorer에서 "브라우저 모드"와 "문서 모드"의 차이점 (0) | 2020.10.24 |