Статьи

Как jQuery 1.9.1 преодолевает JavaScript в Internet Explorer 6/7/8

Как jQuery 1.9.1 поддерживает старый Internet Explorer? Этот пост содержит коллекцию фрагментов кода непосредственно из библиотеки jQuery. Надеемся, что, прочитав код, вы узнаете больше о ванильном JavaScript и о том, как jQuery 1.9.1 преодолел несовместимость браузеров JavaScript с Internet Explorer 6,7,8,9.

Я отфильтровал через grep для «IE / ie6 / ie7 / ie8 / ie9», чтобы извлечь связанные с IE сегменты кода для анализа. Затем сгруппированные фрагменты в некоторые общие области исправлений IE. Прочитайте и посмотрите, какие огромные усилия были предприняты в jQuery для поддержки Internet Explorer . Большое спасибо команде jQuery.

Если вам интересно, как перейти на jQuery 2.0 для поддержки IE.

IE6 / 7/8/9 Исправления в jQuery 1.9.1

Фрагменты кода были сгруппированы в следующие разделы.

IE утечки памяти исправления

Line 1538: // Null elements to avoid leaks in IE container = div = tds = marginDiv = null; }); // Null elements to avoid leaks in IE all = select = fragment = opt = a = input = null; Line 2753: // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events eventHandle.elem = elem; Line 2823: // Nullify elem to prevent memory leaks in IE elem = null; Line 3322: // #8545, #7054, preventing memory leaks for custom events in IE6-8 // detachEvent needed property on element, by name of that event, to properly expose it to GC if ( typeof elem[ name ] === core_strundefined ) { elem[ name ] = null; } elem.detachEvent( name, handle ); Line 8316: // Handle memory leak in IE script.onload = script.onreadystatechange = null; Line 3874: /** * Support testing using an element * @param {Function} fn Passed the created div and expects a boolean result */ function assert( fn ) { var div = document.createElement("div"); try { return fn( div ); } catch (e) { return false; } finally { // release memory in IE div = null; } } 

IE исправления событий

 Line 97: // The ready event handler completed = function( event ) { // readyState === "complete" is good enough for us to call the dom ready in oldIE if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { detach(); jQuery.ready(); } }, Line 905: // If IE event model is used } else { // Ensure firing before onload, maybe late but safe also for iframes document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work window.attachEvent( "onload", completed ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } // detach all dom ready events detach(); // and execute any waiting functions jQuery.ready(); } })(); } } Line 1430: // Support: IE<9 // Opera does not clone events (and typeof div.attachEvent === undefined). // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() if ( div.attachEvent ) { div.attachEvent( "onclick", function() { support.noCloneEvent = false; }); div.cloneNode( true ).click(); } // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php for ( i in { submit: true, change: true, focusin: true }) { div.setAttribute( eventName = "on" + i, "t" ); support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; } Line 3003: // Call a native DOM method on the target with the same name name as the event. // Can't use an .isFunction() check here because IE6/7 fails that test. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; try { elem[ type ](); } catch ( e ) { // IE<9 dies on focus/blur to hidden element (#1486,#12518) // only reproducible on winXP IE8 native, not IE9 in IE8 mode } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } Line 3168: // Support: IE<9 // Fix target property (#1925) if ( !event.target ) { event.target = originalEvent.srcElement || document; } Line 3180: // Support: IE<9 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) event.metaKey = !!event.metaKey; Line 3253: trigger: function() { if ( this !== document.activeElement && this.focus ) { try { this.focus(); return false; } catch ( e ) { // Support: IE<9 // If we error on focus to hidden element (#1486, #12518), // let .trigger() run the handlers } } }, Line 3384: // Support: IE // Otherwise set the returnValue property of the original event to false } else { e.returnValue = false; } Line 3402: // Support: IE // Set the cancelBubble property of the original event to true e.cancelBubble = true; Line 3439: // IE submit delegation if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Lazy-add a submit handler when a descendant form may potentially be submitted jQuery.event.add( this, "click._submit keypress._submit", function( e ) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; if ( form && !jQuery._data( form, "submitBubbles" ) ) { jQuery.event.add( form, "submit._submit", function( event ) { event._submit_bubble = true; }); jQuery._data( form, "submitBubbles", true ); } }); // return undefined since we don't need an event listener }, postDispatch: function( event ) { // If form was submitted by the user, bubble the event up the tree if ( event._submit_bubble ) { delete event._submit_bubble; if ( this.parentNode && !event.isTrigger ) { jQuery.event.simulate( "submit", this.parentNode, event, true ); } } }, teardown: function() { // Only need this for delegated form submit events if ( jQuery.nodeName( this, "form" ) ) { return false; } // Remove delegated handlers; cleanData eventually reaps submit handlers attached above jQuery.event.remove( this, "._submit" ); } }; } Line 3486: // IE change delegation and checkbox/radio fix if ( !jQuery.support.changeBubbles ) { jQuery.event.special.change = { setup: function() { if ( rformElems.test( this.nodeName ) ) { // IE doesn't fire change on a check/radio until blur; trigger it on click // after a propertychange. Eat the blur-change in special.change.handle. // This still fires onchange a second time for check/radio after blur. if ( this.type === "checkbox" || this.type === "radio" ) { jQuery.event.add( this, "propertychange._change", function( event ) { if ( event.originalEvent.propertyName === "checked" ) { this._just_changed = true; } }); jQuery.event.add( this, "click._change", function( event ) { if ( this._just_changed && !event.isTrigger ) { this._just_changed = false; } // Allow triggered, simulated change events (#11500) jQuery.event.simulate( "change", this, event, true ); }); } return false; } // Delegated event; lazy-add a change handler on descendant inputs jQuery.event.add( this, "beforeactivate._change", function( e ) { var elem = e.target; if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); jQuery._data( elem, "changeBubbles", true ); } }); }, handle: function( event ) { var elem = event.target; // Swallow native change events from checkbox/radio, we already triggered them above if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { return event.handleObj.handler.apply( this, arguments ); } }, teardown: function() { jQuery.event.remove( this, "._change" ); return !rformElems.test( this.nodeName ); } }; } 

IE Селектор Исправления

 Line 177: if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } // Otherwise, we inject the element directly into the jQuery object this.length = 1; this[0] = elem; } Line 3922: // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } Line 4195: // IE8 - Some boolean attributes are not treated correctly if ( !div.querySelectorAll("[selected]").length ) { rbuggyQSA.push( "\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); } Line 4202: // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } Line 4218: // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":enabled").length ) { rbuggyQSA.push( ":enabled", ":disabled" ); } Line 4236: // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( div, "div" ); Line 4377: // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } Line 4449: function siblingCheck( a, b ) { var cur = b && a, diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE ); // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } 

IE CSS Исправления

 Line 1360: // Get the style information from getAttribute // (IE uses .cssText instead) style: /top/.test( a.getAttribute("style") ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, Line 1512: if ( typeof div.style.zoom !== core_strundefined ) { // Support: IE<8 // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout div.innerHTML = ""; div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); // Support: IE6 // Check if elements with layout shrink-wrap their children div.style.display = "block"; div.innerHTML = " 
«; div.firstChild.style.width = "5px"; support.shrinkWrapBlocks = (div.offsetWidth! == 3); if (support.inlineBlockNeedsLayout) { // Предотвращаем влияние IE 6 на макет для позиционируемых элементов # 11048 // Запрещаем IE сжимать тело в режиме IE 7 # 12869 // Поддержка: IE <8 body.style.zoom = 1; } } Строка 2637: if (! jQuery.support.style) { jQuery.attrHooks.style = { get: function (elem) { // Возвращаем неопределенное значение в случае пустой строки // Примечание: IE прописывает имена свойств css, но если бы мы были .toLowerCase () // .cssText, который уничтожил бы чувствительность к регистру в URL, как в "background" вернуть elem.style.cssText || не определен; }, set: function (elem, value) { return (elem.style.cssText = value + ""); } }; } Строка 6933: // getPropertyValue требуется только для .css ('filter') в IE9, см. # 12537 ret = вычисляется? computed.getPropertyValue (name) || вычисляется [имя]: не определено, Строка 8917: // Записать все 3 атрибута переполнения, потому что IE не // изменить атрибут переполнения при переполнении и // overflowY установлены на одно и то же значение opts.overflow = [style.overflow, style.overflowX, style.overflowY]; Строка 9087: // Удалить в 2.0 - это поддерживает основанный на панике подход IE8 // для установки вещей на отключенные узлы Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function (tween) { if (tween.elem.nodeType && tween.elem.parentNode) { tween.elem [tween.prop] = tween.now; } } }; Строка 9555: // Либо прокручиваем [Ширина / Высота], либо смещаем [Ширина / Высота], либо клиент [Ширина / Высота], в зависимости от того, что больше // к сожалению, это приводит к ошибке # 3838 только в IE6 / 8, но в настоящее время нет хорошего, маленького способа ее исправить. вернуть Math.max ( elem.body ["scroll" + имя], doc ["scroll" + имя], elem.body ["offset" + name], doc ["offset" + name], doc ["клиент" + имя] );

IE Непрозрачность Исправления

 Line 1360: // Make sure that element opacity exists // (IE uses filter instead) // Use a regex to work around a WebKit issue. See #5145 opacity: /^0.5/.test( a.style.opacity ), Line 7178: // IE uses filters for opacity return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : computed ? "1" : ""; Line 7190: // IE has trouble with opacity if it does not have layout // Force it by setting the zoom level style.zoom = 1; 

IE атрибуты / свойства исправления

 Line 1332: // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", Line 2060: removeProp: function( name ) { name = jQuery.propFix[ name ] || name; return this.each(function() { // try/catch handles cases where IE balks (such as removing a property on window) try { this[ name ] = undefined; delete this[ name ]; } catch( e ) {} }); }, Line 2289: // oldIE doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { Line 2367: // In IE9+, Flash objects don't have .getAttribute (#12945) // Support: IE9+ if ( typeof elem.getAttribute !== core_strundefined ) { ret = elem.getAttribute( name ); } Line 2392: // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 if ( !getSetAttribute && ruseDefault.test( name ) ) { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ propName ] = false; } else { elem[ propName ] = false; } Line 2524: } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { // IE<8 needs the *property* name elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); // Use defaultChecked and defaultSelected for oldIE } else { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; } Line 2537: // fix oldIE value attroperty if ( !getSetInput || !getSetAttribute ) { jQuery.attrHooks.value = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return jQuery.nodeName( elem, "input" ) ? // Ignore the value *property* by using defaultValue elem.defaultValue : ret && ret.specified ? ret.value : undefined; }, set: function( elem, value, name ) { if ( jQuery.nodeName( elem, "input" ) ) { // Does not return so that setAttribute is also used elem.defaultValue = value; } else { // Use nodeHook if defined (#1954); otherwise setAttribute is fine return nodeHook && nodeHook.set( elem, value, name ); } } }; } Line 2561: // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !getSetAttribute ) { // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? ret.value : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { elem.setAttributeNode( (ret = elem.ownerDocument.createAttribute( name )) ); } ret.value = value += ""; // Break association with cloned elements by also using setAttribute (#9646) return name === "value" || value === elem.getAttribute( name ) ? value : undefined; } }; // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, set: function( elem, value, name ) { nodeHook.set( elem, value === "" ? false : value, name ); } }; // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each([ "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { set: function( elem, value ) { if ( value === "" ) { elem.setAttribute( name, "auto" ); return value; } } }); }); } Line 2615: // Some attributes require a special call on IE // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !jQuery.support.hrefNormalized ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret == null ? undefined : ret; } }); }); // href/src property should get the full normalized URL (#10299/#12915) jQuery.each([ "href", "src" ], function( i, name ) { jQuery.propHooks[ name ] = { get: function( elem ) { return elem.getAttribute( name, 4 ); } }; }); } Line 4081: // IE6/7 return modified attributes Expr.attrHandle = assert(function( div ) { div.innerHTML = "  "; return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && div.firstChild.getAttribute("href") === "#"; }) ? {} : { "href": function( elem ) { return elem.getAttribute( "href", 2 ); }, "type": function( elem ) { return elem.getAttribute("type"); } }; Line 4950: "text": function( elem ) { var attr; // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) // use getAttribute instead to test this case return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); }, Line 6597: // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases if ( deleteExpando ) { delete elem[ internalKey ]; } else if ( typeof elem.removeAttribute !== core_strundefined ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } Line 7200: // Setting style.filter to null, "" & " " still leave "filter:" in the cssText // if "filter:" is present at all, clearType is disabled, we want to avoid this // style.removeAttribute is IE Only, but so apparently is this code path... style.removeAttribute( "filter" ); не Line 1332: // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", Line 2060: removeProp: function( name ) { name = jQuery.propFix[ name ] || name; return this.each(function() { // try/catch handles cases where IE balks (such as removing a property on window) try { this[ name ] = undefined; delete this[ name ]; } catch( e ) {} }); }, Line 2289: // oldIE doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { Line 2367: // In IE9+, Flash objects don't have .getAttribute (#12945) // Support: IE9+ if ( typeof elem.getAttribute !== core_strundefined ) { ret = elem.getAttribute( name ); } Line 2392: // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 if ( !getSetAttribute && ruseDefault.test( name ) ) { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ propName ] = false; } else { elem[ propName ] = false; } Line 2524: } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { // IE<8 needs the *property* name elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); // Use defaultChecked and defaultSelected for oldIE } else { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; } Line 2537: // fix oldIE value attroperty if ( !getSetInput || !getSetAttribute ) { jQuery.attrHooks.value = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return jQuery.nodeName( elem, "input" ) ? // Ignore the value *property* by using defaultValue elem.defaultValue : ret && ret.specified ? ret.value : undefined; }, set: function( elem, value, name ) { if ( jQuery.nodeName( elem, "input" ) ) { // Does not return so that setAttribute is also used elem.defaultValue = value; } else { // Use nodeHook if defined (#1954); otherwise setAttribute is fine return nodeHook && nodeHook.set( elem, value, name ); } } }; } Line 2561: // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !getSetAttribute ) { // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? ret.value : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { elem.setAttributeNode( (ret = elem.ownerDocument.createAttribute( name )) ); } ret.value = value += ""; // Break association with cloned elements by also using setAttribute (#9646) return name === "value" || value === elem.getAttribute( name ) ? value : undefined; } }; // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, set: function( elem, value, name ) { nodeHook.set( elem, value === "" ? false : value, name ); } }; // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each([ "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { set: function( elem, value ) { if ( value === "" ) { elem.setAttribute( name, "auto" ); return value; } } }); }); } Line 2615: // Some attributes require a special call on IE // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !jQuery.support.hrefNormalized ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret == null ? undefined : ret; } }); }); // href/src property should get the full normalized URL (#10299/#12915) jQuery.each([ "href", "src" ], function( i, name ) { jQuery.propHooks[ name ] = { get: function( elem ) { return elem.getAttribute( name, 4 ); } }; }); } Line 4081: // IE6/7 return modified attributes Expr.attrHandle = assert(function( div ) { div.innerHTML = "  "; return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && div.firstChild.getAttribute("href") === "#"; }) ? {} : { "href": function( elem ) { return elem.getAttribute( "href", 2 ); }, "type": function( elem ) { return elem.getAttribute("type"); } }; Line 4950: "text": function( elem ) { var attr; // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) // use getAttribute instead to test this case return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); }, Line 6597: // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases if ( deleteExpando ) { delete elem[ internalKey ]; } else if ( typeof elem.removeAttribute !== core_strundefined ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } Line 7200: // Setting style.filter to null, "" & " " still leave "filter:" in the cssText // if "filter:" is present at all, clearType is disabled, we want to avoid this // style.removeAttribute is IE Only, but so apparently is this code path... style.removeAttribute( "filter" ); не Line 1332: // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) getSetAttribute: div.className !== "t", Line 2060: removeProp: function( name ) { name = jQuery.propFix[ name ] || name; return this.each(function() { // try/catch handles cases where IE balks (such as removing a property on window) try { this[ name ] = undefined; delete this[ name ]; } catch( e ) {} }); }, Line 2289: // oldIE doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { Line 2367: // In IE9+, Flash objects don't have .getAttribute (#12945) // Support: IE9+ if ( typeof elem.getAttribute !== core_strundefined ) { ret = elem.getAttribute( name ); } Line 2392: // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8 if ( !getSetAttribute && ruseDefault.test( name ) ) { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ propName ] = false; } else { elem[ propName ] = false; } Line 2524: } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { // IE<8 needs the *property* name elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); // Use defaultChecked and defaultSelected for oldIE } else { elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; } Line 2537: // fix oldIE value attroperty if ( !getSetInput || !getSetAttribute ) { jQuery.attrHooks.value = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return jQuery.nodeName( elem, "input" ) ? // Ignore the value *property* by using defaultValue elem.defaultValue : ret && ret.specified ? ret.value : undefined; }, set: function( elem, value, name ) { if ( jQuery.nodeName( elem, "input" ) ) { // Does not return so that setAttribute is also used elem.defaultValue = value; } else { // Use nodeHook if defined (#1954); otherwise setAttribute is fine return nodeHook && nodeHook.set( elem, value, name ); } } }; } Line 2561: // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !getSetAttribute ) { // Use this for any attribute in IE6/7 // This fixes almost every IE6/7 issue nodeHook = jQuery.valHooks.button = { get: function( elem, name ) { var ret = elem.getAttributeNode( name ); return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ? ret.value : undefined; }, set: function( elem, value, name ) { // Set the existing or create a new attribute node var ret = elem.getAttributeNode( name ); if ( !ret ) { elem.setAttributeNode( (ret = elem.ownerDocument.createAttribute( name )) ); } ret.value = value += ""; // Break association with cloned elements by also using setAttribute (#9646) return name === "value" || value === elem.getAttribute( name ) ? value : undefined; } }; // Set contenteditable to false on removals(#10429) // Setting to empty string throws an error as an invalid value jQuery.attrHooks.contenteditable = { get: nodeHook.get, set: function( elem, value, name ) { nodeHook.set( elem, value === "" ? false : value, name ); } }; // Set width and height to auto instead of 0 on empty string( Bug #8150 ) // This is for removals jQuery.each([ "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { set: function( elem, value ) { if ( value === "" ) { elem.setAttribute( name, "auto" ); return value; } } }); }); } Line 2615: // Some attributes require a special call on IE // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !jQuery.support.hrefNormalized ) { jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { get: function( elem ) { var ret = elem.getAttribute( name, 2 ); return ret == null ? undefined : ret; } }); }); // href/src property should get the full normalized URL (#10299/#12915) jQuery.each([ "href", "src" ], function( i, name ) { jQuery.propHooks[ name ] = { get: function( elem ) { return elem.getAttribute( name, 4 ); } }; }); } Line 4081: // IE6/7 return modified attributes Expr.attrHandle = assert(function( div ) { div.innerHTML = "  "; return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && div.firstChild.getAttribute("href") === "#"; }) ? {} : { "href": function( elem ) { return elem.getAttribute( "href", 2 ); }, "type": function( elem ) { return elem.getAttribute("type"); } }; Line 4950: "text": function( elem ) { var attr; // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) // use getAttribute instead to test this case return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); }, Line 6597: // IE does not allow us to delete expando properties from nodes, // nor does it have a removeAttribute function on Document nodes; // we must handle all of these cases if ( deleteExpando ) { delete elem[ internalKey ]; } else if ( typeof elem.removeAttribute !== core_strundefined ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } Line 7200: // Setting style.filter to null, "" & " " still leave "filter:" in the cssText // if "filter:" is present at all, clearType is disabled, we want to avoid this // style.removeAttribute is IE Only, but so apparently is this code path... style.removeAttribute( "filter" ); 

Типы IE / исправления парсинга

 Line 28: // Support: IE<9 // For `typeof node.method` instead of `node.method !== undefined` core_strundefined = typeof undefined, Line 469: isPlainObject: function( obj ) { // Must be an Object. // Because of IE, we also have to check the presence of the constructor property. // Make sure that DOM nodes and window objects don't pass through, as well if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { return false; } try { // Not own constructor property must be Object if ( obj.constructor && !core_hasOwn.call(obj, "constructor") && !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } } catch ( e ) { // IE8,9 Will throw exceptions on certain host objects #9897 return false; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; for ( key in obj ) {} return key === undefined || core_hasOwn.call( obj, key ); }, Line 568: // Cross-browser xml parsing parseXML: function( data ) { var xml, tmp; if ( !data || typeof data !== "string" ) { return null; } try { if ( window.DOMParser ) { // Standard tmp = new DOMParser(); xml = tmp.parseFromString( data , "text/xml" ); } else { // IE xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = "false"; xml.loadXML( data ); } } catch( e ) { xml = undefined; } if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; }, Line 1560: // We have to handle DOM nodes and JS objects differently because IE6-7 // can't GC object references properly across the DOM-JS boundary isNode = elem.nodeType, Line 2503: detail = typeof prop === "boolean" ? getSetInput && getSetAttribute ? attr != null : // oldIE fabricates an empty string for missing boolean attributes // and conflates checked/selected into attroperties ruseDefault.test( name ) ? elem[ jQuery.camelCase( "default-" + name ) ] : !!attr : // fetch an attribute node for properties not recognized as boolean elem.getAttributeNode( name ); Line 2671: // IE6/7 call enctype encoding if ( !jQuery.support.enctype ) { jQuery.propFix.enctype = "encoding"; } Line 3959: // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { Line 4001: /** * Detect xml * @param {Element|Object} elem An element or a document */ isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; Line 4042: // IE8 returns a string for some attributes even when not present return type !== "boolean" && type !== "string"; Line 6344: // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() core_push.apply( ret, elems.get() ); 

IE клонирование исправления

 Line 6259: function fixCloneNodeIssues( src, dest ) { var nodeName, e, data; // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { return; } nodeName = dest.nodeName.toLowerCase(); // IE6-8 copies events bound via attachEvent when using cloneNode. if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { data = jQuery._data( dest ); for ( e in data.events ) { jQuery.removeEvent( dest, e, data.handle ); } // Event data gets referenced instead of copied if the expando gets copied too dest.removeAttribute( jQuery.expando ); } // IE blanks contents when cloning scripts, and tries to evaluate newly-set text if ( nodeName === "script" && dest.text !== src.text ) { disableScript( dest ).text = src.text; restoreScript( dest ); // IE6-10 improperly clones children of object elements using classid. // IE10 throws NoModificationAllowedError if parent is null, #12132. } else if ( nodeName === "object" ) { if ( dest.parentNode ) { dest.outerHTML = src.outerHTML; } // This path appears unavoidable for IE9. When cloning an object // element in IE9, the outerHTML strategy above is not sufficient. // If the src has innerHTML and the destination does not, // copy the src.innerHTML into the dest.innerHTML. #10324 if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { dest.innerHTML = src.innerHTML; } } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set dest.defaultChecked = dest.checked = src.checked; // IE6-7 get confused and end up setting the value of a cloned // checkbox/radio button to an empty string instead of "on" if ( dest.value !== src.value ) { dest.value = src.value; } // IE6-8 fails to return the selected option to the default selected // state when cloning options } else if ( nodeName === "option" ) { dest.defaultSelected = dest.selected = src.defaultSelected; // IE6-8 fails to set the defaultValue to the correct value when // cloning other types of input fields } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } Line 6389: // IE< =8 does not properly clone detached, unknown element nodes } else { fragmentDiv.innerHTML = elem.outerHTML; fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); } Line 6402: // Fix all IE cloning issues for ( i = 0; (node = srcElements[i]) != null; ++i ) { // Ensure that the destination node is not null; Fixes #9587 if ( destElements[i] ) { fixCloneNodeIssues( node, destElements[i] ); } } [/js] 

Исправления пробелов в IE [JS] Строка 550: // Убедитесь, что начальные / конечные пробелы удалены (IE не может их обработать) data = jQuery.trim (data); Строка 1335: // IE удаляет первые пробелы при использовании .innerHTML leadWhitespace: div.firstChild.nodeType === 3, Строка 6477: // Вручную добавить начальные пробелы, удаленные IE if (! jQuery.support.leadingWhitespace && rleadingWhitespace.test (elem)) { node.push (context.createTextNode (rleadingWhitespace.exec (elem) [0])); } Строка 7419: rheaders = / ^ (. *?): [t] * ([^ rn] *) r? $ / mg, // IE оставляет символ r в EOL

IE Table Fixes

 Line 1340: // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, Line 1469: // Support: IE8 // Check if table cells still have offsetWidth/Height when they are set // to display:none and there are still other visible table cells in a // table row; if so, offsetWidth/Height are not reliable for use when // determining if an element has been hidden directly using // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). div.innerHTML = " 
T

«;
tds = div.getElementsByTagName («td»);
tds [0] .style.cssText = «padding: 0; margin: 0; border: 0; display: none»;
isSupported = (tds [0] .offsetHeight === 0);

tds [0] .style.display = «»;
tds [1] .style.display = «нет»;

// Поддержка: IE8
// Проверяем, все ли пустые ячейки таблицы имеют offsetWidth / Height
support.reliableHiddenOffsets = isSupported && (tds [0] .offsetHeight === 0);


Строка 6482:

// Удалить IE, вставленный автоматически из фрагментов таблицы
if (! jQuery.support.tbody) {

// Строка была * может * иметь поддельные elem = tag === «таблица» &&! rtbody.test (elem)? tmp.firstChild: // Строка была голой или обернуть [1] === «





«&&! rtbody.test (elem)? тпм: 0; j = elem && elem.childNodes.length; while (j—) { if (jQuery.nodeName ((tbody = elem.childNodes [j]), «tbody») &&! tbody.childNodes.length) { elem.removeChild (tbody); } } }

Исправления ввода IE

 Line 1360: // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) checkOn: !!input.value, Line 2410: attrHooks: { type: { set: function( elem, value ) { if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { // Setting the type on a radio button after the value resets the value in IE6-9 // Reset value to default in case type is set after value during creation var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, Line 3486: // IE doesn't fire change on a check/radio until blur; trigger it on click // after a propertychange. Eat the blur-change in special.change.handle. // This still fires onchange a second time for check/radio after blur. if ( this.type === "checkbox" || this.type === "radio" ) { jQuery.event.add( this, "propertychange._change", function( event ) { if ( event.originalEvent.propertyName === "checked" ) { this._just_changed = true; } }); ... // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked; Line 4188: // Select is set to empty string on purpose // This is to test IE's treatment of not explictly // setting a boolean content attribute, // since its presence should be enough // http://bugs.jquery.com/ticket/12359 div.innerHTML = " "; Line 6523: handle: function( event ) { var elem = event.target; // Swallow native change events from checkbox/radio, we already triggered them above if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { return event.handleObj.handler.apply( this, arguments ); } }, Line 6523: // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); }  Line 1360: // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) checkOn: !!input.value, Line 2410: attrHooks: { type: { set: function( elem, value ) { if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { // Setting the type on a radio button after the value resets the value in IE6-9 // Reset value to default in case type is set after value during creation var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, Line 3486: // IE doesn't fire change on a check/radio until blur; trigger it on click // after a propertychange. Eat the blur-change in special.change.handle. // This still fires onchange a second time for check/radio after blur. if ( this.type === "checkbox" || this.type === "radio" ) { jQuery.event.add( this, "propertychange._change", function( event ) { if ( event.originalEvent.propertyName === "checked" ) { this._just_changed = true; } }); ... // Check if a disconnected checkbox will retain its checked // value of true after appended to the DOM (IE6/7) support.appendChecked = input.checked; Line 4188: // Select is set to empty string on purpose // This is to test IE's treatment of not explictly // setting a boolean content attribute, // since its presence should be enough // http://bugs.jquery.com/ticket/12359 div.innerHTML = " "; Line 6523: handle: function( event ) { var elem = event.target; // Swallow native change events from checkbox/radio, we already triggered them above if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { return event.handleObj.handler.apply( this, arguments ); } }, Line 6523: // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); } 

IE Window / Расположение Исправления

 Line 7450: // #8138, IE may throw an exception when accessing // a field from window.location if document.domain has been set try { ajaxLocation = location.href; } catch( e ) { // Use the href attribute of an A element // since IE will modify it given document.location ajaxLocation = document.createElement( "a" ); ajaxLocation.href = ""; ajaxLocation = ajaxLocation.href; } 

IE исправляет ошибки

 Line 6848: // Wrapped to prevent IE from throwing errors when 'invalid' values are provided // Fixes bug #5509 try { style[ name ] = value; } catch(e) {} Line 7583: // If a selector was specified, locate the right elements in a dummy div // Exclude scripts to avoid IE 'Permission Denied' errors jQuery(" 
") .append (jQuery.parseHTML (responseText)) .find (селектор):

Протокол IE / исправления URL

 Line 7839: // Remove hash character (#7531: and string promotion) // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); 

IE Script / Ajax Исправления

 Line 8334: // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending // Use native DOM manipulation to avoid our domManip AJAX trickery head.insertBefore( script, head.firstChild ); Line 8427: var xhrCallbacks, xhrSupported, xhrId = 0, // #5280: Internet Explorer will keep connections alive if we don't abort on unload xhrOnUnloadAbort = window.ActiveXObject && function() { // Abort all pending requests var key; for ( key in xhrCallbacks ) { xhrCallbacks[ key ]( undefined, true ); } }; // Functions to create xhrs function createStandardXHR() { try { return new window.XMLHttpRequest(); } catch( e ) {} } function createActiveXHR() { try { return new window.ActiveXObject("Microsoft.XMLHTTP"); } catch( e ) {} } // Create the request object // (This is still attached to ajaxSettings for backward compatibility) jQuery.ajaxSettings.xhr = window.ActiveXObject ? /* Microsoft failed to properly * implement the XMLHttpRequest in IE7 (can't request local files), * so we use the ActiveXObject when it is available * Additionally XMLHttpRequest can be disabled in IE7/IE8 so * we need a fallback. */ function() { return !this.isLocal && createStandardXHR() || createActiveXHR(); } : // For all other browsers, use the standard XMLHttpRequest object createStandardXHR; Line 8562: // When requesting binary data, IE6-9 will throw an exception // on any attempt to access responseText (#11426) if ( typeof xhr.responseText === "string" ) { responses.text = xhr.responseText; } Line 8584: // IE - #1450: sometimes returns 1223 when it should be 204 } else if ( status === 1223 ) { status = 204; } Line 8605: } else if ( xhr.readyState === 4 ) { // (IE6 & IE7) if it's in cache and has been // retrieved directly we need to fire the callback setTimeout( callback ); 

IE Разное Исправления

 Line 71: // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) rtrim = /^[suFEFFxA0]+|[suFEFFxA0]+$/g, Line 419: // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready ); } Line 441: // See test/unit/core.js for details concerning isFunction. // Since version 1.3, DOM methods and functions like alert // aren't supported. They return false on IE (#2968). isFunction: function( obj ) { return jQuery.type(obj) === "function"; }, Line 1332: // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Make sure that URLs aren't manipulated // (IE normalizes it by default) hrefNormalized: a.getAttribute("href") === "/a", // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, Line 1399; // Support: IE<9 try { delete div.test; } catch( e ) { support.deleteExpando = false; } Line 5863: // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X 
","
"] Строка 6018: // Если это выбор, убедитесь, что он отображается пустым (# 12336) // Поддержка: IE <9 if (elem.options && jQuery.nodeName (elem, "select")) { elem.options.length = 0; } Строка 6504: // Исправляем # 12392 для WebKit и IE> 9 tmp.textContent = "";

Вы можете быть в курсе обновлений браузера IE здесь: http://blogs.msdn.com/b/ie/

Спасибо за чтение и, пожалуйста, оставляйте комментарии.