JavaScript IE/Edge Compatibility

Writing JavaScript that works across all browsers

🌐 Browser Compatibility

Learn how to write JavaScript that works in Internet Explorer, Edge, and all modern browsers. Understanding compatibility ensures your code reaches all users!


// This works in all browsers
function greetUser(name) {
    return "Hello, " + name + "!";
}

// This might not work in older browsers
const greetUserModern = (name) => `Hello, ${name}!`;
                                    

Browser Support Overview

🔴

Internet Explorer

Legacy browser (discontinued)

IE 11 (2013) Limited ES6
🔵

Edge Legacy

Old Edge (EdgeHTML)

Edge 12-18 Better ES6
🟢

Modern Edge

Chromium-based Edge

Edge 79+ Full ES6+

Modern Browsers

Chrome, Firefox, Safari

Latest Features ES2020+

🔹 IE11 Compatible JavaScript

Code that works in Internet Explorer 11 and all modern browsers:

// ✅ Works in IE11 and all browsers
function processUsers(users) {
    var activeUsers = [];
    
    // Use for loop instead of forEach for IE11
    for (var i = 0; i < users.length; i++) {
        if (users[i].active) {
            activeUsers.push(users[i]);
        }
    }
    
    return activeUsers;
}

// ✅ IE11 compatible object creation
function createUser(name, age) {
    return {
        name: name,
        age: age,
        greet: function() {
            return "Hello, I'm " + this.name;
        }
    };
}

// ✅ IE11 compatible event handling
function addClickHandler(element, callback) {
    if (element.addEventListener) {
        // Modern browsers
        element.addEventListener('click', callback);
    } else if (element.attachEvent) {
        // IE8 and below (if needed)
        element.attachEvent('onclick', callback);
    }
}

// ✅ IE11 compatible AJAX
function makeRequest(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                callback(null, JSON.parse(xhr.responseText));
            } else {
                callback(new Error('Request failed'));
            }
        }
    };
    
    xhr.send();
}

// Example usage
var users = [
    { name: "Alice", active: true },
    { name: "Bob", active: false },
    { name: "Charlie", active: true }
];

var active = processUsers(users);
console.log("Active users:", active.length);

Output:

Active users: 2

✅ Works in IE11, Edge, Chrome, Firefox, Safari

🔹 Modern vs IE11 Compatible Code

See the differences between modern JavaScript and IE11-compatible versions:

// ❌ Modern JavaScript (doesn't work in IE11)
const modernCode = () => {
    const users = [
        { name: "Alice", age: 25 },
        { name: "Bob", age: 30 }
    ];
    
    // Arrow functions, template literals, const/let
    const names = users.map(user => `${user.name} (${user.age})`);
    
    // Destructuring
    const [first, second] = names;
    
    return { first, second };
};

// ✅ IE11 Compatible version
function ie11CompatibleCode() {
    var users = [
        { name: "Alice", age: 25 },
        { name: "Bob", age: 30 }
    ];
    
    // Regular function, string concatenation, var
    var names = [];
    for (var i = 0; i < users.length; i++) {
        names.push(users[i].name + " (" + users[i].age + ")");
    }
    
    // Manual assignment instead of destructuring
    var first = names[0];
    var second = names[1];
    
    return { 
        first: first, 
        second: second 
    };
}

// ❌ Modern Promise (IE11 needs polyfill)
function modernAsync() {
    return fetch('/api/data')
        .then(response => response.json())
        .then(data => data.users);
}

// ✅ IE11 Compatible AJAX
function ie11Async(callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', '/api/data', true);
    
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            var data = JSON.parse(xhr.responseText);
            callback(data.users);
        }
    };
    
    xhr.send();
}

// Test both versions
console.log("IE11 compatible result:", ie11CompatibleCode());

// Modern browsers can use either
if (typeof fetch !== 'undefined') {
    console.log("Modern browser detected");
} else {
    console.log("Legacy browser - using compatible code");
}

Output:

IE11 compatible result: {first: "Alice (25)", second: "Bob (30)"}

Modern browser detected

🔹 Feature Detection

Check if features are available before using them:

// Feature detection for safe coding
function safeJavaScript() {
    // Check for forEach support
    if (Array.prototype.forEach) {
        console.log("forEach is supported");
        [1, 2, 3].forEach(function(num) {
            console.log("Number:", num);
        });
    } else {
        console.log("forEach not supported, using for loop");
        var numbers = [1, 2, 3];
        for (var i = 0; i < numbers.length; i++) {
            console.log("Number:", numbers[i]);
        }
    }
    
    // Check for JSON support
    if (typeof JSON !== 'undefined') {
        var data = JSON.stringify({ message: "JSON works!" });
        console.log("JSON data:", data);
    } else {
        console.log("JSON not supported");
    }
    
    // Check for localStorage
    if (typeof Storage !== 'undefined') {
        localStorage.setItem('test', 'localStorage works!');
        console.log("Stored:", localStorage.getItem('test'));
    } else {
        console.log("localStorage not supported");
    }
    
    // Check for addEventListener
    var button = document.createElement('button');
    if (button.addEventListener) {
        console.log("Modern event handling available");
    } else if (button.attachEvent) {
        console.log("Legacy event handling (IE8 and below)");
    }
}

// Polyfill example for older browsers
if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(callback, thisArg) {
        for (var i = 0; i < this.length; i++) {
            callback.call(thisArg, this[i], i, this);
        }
    };
}

// Browser detection (use sparingly)
function getBrowserInfo() {
    var userAgent = navigator.userAgent;
    var browserInfo = {
        isIE: userAgent.indexOf('MSIE') !== -1 || userAgent.indexOf('Trident') !== -1,
        isEdge: userAgent.indexOf('Edge') !== -1,
        isChrome: userAgent.indexOf('Chrome') !== -1,
        isFirefox: userAgent.indexOf('Firefox') !== -1,
        isSafari: userAgent.indexOf('Safari') !== -1 && userAgent.indexOf('Chrome') === -1
    };
    
    console.log("Browser info:", browserInfo);
    return browserInfo;
}

// Run the tests
safeJavaScript();
getBrowserInfo();

Output:

forEach is supported

Number: 1

Number: 2

Number: 3

JSON data: {"message":"JSON works!"}

Stored: localStorage works!

Modern event handling available

🔹 Cross-Browser Best Practices

Guidelines for maximum browser compatibility:

✅ Do This (Compatible):

  • Use var instead of let/const for IE11
  • Regular functions instead of arrow functions
  • String concatenation instead of template literals
  • for loops instead of forEach/map for IE11
  • Feature detection before using new APIs
  • Polyfills for missing features

❌ Avoid This (Modern Only):

  • Arrow functions: () => {}
  • Template literals: `Hello ${name}`
  • Destructuring: const {name} = user
  • Spread operator: ...array
  • Promises without polyfill
  • fetch() without polyfill
// Universal JavaScript pattern
(function() {
    'use strict';
    
    // Feature detection
    var hasLocalStorage = typeof Storage !== 'undefined';
    var hasJSON = typeof JSON !== 'undefined';
    
    // Main application code
    function initApp() {
        console.log("App initialized");
        
        // Safe data storage
        if (hasLocalStorage) {
            localStorage.setItem('appVersion', '1.0');
        }
        
        // Safe JSON handling
        if (hasJSON) {
            var config = JSON.stringify({ theme: 'light' });
            console.log("Config saved:", config);
        }
    }
    
    // Wait for DOM to be ready (works in all browsers)
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initApp);
    } else {
        initApp();
    }
})();

🧠 Test Your Knowledge

Which JavaScript feature is NOT supported in IE11?