Modernizr를 사용하여 IE를 감지하는 올바른 방법?


84

Modernizr JS 라이브러리를 사용하여 일부 브라우저 속성을 감지하여 표시하거나 표시하지 않을 콘텐츠를 결정하고 싶었습니다.

HTML5와 SWF를 모두 출력하는 Pano2VR 이라는 앱이 있습니다 . iOS 기기 사용자를위한 HTML5가 필요합니다.

그러나 IE는이 "HTML5"출력을 전혀 렌더링하지 않습니다. 그들의 출력은 CSS3 3D 변환 및 WebGL을 사용하는 것으로 보입니다. 하나 이상의 IE9에서 지원되지 않는 것 같습니다.

따라서 이러한 사용자를 위해 Flash 버전을 표시해야합니다. IFRAME을 사용하고 Modernizr 스크립트를 통해 SRC를 전달하거나 브라우저에 따라 올바른 IFRAME 코드를 작성하십시오.

이 모든 것이 Modernizr를 사용하여 IE가 아닌 IE를 감지하는 방법으로 연결됩니까? 아니면 CSS 3D 변환을 감지합니까?

아니면 다른 방법이 있습니까?

답변:


1

기능을 테스트해야한다는 데 동의하지만 " '최신 브라우저'에서 지원하지만 '이전 브라우저'는 지원하지 않는 기능은 무엇입니까?"에 대한 간단한 답을 찾기가 어렵습니다.

그래서 여러 브라우저를 실행하고 Modernizer를 직접 조사했습니다. 꼭 필요한 몇 가지 기능을 추가 한 다음 "inputtypes.color"를 추가했습니다. Chrome, Firefox, Opera, Edge ... 그리고 IE11이 아닌 모든 주요 브라우저를 포함하는 것 같기 때문입니다. 이제 사용자가 Chrome / Opera / Firefox / Edge를 사용하는 것이 더 나을 것이라고 부드럽게 제안 할 수 있습니다.

이것이 제가 사용하는 것입니다. 특정 사례에 대해 테스트 할 항목 목록을 편집 할 수 있습니다. 누락 된 기능이 있으면 false를 반환합니다.

/**
 * Check browser capabilities.
 */
public CheckBrowser(): boolean
{
    let tests = ["csstransforms3d", "canvas", "flexbox", "webgl", "inputtypes.color"];

    // Lets see what each browser can do and compare...
    //console.log("Modernizr", Modernizr);

    for (let i = 0; i < tests.length; i++)
    {
        // if you don't test for nested properties then you can just use
        // "if (!Modernizr[tests[i]])" instead
        if (!ObjectUtils.GetProperty(Modernizr, tests[i]))
        {
            console.error("Browser Capability missing: " + tests[i]);
            return false;
        }
    }

    return true;
}

그리고 여기에 "inputtypes.color"에 필요한 GetProperty 메소드가 있습니다.

/**
 * Get a property value from the target object specified by name.
 * 
 * The property name may be a nested property, e.g. "Contact.Address.Code".
 * 
 * Returns undefined if a property is undefined (an existing property could be null).
 * If the property exists and has the value undefined then good luck with that.
 */
public static GetProperty(target: any, propertyName: string): any
{
    if (!(target && propertyName))
    {
        return undefined;
    }

    var o = target;

    propertyName = propertyName.replace(/\[(\w+)\]/g, ".$1");
    propertyName = propertyName.replace(/^\./, "");

    var a = propertyName.split(".");

    while (a.length)
    {
        var n = a.shift();

        if (n in o)
        {
            o = o[n];

            if (o == null)
            {
                return undefined;
            }
        }
        else
        {
            return undefined;
        }
    }

    return o;
}

195

Modernizr는 브라우저를 감지하지 않고 어떤 기능과 기능이 있는지 감지하며 이것이 수행하려는 작업의 전체적인 요점입니다.

이와 같은 간단한 감지 스크립트에 연결 한 다음이를 사용하여 선택할 수 있습니다. 필요한 경우를 대비하여 버전 감지도 포함했습니다. IE의 버전 만 확인하려면 "MSIE"값을 가진 navigator.userAgent를 찾을 수 있습니다.

var BrowserDetect = {
        init: function () {
            this.browser = this.searchString(this.dataBrowser) || "Other";
            this.version = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "Unknown";
        },
        searchString: function (data) {
            for (var i = 0; i < data.length; i++) {
                var dataString = data[i].string;
                this.versionSearchString = data[i].subString;

                if (dataString.indexOf(data[i].subString) !== -1) {
                    return data[i].identity;
                }
            }
        },
        searchVersion: function (dataString) {
            var index = dataString.indexOf(this.versionSearchString);
            if (index === -1) {
                return;
            }

            var rv = dataString.indexOf("rv:");
            if (this.versionSearchString === "Trident" && rv !== -1) {
                return parseFloat(dataString.substring(rv + 3));
            } else {
                return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
            }
        },

        dataBrowser: [
            {string: navigator.userAgent, subString: "Edge", identity: "MS Edge"},
            {string: navigator.userAgent, subString: "MSIE", identity: "Explorer"},
            {string: navigator.userAgent, subString: "Trident", identity: "Explorer"},
            {string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
            {string: navigator.userAgent, subString: "Opera", identity: "Opera"},  
            {string: navigator.userAgent, subString: "OPR", identity: "Opera"},  

            {string: navigator.userAgent, subString: "Chrome", identity: "Chrome"}, 
            {string: navigator.userAgent, subString: "Safari", identity: "Safari"}       
        ]
    };
    
    BrowserDetect.init();
    document.write("You are using <b>" + BrowserDetect.browser + "</b> with version <b>" + BrowserDetect.version + "</b>");

그런 다음 간단히 확인할 수 있습니다.

BrowserDetect.browser == 'Explorer';
BrowserDetect.version <= 9;

2
감사. 나는 마침내 문제가 webgl 지원이 필요한 파일이라는 것을 추적했습니다. 따라서 Modernizer를 사용하여이를 테스트하고 다른 코드 블록의 문서 작성을 수행 할 수 있습니다. 그러나 이것은 브라우저 감지를위한 훌륭한 솔루션입니다. 다시 한 번 감사드립니다.
Steve

2
기억해야 할 한 가지 : UA 문자열은 완전히 사용자가 구성 할 수 있습니다. 따라서 UA 문자열을 확인하는 것은 브라우저를 확인하는 일관된 방법이 아닙니다. developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent "Notes"섹션 :Browser identification based on detecting the user agent string is unreliable and is not recommended, as the user agent string is user configurable.
Andrew Senner

51
예,하지만 수정 / 스푸핑 / 잘못된 UA 문자열로 웹을 검색하는 사용자 비율은 얼마입니까? 극소수의 사용자가 사이트에서 최적의 경험을 할 수 있도록 엔지니어링 시간을 얼마나 투자하고 싶으십니까? UA 문자열을 통한 브라우저 스니핑은 실용적이고 건전한 접근 방식입니다.
Jed Richards

17
@Wintamute, 더 이상 동의 할 수 없습니다. "특징 탐지는 악하다"같은 종류의 강의에 질려 버려. 우리는 예술을 추구하는 것이 아니라 엔지니어링을하고 있습니다
Philip007 2013-07-03

9
누군가가 자신의 UA 문자열을 수정하면 자신이 무엇을하는지 알고 결과를 처리 할 수 ​​있다는 일반적인 가정입니다. 실제로 이것은 브라우저 버전을 서버에 선언하기 위해 UA 문자열이 존재하는 것입니다. 클라이언트가 그것에 대해 거짓말을하고 싶다면, 그건 그냥 인생입니다! 물론 사용자의 동의없이 문자열이 변경 될 가능성이 적지 만 실제로는 실제 문제가 아닙니다. 사용자에게 먹이를주고 등을 문질러 야합니까?
Rolf

20

Modernizr 를 사용 하여 SVG SMIL 을 확인하여 IE가 아닌 IE를 검색 할 수 있습니다. 애니메이션 지원 .

Modernizr 설정에 SMIL 기능 감지를 포함했다면 간단한 CSS 접근 방식을 사용하고 Modernizr이 html 요소에 적용 하는 .no-smil 클래스를 대상으로 지정할 수 있습니다 .

html.no-smil {
  /* IE/Edge specific styles go here - hide HTML5 content and show Flash content */
}

또는 다음과 같이 간단한 JavaScript 접근 방식으로 Modernizr를 사용할 수 있습니다.

if ( Modernizr.smil ) {
  /* set HTML5 content */
} else {
  /* set IE/Edge/Flash content */
}

IE / Edge는 언젠가 SMIL을 지원할 수 있습니다. 있지만 현재는 그렇게 할 계획이 없습니다.

참고 로 caniuse.comSMIL 호환성 차트에 대한 링크가 있습니다.


최고의 답변 imo. 너무 간단합니다
Batman

2
이것이 작동하지만 지금은 작동합니다. 기능 감지 및 Modernizr의 요점은 내일 무슨 일이 일어날 지 걱정할 필요가 없다는 것입니다. Edge가 내일 smil 지원으로 업데이트하면 코드가 더 이상 작동하지 않으며 심지어 모를 수도 있습니다.
Jason


1
이것은 매우 간단 해 보였지만 Edge는 이제 SMIL을 지원합니다 .
Jeremy Carlson

12

CSS 3D 변환 감지

Modernizr 는 CSS 3D 변환을 감지 할 수 있습니다 . 진실성Modernizr.csstransforms3d 브라우저가 지원하는지 여부를 알려줍니다.

위의 링크를 사용하면 Modernizr 빌드에 포함 할 테스트를 선택할 수 있으며 원하는 옵션을 사용할 수 있습니다.


특히 IE 감지

또는 user356990이 대답했듯이 IE와 IE 만 검색하는 경우 조건부 주석을 사용할 수 있습니다. 전역 변수를 만드는 대신 HTML5 Boilerplate의 <html>조건부 주석 트릭을 사용하여 클래스를 할당 할 수 있습니다 .

<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->

이미 jQuery가 초기화 된 경우 $('html').hasClass('lt-ie9'). 조건부로 jQuery 1.x 또는 2.x를로드 할 수 있도록 현재 사용중인 IE 버전을 확인해야하는 경우 다음과 같이 할 수 있습니다.

myChecks.ltIE9 = (function(){
    var htmlElemClasses = document.querySelector('html').className.split(' ');
    if (!htmlElemClasses){return false;}
    for (var i = 0; i < htmlElemClasses.length; i += 1 ){
      var klass = htmlElemClasses[i];
      if (klass === 'lt-ie9'){
        return true;
      }
    }
    return false;
}());

NB IE 조건부 주석은 IE9까지만 지원됩니다. IE10부터 Microsoft는 브라우저 감지보다는 기능 감지 사용을 권장합니다.


어떤 방법을 선택하든 다음으로 테스트합니다.

if ( myChecks.ltIE9 || Modernizr.csstransforms3d ){
    // iframe or flash fallback
} 

||물론 문자 그대로 받아들이지 마십시오 .


개인적으로 나는 항상 오히려 브라우저 탐지보다 기능 기반 탐지을 시도
크리스

@Chris 당신을 위해 좋은, 여기 같은? 제 대답을 실제로 읽은 것 같지 않습니다.
iono 2014

귀하의 답변은 실제로 기능 감지 사용을 제안한 첫 번째 답변이므로 다른 사람이 댓글을 읽으면 도움이 될 것이라고 생각했습니다
Chris

@Chris 오, 죄송합니다. 나는 당신이 IE 테스트를 포함시킨 것에 대해 나를 비난한다고 생각했습니다.
iono

9

html5 상용구에서 사용 된 작업의 JS 버전 (기능 감지 및 UA 스니핑 조합 사용)을 찾고 있다면 :

var IE = (!! window.ActiveXObject && +(/msie\s(\d+)/i.exec(navigator.userAgent)[1])) || NaN;
if (IE < 9) {
    document.documentElement.className += ' lt-ie9' + ' ie' + IE;
}

3

이 주제에 대해 더 많은 연구를 한 후에 IE 10+를 대상으로하는 다음 솔루션을 사용하게되었습니다. IE10 & 11은 -ms- 고 대비 미디어 쿼리를 지원하는 유일한 브라우저이므로 JS가없는 좋은 옵션입니다.

@media screen and (-ms-high-contrast: active), screen and (-ms-high-contrast: none) {  
   /* IE10+ specific styles go here */  
}

완벽하게 작동합니다.


2

CSS 트릭은 IE 11을 대상으로하는 좋은 솔루션입니다.

http://css-tricks.com/ie-10-specific-styles/

.NET 및 Trident / 7.0은 IE에 고유하므로 IE 버전 11을 감지하는 데 사용할 수 있습니다.

그런 다음 코드는 'data-useragent'속성이있는 html 태그에 사용자 에이전트 문자열을 추가하므로 IE 11을 구체적으로 타겟팅 할 수 있습니다.


1

IE와 대부분의 다른 것을 감지해야했고 UA 문자열에 의존하고 싶지 않았습니다. 나는es6numberModernizr와 함께 하면 내가 원하는 것을 정확히 알 수 있습니다. IE가 ES6 번호를 지원하지 않을 것으로 예상하기 때문에이 변경에 대해별로 걱정하지 않습니다. 이제 모든 버전의 IE와 Edge / Chrome / Firefox / Opera / Safari의 차이점을 알고 있습니다.

자세한 내용은 여기 : http://caniuse.com/#feat=es6-number

저는 Opera Mini의 거짓 음성에 대해 정말로 걱정하지 않습니다. 너는 아마.


0

< !-- [if IE] > 해킹을 사용 하여 일반 js 코드에서 테스트되는 전역 js 변수를 설정할 수 있습니다 . 약간 못 생겼지 만 나를 위해 잘 작동했습니다.


23
Internet Explorer> = 10에서는 조건부 주석이 더 이상 지원되지 않습니다.
초보
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.