선택기 객체가 유효하지 않은 경우 jQuery가 폭탄을 터뜨리지 않는 이유는 무엇입니까?
최근에 몇 가지 코드를
$("#divMenuContainer:visible").hide("explode");
그러나 그것을 작동시키기 위해 시간을 보낸 후 내 선택기가 존재하지 않는 div를 참조하고 있음을 깨달았습니다.
쿼리의 결과는 단순히 실행되지 않았다는 것입니다.
분명히 이것은 의도적으로 설계된 것입니다. 누군가 예외를 일으키기보다는이 디자인 선택이 만들어진 이유에 대한 논리를 설명 할 수 있습니까?
이해하려고 비판하려고하지 않습니다.
여기에는 몇 가지 좋은 이유가 있습니다. "체인 가능성"이 주된 동력입니다. 체인을 통해 매우 간결한 코드를 작성할 수있는 능력은 아무 오류없이 작동하도록해야합니다. 예를 들면 다음과 같습니다.
$("#divMenuContainer:visible").hide("explode").add("#another").fadeIn();
체인의 각 객체는 DOM 요소를 참조하지 않더라도 나중에 더 추가 될 수 있습니다. 또는 다른 예를 들어 보겠습니다.
$("#divMenuContainer:visible").live("click", function() { ... });
이 경우 우리는 선택자가 찾은 요소에 대해 신경 쓰지 않고 선택자 자체에 신경을 씁니다. 또 다른 것이 있습니다.
$("#divMenuContainer:visible").find(".child").hide("explode").end().fadeOut();
자식이 없더라도 나중에 체인 .prevObject으로 돌아가서 참조를 계속 사용 하여 체인 위로 돌아갈 수 있습니다.
도서관이있는 그대로의 이점을 보여주는 이와 같은 수십 가지 사례가 있습니다. 이유에 관해서 는 jQuery를 만든 John Resig의 인터뷰 에서 그는 그것이 어떻게 작동했는지를 말합니다. 그는 그가 얻을 수있는 한 간결한 코드를 추구했고, 체이닝 모델은 모자에서 나온 것입니다. 또한 많은 이점이 있습니다. 위의 예는 그 중 몇 가지에 불과합니다.
명확하게 말해서 , 체인의 모든 속성이 좋은 것이 아니라 많은 장점이 있습니다.
이 페이지를 예로 들어 보겠습니다. 다음과 같은 것이 있다면 어떨까요?
$(".comment").click(replyToFunction);
아직 댓글이 없기 때문에 실패 해야합니까 ? 실제로는 아닙니다. 예상 한대로 여기에서 오류가 발생하는 것을 원하지는 않습니다. 요소가 존재하면 그렇지 않은 경우 수행합니다. 내 요점은 적어도 내 경험상 누락 된 요소 때문에 오류를 던지지 않는 것이 하나를 던지는 것보다 훨씬 더 유용하다는 것입니다.
귀하의 질문에서 #ID선택자는 단일 요소 만 기대하는 매우 특별한 경우이므로 실패해야한다고 주장 할 수 있습니다 ...하지만 다른 선택자와 일치하지 않으며 라이브러리를 원합니다. 일관성을 유지합니다.
거의 모든 다른 선택기를 사용 하면 0- 많은 요소를 예상하므로 요소를 찾지 못할 때 실패하는 것은 대부분의 상황에서 훨씬 덜 바람직하며 .live()위와 같은 경우에는 더욱 그렇습니다 .
쿼리 라고 생각하면됩니다 . 기준과 일치하는 모든 "레코드"(DOM 요소)를 요청합니다. 결과는 0 개의 레코드 세트입니다.
그런 다음 제로 레코드를 반복하고 작업을 적용합니다. :)
SQL 또는 배열로 동일한 작업을 수행하면 대부분의 언어에서 동일한 방식으로 작동합니다. 0 개의 레코드 모음은 오류 상태가 아닙니다.
var things = $("invalid selector");
$("p").text("The object is valid: " + things + " but has " + things.length + " elements.")
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p></p>
유연성의 문제입니다. 나 자신은 당신이 요구하는 것과 동일한 보호를 원합니다. 당신은 항상 그것을 스스로 할 수 있습니다. 사용하다:
jQuery.fn.single = function() {
if (this.length != 1) {
throw new Error("Expected 1 matching element, found " + this.length);
}
return this;
};
이제 $ ( "input : checked"). single ()을 사용하여 단일 항목을 반환하거나 오류를 제공하는지 확인합니다.
jQuery ()는 오류를 방지하기 위해 항상 jQuery 객체를 반환하지만 더 중요한 것은 다음과 같습니다.
따라서 반응 형 코드를 작성할 수 있습니다.
do X if Y is present
Y가 없으면 X는 계산하지 않습니다.
이것은 당신이 글로벌 init 크로스 페이지를 가질 수 있고 그들이 무언가를 찾든 안 찾든 그냥 init 플러그인을 가질 수 있다는 것을 의미합니다.
$(function(){
// does nothing if the page contains no element with className 'accordion'
$('.accordion').implementAccordion();
// usually on a single page, but we can add it to a global js file nontheless.
$('.validate-form').implementFormValidator();
});
물론 일부 플러그인은 실제로 잘못 작성되어 오류가 발생합니다.
라이브러리에 대한 jQuerys (실제로 John Resigs라고 생각합니다) 철학의 일부입니다.
It trys to be "kind" to you and your customers, that in turn means, it'll throw exceptions pretty rarely
(like really rarely)
But like always, you can easily extend it like:
(function(_jQuery){
jQuery = function(){
var ret = _jQuery.apply(this, arguments);
if(!ret.length) throw new Error('empty selector');
return ret;
};
}(jQuery));
But like Nick says in a comment, most times this is not a desired behavior. If you want to have it for some reason anyway, a code snippet like the above should do it.
A selector that doesn't refer to any elements is still a legal selector, and it may be intentional. It may be that a given selector will sometimes return elements, and you would want to be able to use such a selector without a chance to throw runtime errors.
A good example is when you want to do something with all the checked checkboxes
$("input:checked")
...you don't know how many are checked. Could be any, all or none. It depends on the user.
So, instead of having to write code like
var checkedInputs = $("input:checked");
if (checkedInputs && checkedInputs .length > 0) {
checkedInputs .doStuff();
}
You can just
$("input:checked").doStuff();
And if they have made selections, great, stuff gets done. If not... no harm, no foul.
because $("#thisdivdoesntexist") in jQuery still returns an 'empty' jQuery Object and all jQuery objects have their methods, so no error.
this is actually a good thing. If this were to throw an error, you would need some extra checks in a lot of cases before doing something, meaning you'd have a lot of 'overload' code. although it would not be bad practice to check if it exists before calling a method on the object, when the selector returns nothing, not all javascript will halt (which is what would happen if it'd throw an error)
therefore you can use selectors globally, even if some pages don't have the selector, without really having to worry about that.
Normally I only continue if the element(s) exist by doing something along the lines of:
var aThing = $("#myElement");
if(aThing.length){
//my code here
}
I think that it is probably to do with the fact that your selector:
$("#divMenuContainer:visible")
Under the covers returns a jQuery object, containing a number of possible matches. The Hide function is then performed on each of these. I imagine not throwing an exception in this case makes a certain kind of sense, as you have a list with zero entries, rather than getting a null back.
It just makes sense to me... If your selector doesn't match any element, you can still call all the normal jQuery prototype functions without generating errors! The worst case, you end up with an 'empty' jQuery set, applying your changes to no elements.
i guess because it'll be used on the front-end - end users shouldn't see exceptions because a developer has written some bad code. it's probably generally safer to fail silently in this case.
I thought it was to be like CSS, meaning if you are trying to style an element that does not exist, you get no error.
'IT박스' 카테고리의 다른 글
| SQL Server Windows 모드에서 혼합 모드로 변경하려면 어떻게합니까 (SQL Server 2008)? (0) | 2020.10.24 |
|---|---|
| Haml에서 어떻게 동적 ID를 만드나요? (0) | 2020.10.24 |
| Quartz : 절대 실행되지 않는 Cron 표현식 (0) | 2020.10.24 |
| CSS에서 회전하는 지구본 (0) | 2020.10.24 |
| TestFlight 용 iTunes Connect에 빌드를 어떻게 업로드합니까? (0) | 2020.10.24 |