Cách chính xác để sử dụng Modernizr để phát hiện IE?


84

Tôi muốn sử dụng thư viện Modernizr JS để phát hiện một số thuộc tính của trình duyệt nhằm xác định nội dung nào sẽ hiển thị hoặc không hiển thị.

Tôi có một ứng dụng tên là Pano2VR xuất ra cả HTML5 và SWF. Tôi cần HTML5 cho người dùng thiết bị iOS.

Tuy nhiên, IE hoàn toàn không hiển thị đầu ra "HTML5" này. Có vẻ như đầu ra của họ sử dụng các biến đổi 3D CSS3 và WebGL, một hoặc nhiều thứ dường như không được hỗ trợ trong IE9.

Vì vậy, đối với những người dùng đó, tôi cần hiển thị phiên bản Flash. Tôi đã định sử dụng IFRAME và chuyển SRC qua tập lệnh Modernizr hoặc document. Viết ra mã IFRAME chính xác tùy thuộc vào trình duyệt.

Tất cả những điều đó dẫn đến làm thế nào để tôi sử dụng Modernizr để phát hiện đơn giản là IE hay không phải IE? Hoặc phát hiện các biến đổi 3D CSS?

Hoặc là có một cách khác để làm điều này?

Câu trả lời:


1

Tôi đồng ý rằng chúng ta nên kiểm tra các khả năng, nhưng thật khó để tìm ra câu trả lời đơn giản cho "những khả năng nào được hỗ trợ bởi 'trình duyệt hiện đại' chứ không phải 'trình duyệt cũ'?"

Vì vậy, tôi đã kích hoạt một loạt các trình duyệt và kiểm tra trực tiếp Modernizer. Tôi đã thêm một vài khả năng mà tôi chắc chắn yêu cầu, và sau đó tôi thêm "inputtypes.color" vì điều đó dường như bao gồm tất cả các trình duyệt chính mà tôi quan tâm: Chrome, Firefox, Opera, Edge ... và KHÔNG PHẢI IE11. Bây giờ tôi có thể nhẹ nhàng gợi ý rằng người dùng sẽ tốt hơn với Chrome / Opera / Firefox / Edge.

Đây là những gì tôi sử dụng - bạn có thể chỉnh sửa danh sách những thứ cần kiểm tra cho trường hợp cụ thể của bạn. Trả về false nếu thiếu bất kỳ khả năng nào.

/**
 * 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;
}

Và đây là phương thức GetProperty cần thiết cho "inputtypes.color".

/**
 * 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 không phát hiện các trình duyệt như vậy, nó phát hiện tính năng và khả năng nào hiện có và đây là toàn bộ những gì nó đang cố gắng thực hiện.

Bạn có thể thử kết nối với một tập lệnh phát hiện đơn giản như thế này và sau đó sử dụng nó để đưa ra lựa chọn của bạn. Tôi cũng đã bao gồm tính năng Phát hiện Phiên bản trong trường hợp cần thiết. Nếu bạn chỉ muốn kiểm tra bất kỳ phiên bản IE nào, bạn chỉ cần tìm kiếm điều hướng.userAgent có giá trị là "MSIE".

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>");

Sau đó, bạn có thể chỉ cần kiểm tra:

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

2
Cảm ơn. Cuối cùng tôi cũng theo dõi được rằng vấn đề là tệp của họ cần hỗ trợ webgl. Vì vậy, tôi có thể sử dụng Modernizer để kiểm tra điều đó và thực hiện một document.write của một khối mã của khối kia. Nhưng đây là một giải pháp tuyệt vời để phát hiện trình duyệt. Cảm ơn một lần nữa.
Steve

2
Một điều cần nhớ: Chuỗi UA hoàn toàn có thể định cấu hình bởi người dùng .. Vì vậy, kiểm tra chuỗi UA KHÔNG phải là cách nhất quán để kiểm tra trình duyệt. developer.mozilla.org/en-US/docs/DOM/window.navigator.userAgent Trong phần "Ghi chú":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
Có, nhưng có bao nhiêu phần trăm người dùng duyệt web với chuỗi UA được sửa đổi / giả mạo / không chính xác? Bạn muốn dành bao nhiêu thời gian kỹ thuật để đảm bảo rằng thiểu số nhỏ bé có trải nghiệm tối ưu trên trang web của bạn? Đánh hơi trình duyệt thông qua chuỗi UA là một cách tiếp cận thực tế và lành mạnh.
Jed Richards

17
@Wintamute, không thể đồng ý hơn. Phát bệnh với kiểu bài giảng "phát hiện tính năng là xấu". Chúng tôi đang làm kỹ thuật, không theo đuổi nghệ thuật
Philip007

9
Giả định chung là nếu ai đó sửa đổi chuỗi UA của họ, thì họ biết họ đang làm gì và họ có thể giải quyết hậu quả. Trên thực tế, đây chính xác là chuỗi UA tồn tại - để khai báo phiên bản trình duyệt cho máy chủ. Nếu khách hàng muốn nói dối về điều đó, thì đó chỉ là cuộc sống! Tất nhiên có một khả năng nhỏ là chuỗi bị thay đổi mà không có sự đồng ý của người dùng nhưng trên thực tế, đó không phải là mối quan tâm thực sự - và chúng ta có nên cho người dùng ăn và xoa lưng họ không?
Rolf

20

Bạn có thể sử dụng Modernizr để phát hiện đơn giản là IE hoặc không phải IE, bằng cách kiểm tra hỗ trợ hoạt hình SVG SMIL .

Nếu bạn đã bao gồm phát hiện tính năng SMIL trong thiết lập Modernizr của mình, bạn có thể sử dụng cách tiếp cận CSS đơn giản và nhắm mục tiêu lớp .no-smil mà Modernizr áp dụng cho phần tử html :

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

Ngoài ra, bạn có thể sử dụng Modernizr với một cách tiếp cận JavaScript đơn giản, như sau:

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

Hãy nhớ rằng một ngày nào đó IE / Edge có thể hỗ trợ SMIL , nhưng hiện tại không có kế hoạch làm như vậy.

Để tham khảo, đây là liên kết đến biểu đồ tương thích của SMIL tại caniuse.com .


Câu trả lời hay nhất imo. Thật đơn giản
Batman

2
Trong khi điều này hoạt động, nó hoạt động cho bây giờ. Toàn bộ điểm của tính năng phát hiện và Modernizr là bạn không phải lo lắng về những gì xảy ra vào ngày mai. Nếu Edge cập nhật vào ngày mai với sự hỗ trợ của smil, mã của bạn không còn hoạt động nữa và bạn thậm chí có thể không biết nó.
Jason


1
Điều này trông rất đơn giản, nhưng rõ ràng Edge hiện hỗ trợ SMIL .
Jeremy Carlson

12

Phát hiện các chuyển đổi CSS 3D

Modernizr có thể phát hiện các biến đổi CSS 3D , vâng. Tính xác thực của Modernizr.csstransforms3dsẽ cho bạn biết liệu trình duyệt có hỗ trợ chúng hay không.

Liên kết trên cho phép bạn chọn các thử nghiệm để đưa vào bản dựng Modernizr và tùy chọn bạn đang tìm có sẵn ở đó.


Phát hiện IE cụ thể

Ngoài ra , như user356990 đã trả lời, bạn có thể sử dụng nhận xét có điều kiện nếu chỉ tìm kiếm IE và IE. Thay vì tạo một biến toàn cục, bạn có thể sử dụng <html>thủ thuật nhận xét có điều kiện của HTML5 Boilerplate để gán một lớp:

<!--[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]-->

Nếu bạn đã khởi tạo jQuery, bạn chỉ cần kiểm tra với $('html').hasClass('lt-ie9'). Nếu bạn cần kiểm tra phiên bản IE nào bạn đang sử dụng để có thể tải có điều kiện jQuery 1.x hoặc 2.x, bạn có thể làm như sau:

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;
}());

Các nhận xét có điều kiện của NB IE chỉ được hỗ trợ lên đến IE9. Từ IE10 trở đi, Microsoft khuyến khích sử dụng tính năng phát hiện hơn là phát hiện trình duyệt.


Cho dù bạn chọn phương pháp nào, thì bạn sẽ thử nghiệm với

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

Tất nhiên, đừng hiểu theo ||nghĩa đen.


Cá nhân tôi luôn cố gắng phát hiện dựa trên tính năng hơn là phát hiện trình duyệt
Chris

@Chris Tốt cho bạn, giống nhau ở đây? Tôi ... không nghĩ rằng bạn thực sự đọc câu trả lời của tôi.
iono

Yours là câu trả lời đầu tiên mà thực sự cho thấy sử dụng tính năng phát hiện các quá figured nó có thể giúp đỡ người khác nếu họ đọc những nhận xét
Chris

@Chris ơi, xin lỗi. Tôi nghĩ bạn đang lên án tôi vì đã đưa vào bài kiểm tra IE.
iono

9

Nếu bạn đang tìm kiếm một phiên bản JS (sử dụng kết hợp phát hiện tính năng và đánh giá UA) cho những gì bảng soạn sẵn html5 được sử dụng để làm:

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

3

Vâng, sau khi nghiên cứu thêm về chủ đề này, tôi đã kết thúc sử dụng giải pháp sau để nhắm mục tiêu IE 10+. Vì IE10 & 11 là trình duyệt duy nhất hỗ trợ truy vấn phương tiện có độ tương phản cao -ms, đó là một lựa chọn tốt mà không có bất kỳ JS nào:

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

Hoạt động hoàn hảo.


2

Thủ thuật CSS có một giải pháp tốt để nhắm mục tiêu IE 11:

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

.NET và Trident / 7.0 là duy nhất cho IE nên có thể được sử dụng để phát hiện phiên bản IE 11.

Sau đó, mã này thêm chuỗi Tác nhân Người dùng vào thẻ html với thuộc tính 'data-useragent', vì vậy IE 11 có thể được nhắm mục tiêu cụ thể ...


1

Tôi cần phát hiện IE so với hầu hết mọi thứ khác và tôi không muốn phụ thuộc vào chuỗi UA. Tôi thấy rằng việc sử dụng es6numbervới Modernizr đã làm chính xác những gì tôi muốn. Tôi không quan tâm nhiều đến sự thay đổi này vì tôi không mong đợi IE sẽ hỗ trợ ES6 Number. Vì vậy, bây giờ tôi đã biết sự khác biệt giữa bất kỳ phiên bản nào của IE với Edge / Chrome / Firefox / Opera / Safari.

Thông tin chi tiết tại đây: http://caniuse.com/#feat=es6-number

Lưu ý rằng tôi không thực sự lo lắng về âm tính giả của Opera Mini. Bạn có thể là.


0

Bạn có thể sử dụng < !-- [if IE] > hack để đặt một biến js toàn cục, sau đó sẽ được kiểm tra trong mã js bình thường của bạn. Một chút xấu xí nhưng đã làm việc tốt cho tôi.


23
Nhận xét có điều kiện không được hỗ trợ nhiều hơn trong trình khám phá internet> = 10.
rudimenter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.