วิธีที่ถูกต้องในการใช้ Modernizr เพื่อตรวจจับ IE?


84

ฉันต้องการใช้ไลบรารี Modernizr JS เพื่อตรวจหาคุณสมบัติบางอย่างของเบราว์เซอร์เพื่อกำหนดเนื้อหาที่จะแสดงหรือไม่แสดง

ฉันมีแอปชื่อPano2VRซึ่งแสดงผลทั้ง HTML5 และ SWF ฉันต้องการ HTML5 สำหรับผู้ใช้อุปกรณ์ iOS

อย่างไรก็ตาม IE ไม่แสดงผลลัพธ์ "HTML5" นี้เลย ดูเหมือนว่าผลลัพธ์ของพวกเขาใช้การแปลง CSS3 3D และ WebGL ซึ่งเห็นได้ชัดว่าอย่างน้อยหนึ่งรายการไม่รองรับใน IE9

ดังนั้นสำหรับผู้ใช้เหล่านั้นฉันจำเป็นต้องแสดงเวอร์ชัน Flash ฉันวางแผนที่จะใช้ IFRAME และส่ง SRC ผ่านสคริปต์ Modernizr หรือเอกสารเขียนโค้ด IFRAME ที่ถูกต้องขึ้นอยู่กับเบราว์เซอร์

ทั้งหมดนี้นำไปสู่ฉันจะใช้ Modernizr เพื่อตรวจหา IE หรือไม่ IE ได้อย่างไร หรือตรวจหาการแปลง CSS 3d?

หรือมีวิธีอื่นในการทำเช่นนี้?

คำตอบ:


1

ฉันเห็นด้วยว่าเราควรทดสอบความสามารถ แต่ยากที่จะหาคำตอบง่ายๆว่า "" เบราว์เซอร์สมัยใหม่ "รองรับความสามารถใดบ้าง แต่ไม่ใช่" เบราว์เซอร์รุ่นเก่า "

ดังนั้นฉันจึงเปิดเบราว์เซอร์จำนวนมากและตรวจสอบ Modernizer โดยตรง ฉันเพิ่มความสามารถบางอย่างที่ฉันต้องการอย่างแน่นอนจากนั้นฉันก็เพิ่ม "inputtypes.color" เพราะดูเหมือนว่าจะครอบคลุมเบราว์เซอร์หลัก ๆ ทั้งหมดที่ฉันสนใจ: Chrome, Firefox, Opera, Edge ... และไม่ใช่ IE11 ตอนนี้ฉันสามารถแนะนำผู้ใช้ได้อย่างนุ่มนวลว่าจะดีกว่าด้วย Chrome / Opera / Firefox / Edge

นี่คือสิ่งที่ฉันใช้ - คุณสามารถแก้ไขรายการสิ่งที่จะทดสอบสำหรับกรณีเฉพาะของคุณได้ ส่งกลับเท็จหากความสามารถใด ๆ หายไป

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

และนี่คือเมธอด GetProperty ที่จำเป็นสำหรับ "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 ตรวจไม่พบเบราว์เซอร์ดังกล่าวตรวจพบว่ามีคุณลักษณะและความสามารถใดบ้างและนี่คือสิ่งที่พยายามทำ

คุณสามารถลองใช้สคริปต์การตรวจจับง่ายๆเช่นนี้แล้วใช้เพื่อเลือก ฉันได้รวม Version Detection ไว้ด้วยในกรณีที่จำเป็น หากคุณต้องการตรวจสอบเวอร์ชันใด ๆ ของ IE คุณสามารถค้นหา navigator.userAgent ที่มีค่าเป็น "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>");

จากนั้นคุณสามารถตรวจสอบ:

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

9
เป็นสมมติฐานทั่วไปที่ว่าหากมีคนแก้ไขสตริง UA ของพวกเขาพวกเขาจะรู้ว่ากำลังทำอะไรอยู่และสามารถจัดการกับผลที่ตามมาได้ ในความเป็นจริงนี่คือสิ่งที่สตริง UA มีอยู่เพื่อประกาศเวอร์ชันเบราว์เซอร์ไปยังเซิร์ฟเวอร์ ถ้าลูกค้าต้องการโกหกเรื่องนั้นก็แค่ชีวิต! แน่นอนว่ามีความเป็นไปได้เล็กน้อยที่สตริงจะถูกเปลี่ยนโดยไม่ได้รับความยินยอมจากผู้ใช้ แต่ในทางปฏิบัตินั่นไม่ใช่เรื่องจริง - และเดี๋ยวก่อนเราควรให้อาหารผู้ใช้และถูหลังด้วยหรือไม่?
Rolf

20

คุณสามารถใช้Modernizrเพื่อตรวจหา IE หรือไม่ IE โดยตรวจสอบการรองรับภาพเคลื่อนไหวSVG SMIL

หากคุณรวมการตรวจจับคุณสมบัติSMILไว้ในการตั้งค่า Modernizr ของคุณคุณสามารถใช้วิธีการ CSS แบบง่ายๆและกำหนดเป้าหมายคลาส. no-smilที่ Modernizr ใช้กับองค์ประกอบhtml :

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

หรือคุณสามารถใช้ Modernizr ด้วยวิธี JavaScript ง่ายๆเช่น:

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

โปรดทราบว่าสักวันหนึ่ง IE / Edge อาจรองรับSMILแต่ขณะนี้ยังไม่มีแผนที่จะทำเช่นนั้น

สำหรับการอ้างอิงนี่คือการเชื่อมโยงไปSMILเข้ากันได้แผนภูมิที่caniuse.com


คำตอบที่ดีที่สุด imo ง่ายมาก
Batman

2
แม้ว่าจะได้ผล แต่ก็ใช้ได้ในตอนนี้ จุดรวมของการตรวจจับคุณสมบัติและ Modernizr คือคุณไม่ต้องกังวลว่าจะเกิดอะไรขึ้นในวันพรุ่งนี้ หาก Edge อัปเดตพรุ่งนี้ด้วยการสนับสนุน smil รหัสของคุณจะไม่ทำงานอีกต่อไปและคุณอาจไม่รู้ด้วยซ้ำ
Jason

มันยังคงอยู่ที่ว่ามีแผนสำหรับการสนับสนุน SMIL ในขอบไม่มี
jacefarm

1
สิ่งนี้ดูเรียบง่าย แต่เห็นได้ชัดว่าEdge รองรับ SMILแล้ว
Jeremy Carlson

12

การตรวจจับการแปลง CSS 3D

Modernizr สามารถตรวจจับการแปลง CSS 3Dได้ ความจริงของModernizr.csstransforms3dจะบอกคุณว่าเบราว์เซอร์รองรับหรือไม่

ลิงก์ด้านบนช่วยให้คุณสามารถเลือกการทดสอบที่จะรวมไว้ในโครงสร้าง Modernizr และตัวเลือกที่คุณต้องการจะมีอยู่ที่นั่น


ตรวจจับ IE โดยเฉพาะ

หรือตามที่ user356990 ตอบคุณสามารถใช้ความคิดเห็นแบบมีเงื่อนไขได้หากคุณค้นหา IE และ IE เพียงอย่างเดียว แทนที่จะสร้างตัวแปรส่วนกลางคุณสามารถใช้<html>เคล็ดลับความคิดเห็นที่มีเงื่อนไขของ HTML5 Boilerplate เพื่อกำหนดคลาส:

<!--[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')ไฟล์. หากคุณต้องการตรวจสอบว่าคุณอยู่ในเวอร์ชัน IE ใดเพื่อให้คุณสามารถโหลด jQuery 1.x หรือ 2.x ได้ตามเงื่อนไขคุณสามารถดำเนินการดังนี้:

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
} 

อย่าเอา||ตามตัวอักษรแน่นอน


โดยส่วนตัวแล้วฉันมักจะลองทำการตรวจจับตามฟีเจอร์มากกว่าการตรวจจับเบราว์เซอร์
คริส

@ คริสดีสำหรับคุณที่นี่? ฉัน ... ไม่คิดว่าคุณจะอ่านคำตอบของฉันจริงๆ
iono

คุณเป็นคำตอบแรกที่แนะนำให้ใช้คุณลักษณะการตรวจจับดังนั้นจึงคิดว่าอาจช่วยคนอื่นได้หากพวกเขาอ่านความคิดเห็น
คริส

@ คริสโอ้ขอโทษ ฉันคิดว่าคุณประณามฉันที่รวมการทดสอบ IE
iono

9

หากคุณกำลังมองหาเวอร์ชัน JS (โดยใช้การตรวจจับคุณลักษณะและการดมกลิ่น UA ร่วมกัน) ของเอกสารสำเร็จรูป html5 ที่ใช้ทำ:

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 ได้

จากนั้นโค้ดจะเพิ่มสตริง User Agent ลงในแท็ก html ด้วยแอตทริบิวต์ 'data-useragent' ดังนั้น IE 11 จึงสามารถกำหนดเป้าหมายได้โดยเฉพาะ ...


1

ฉันต้องการตรวจจับ IE เทียบกับสิ่งอื่น ๆ ส่วนใหญ่และฉันไม่ต้องการขึ้นอยู่กับสตริง UA ฉันพบว่าการใช้es6numberกับ Modernizr ทำได้ตามที่ฉันต้องการ ฉันไม่ได้กังวลกับการเปลี่ยนแปลงนี้มากนักเพราะฉันไม่คาดหวังว่า IE จะรองรับ ES6 Number ตอนนี้ฉันรู้ความแตกต่างระหว่าง IE กับ Edge / Chrome / Firefox / Opera / Safari ทุกเวอร์ชัน

รายละเอียดเพิ่มเติมที่นี่: http://caniuse.com/#feat=es6-number

โปรดทราบว่าฉันไม่ได้กังวลเกี่ยวกับเนกาทีฟเท็จของ Opera Mini คุณอาจจะ


0

คุณสามารถใช้< !-- [if IE] > แฮ็คเพื่อตั้งค่าตัวแปร js ส่วนกลางซึ่งจะได้รับการทดสอบในโค้ด js ปกติของคุณ น่าเกลียดนิดหน่อย แต่ได้ผลดีสำหรับฉัน


23
ความคิดเห็นแบบมีเงื่อนไขไม่ได้รับการสนับสนุนใน internet explorer> = 10
rudimenter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.