NOTE: This page lists the messages for jQuery Migrate 3.0. If you are using an earlier version, see the documentation on the 1.x-stable branch.
To allow developers to identify and fix compatibility issues when migrating older jQuery code, the development (uncompressed) version of the plugin generates console warning messages whenever any of its functionality is called. The messages only appear once on the console for each unique message.
In most cases these messages are simply warnings; code should continue to work properly with later versions of jQuery as long as the jQuery Migrate plugin is used, but we recommend changing the code where possible to eliminate warnings so that the plugin does not need to be used.
The production (compressed) version of the plugin does not generate warnings. To continue using jQuery code that has compatibility issues without making any changes and without console messages, simply include the production version in the file rather than the development version. See the README for download instructions.
All messages generated by this plugin start with the text "JQMIGRATE" for easy identification. The warning messages, causes, and remediation instructions are listed below. Items listed as deprecated and removed must be changed before the code will work properly without the Migrate plugin. Items listed as only deprecated are still supported by the current version but no longer considered a good practice, and may be removed in the future.
This is not a warning, but a console log message the plugin shows when it first loads to indicate whether warnings will be shown on the console when appropriate. As of version 1.4.0 this message is also shown with production builds. The use jQuery Migrate in production has performance impacts and can complicate debugging as it modifies the normal behavior of the version of jQuery being used.
Cause: The page does not have a version of jQuery installed, or is using a version of jQuery older than 3.0.0. The jQuery Migrate plugin is not intended to be used for those cases. Any messages that follow this one may not be accurate, or the page may not run properly at all.
Solution: See the README for more information on usage and upgrading from older versions.
Cause: The plugin detected that some version of jQuery Migrate is already loaded. Loading multiple versions can cause unpredictable behavior.
Solution: Remove all but the latest version of the jQuery Migrate plugin. See the README for more information on usage and upgrading from older versions.
Cause: Selectors such as a[href=#main]
are not valid CSS syntax because the value contains special characters that are not quoted. Until jQuery 1.11.3/2.1.4 this was accepted, but the behavior is non-standard and was never documented. In later versions this selector throws an error. In some cases with complex selectors, Migrate may not attempt a repair. In those cases a fatal error will be logged on the console and you will need to fix the selector manually.
Solution: Put quotes around any attribute values that have special characters, e.g. a[href="#main"]
. The warning message contains the selector that caused the problem, use that to find the selector in the source files.
Cause: A browser runs in "quirks mode" when the HTML document does not have a <!doctype ...>
as its first non-blank line, or when the doctype in the file is invalid. This mode causes the browser to emulate 1990s-era (HTML3) behavior. In Internet Explorer, it also causes many high-performance APIs to be hidden in order to better emulate ancient browsers. jQuery has never been compatible with, or tested in, quirks mode.
Solution: Put a valid doctype in the document and ensure that the document is rendering in standards mode. The simplest valid doctype is the HTML5 one, which we highly recommend: <!doctype html>
. The jQuery Migrate plugin does not attempt to fix issues related to quirks mode.
Cause: The .success()
, .error()
, and .complete()
methods of the jQXHR
object returned from jQuery.ajax()
have been deprecated since jQuery 1.8 and were removed in jQuery 3.0.
Solution: Replace the use of these methods with the standard Deferred methods: .success()
becomes .done()
, .error()
becomes .fail()
, and .complete()
becomes .always()
.
Cause: The $().error()
method was used to attach an "error" event to an element but has been removed in 1.9 to reduce confusion with the $.error()
method which is unrelated and has not been deprecated. It also serves to discourage the temptation to use $(window).error()
which does not work because window.onerror
does not follow standard event handler conventions. The $().error()
method was removed in jQuery 3.0.
Solution: Change any use of $().error(fn)
to $().on("error", fn)
.
Cause: The .load()
and .unload()
event methods attach a "load" and "unload" event, respectively, to an element. They were deprecated in 1.9 and removed in 3.0 to reduce confusion with the AJAX-related .load()
method that loads HTML fragments and which has not been deprecated. Note that these two methods are used almost exclusively with a jQuery collection consisting of only the window
element. Also note that attaching an "unload" or "beforeunload" event on a window via any means can impact performance on some browsers because it disables the document cache (bfcache). For that reason we strongly advise against it.
Solution: Change any use of $().load(fn)
to $().on("load", fn)
and $().unload(fn)
to $().on("unload", fn)
.
Cause: The .pipe()
method on a jQuery.Deferred
object was deprecated as of jQuery 1.8, when the .then()
method was changed to perform the same function.
Solution: In most cases it is sufficient to change all occurrences of .pipe()
to .then()
. Ensure that you aren't relying on context/state propagation (e.g., using this
) or synchronous callback invocation, which were dropped from .then()
for Promises/A+ interoperability as of jQuery 3.0.
Cause: As of jQuery 3.0 the jQuery.fx.interval
property can be used to change the animation interval only on browsers that do not support the window.requestAnimationFrame()
method. That is currently only Internet Explorer 9 and the Android Browser. Once support is dropped for these browsers, the property will serve no purpose and it will be removed.
Solution: Find and remove code that changes or uses jQuery.fx.interval
. If the value is being used by code in your page or a plugin, the code may be making assumptions that are no longer valid. The default value of jQuery.fx.interval
is 13
(milliseconds), which could be used instead of accessing this property.
Cause: The .andSelf()
method has been renamed to .addBack()
as of jQuery 1.9 to better reflect its purpose of adding back the previous set of results. The old alias was removed in jQuery 3.0.
Solution: Replace any use of .andSelf()
with .addBack()
.
Cause: The .size()
method returns the number of elements in the current jQuery object, but duplicates the more-efficient .length
property which provides the same functionality. As of jQuery 1.9 the .length
property is the preferred way to retrieve this value. jQuery 3.0 no longer contains the .size()
method.
Solution: Replace any use of .size()
with .length
.
Cause: The page is attempting to set or get a jQuery data item using kebab case, e.g. my-data
, when a my-data
item has been set directly on the jQuery data object. jQuery 3.0 always exclusively uses camel case, e.g., myData
, when it accesses data items via the .data()
API and does not find kebab case data in that object.
Solution: Either 1) Always use the .data()
API to set or get data items, 2) Always use camelCase names when also setting properties directly on jQuery's data object, or 3) Always set properties directly on the data object without using the API call to set or get data by name. Never mix direct access to the data object and API calls with kebab case names.
Cause: Prior to jQuery 3.0, using .removeAttr()
on a boolean attribute such as checked
, selected
, or readonly
would also set the corresponding named property to false
. This behavior was required for ancient versions of Internet Explorer but is not correct for modern browsers because the attribute represents the initial value and the property represents the current (dynamic) value.
Solution: It is almost always a mistake to use .removeAttr( "checked" )
on a DOM element. The only time it might be useful is if the DOM is later going to be serialized back to an HTML string. In all other cases, .prop( "checked", false )
should be used instead.
Cause: In earlier versions of jQuery, the .offset()
method would return a value of { top: 0, left: 0 }
for some cases of invalid input. jQuery 3.0 throws errors in some of these cases. The selected element in the jQuery collection must be a DOM element that has a getBoundingClientRect
method. Text nodes, the window
object, and plain JavaScript objects are not valid input to the .offset()
method. jQuery may throw an error in those cases but in general does not guarantee specific results with invalid inputs.
Solution: Do not attempt to get or set the offset information of invalid input.
Cause: As of jQuery 3.0, the serialization method jQuery.param
is fully independent of jQuery's ajax module. As a result, it does not look at the jQuery.ajaxSettings.traditional
flag that affects how form data is encoded. Note that the jQuery.ajax()
method still honors this flag if you make a request through it.
Solution: To continue using the traditional
flag, pass it explicitly: jQuery.data( myData, jQuery.ajaxSettings.traditional )
.
Cause: The jQuery.swap()
method temporarily exchanges a set of CSS properties. It was never documented as part of jQuery's public API and should not be used because it can cause performance problems due to forced layout. This method has been removed in jQuery 3.0.
Solution: Rework the code to avoid calling jQuery.swap()
, or explicitly set and restore the properties you need to change.
Cause:: These event binding methods have been deprecated in favor of the .on()
and .off()
methods which can handle both delegated and direct event binding. Although the older methods are still present in jQuery 3.0, they may be removed as early as the next major-version update.
Solution: Change the method call to use .on()
or .off()
, the documentation for the old methods include specific instructions. In general, the .bind()
and .unbind()
methods can be renamed directly to .on()
and .off()
respectively since the argument orders are identical.
Cause: Using one of jQuery's API methods to bind a "ready" event, e.g. $( document ).on( "ready", fn )
, will cause the function to be called when the document is ready, but only if it is attached before the browser fires its own DOMContentLoaded
event. That makes it unreliable for many uses, particularly ones where jQuery or its plugins are loaded asynchronously after page load.
Solution: Replace any use of $( document ).on( "ready", fn )
with $( fn )
. This approach works reliably even when the document is already loaded.
Cause: Additional arguments for jQuery.easing
methods were never documented and are redundant since the same behavior can be easily achieved without them. When Migrate detects this case, the specified easing function is not used and "linear"
easing is used instead for the animation.
Solution: Rewrite the easing function to only use one argument. If you are using the jQuery Easing plugin, upgrade to version 1.4.0 or higher.
For example, to implement Cubic easing, the old function might be:
jQuery.easing.easeInCubic = function ( p, t, b, c, d ) {
return c * ( t /= d ) * t * t + b;
}
You can achive same effect with this:
jQuery.easing.easeInCubic = function ( p ) {
return Math.pow( p, 3 );
}
See jQuery-ui commit for other possible cases.
Cause: The jQuery.parseJSON
method in recent jQuery is identical to the native JSON.parse
. As of jQuery 3.0 jQuery.parseJSON
is deprecated.
Solution: Replace any use of jQuery.parseJSON
with JSON.parse
.
Cause: This method was used by jQuery to determine if certain string arguments could be converted to numbers, but the name led people to apply their own interpretations to what the method means. As a result, it often doesn't meet the needs of specific cases. For example, a 25-character string of only digits is technically a valid number, but JavaScript cannot represent it accurately. The string "0x251D"
is a valid hexadecimal number but may not be acceptable numeric input to a web form.
Solution: Use a test for being numeric that makes sense for the specific situation. For example, instead of jQuery.isNumeric(string)
, use isNan(parseFloat(string))
if a floating point number is expected, or string.test(/^[0-9]{1,8}$/)
if a sequence of 1 to 8 digits is expected.
Cause: This method returns a string that indicates the type of the argument, for example "number"
or "function"
. However, as the JavaScript language evolves this method has become problematic because new language constructs might require this function to either return a new string (potentially breaking existing code) or somehow map new constructs into existing strings (again, potentially breaking existing code). Examples of new recent JavaScript features include asynchronous functions, class constructors, Symbol
s, or functions that act as iterators.
Solution: Review code that uses jQuery.type()
and use a type check that is appropriate for the situation. For example. if the code expects a plain function, check for typeof arg === "function"
.
Cause: The fact that jQuery.unique
sorted its results in DOM order was surprising to many who did not read the documentation carefully. As of jQuery 3.0 this function is being renamed to make it clear.
Solution: Replace all uses of jQuery.unique
with jQuery.uniqueSort
which is the same function with a better name.
Cause: The standard way to add new custom selectors through jQuery is jQuery.expr.pseudos
. These two other aliases are deprecated, although they still work as of jQuery 3.0.
Solution: Rename any of the older usage to jQuery.expr.pseudos
. The functionality is identical.
Cause: Calling .toggleClass()
with no arguments, or with a single Boolean true
or false
argument, has been deprecated. Its behavior was poorly documented, but essentially the method saved away the current class
value in a data item when the class was removed and restored the saved value when it was toggled back. If you do not believe you are specificially trying to use this form of the method, it is possible you are accidentally doing so via an inadvertent undefined value, as .toggleClass( undefined )
toggles all classes.
Solution: If this functionality is still needed, save the current full .attr( "class" )
value in a data item and restore it when required.
Cause: The code on the page has used the jQuery.event.props
or jQuery.event.fixHooks
data structures. These were used in previous versions to affect the properties that are copied from the native event to the jQuery event each time an event is delivered, but they had the potential to create performance issues. Versions of jQuery Mobile before 1.5 make use of this API and require jQuery Migrate to run properly.
Solution: The most popular use of these data structures are to add properties for touch or pointer events, and those properties are now supported by default with a newer high-performance approach in jQuery 3.0 that only retrieves the properties on first access. If you are using jQuery Mobile, check the jquerymobile.com site for updates. If you are using plugins such as pointerTouch or touchHooks, simply remove them as they are no longer needed.
Cause: The calling code has attempted to attach a load
event to window
after the page has already loaded. That means the handler will never run and so is probably not what the caller intended. This can occur when the event attachment is made too late, for example, in a jQuery ready handler. It can also occur when a file is loaded dynamically with jQuery after the page has loaded, for example using the $.getScript()
method.
Solution: If a function fn
does not actually depend on all page assets being fully loaded, switch to a ready handler $( fn )
which runs earlier and will aways run fn
even if the script that contains the code loads long after the page has fully loaded. If fn
actually does depend on the script being fully loaded, check document.readyState
. If the value is "complete"
run the function immediately, otherwise use $(window).on( "load", fn )
.
Cause: The jQuery.holdReady()
method has been deprecated due to its detrimental effect on the global performance of the page. This method can prevent all the code on the page from initializing for extended lengths of time.
Solution: Rewrite the page so that it does not require all jQuery ready handlers to be delayed. This might be accomplished, for example, by late-loading only the code that requires the delay when it is safe to run. Due to the complexity of this method, jQuery Migrate does not attempt to fill the functionality. If the underlying version of jQuery used with jQuery Migrate no longer contains jQuery.holdReady()
the code will fail shortly after this warning appears.
Cause: This method returns true
if its argument is thought to be a window
element. It was created for internal use and is not a reliable way of detecting window
for public needs.
Solution: Remove any use of jQuery.isWindow()
from code. If it is truly needed it can be replaced with a check for obj != null && obj === obj.window
which was the test used inside this method.
Cause: The .on()
and .trigger()
methods can set an event handler or generate an event for any event type, and should be used instead of the shortcut methods. This message also applies to the other event shorthands, including: blur, focus, focusin, focusout, resize, scroll, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, and contextmenu.
Solution: Instead of .click(fn)
use .on("click", fn)
. Instead of .click()
use .trigger("click")
.
Cause: The .hover()
method is a shorthand for the use of the mouseover
/mouseout
events. It is often a poor user interface choice because it does not allow for any small amounts of delay between when the mouse enters or exits an area and when the event fires. This can make it quite difficult to use with UI widgets such as drop-down menus. For more information on the problems of hovering, see the hoverIntent plugin.
Solution: Review uses of .hover()
to determine if they are appropriate, and consider use of plugins such as hoverIntent
as an alternative. The direct replacement for .hover(fn1, fn2)
, is .on("mouseenter", fn1).on("mouseleave", fn2)
.
Cause: This public but never-documented method has been deprecated as of jQuery 3.2.0.
Solution: Replace calls such as jQuery.nodeName( elem, "div" )
with a test such as elem.nodeName.toLowerCase() === "div"
.
Cause: The jQuery.cssProps
property is a public but undocumented object that allows CSS properties with one name to be mapped into another name. It was used for legacy browsers like IE8 that used non-standard names. This object is no longer used inside jQuery since all supported browsers now use the standard CSS property names.
Solution: Remove any uses of jQuery.cssProps
in application code.
Cause: Older versions of JavaScript made it difficult to determine if a particular object was a true Array, so jQuery provided a cross-browser function to do the work. The browsers supported by jQuery 3.0 all provide a standard method for this purpose.
Solution: Replace any calls to jQuery.isArray
with Array.isArray
.
Cause: Older versions of IE & Android Browser didn't implement a method to trim
strings so jQuery provided a cross-browser implementation. The browsers supported by jQuery 3.0 all provide a standard method for this purpose.
Solution: Replace any calls to jQuery.trim( text )
with text.trim()
if you know text
is a string; otherwise, you can replace it with String.prototype.trim.call( text == null ? "" : text )
.
Cause: In past versions, when a number-typed value was passed to .css()
jQuery converted it to a string and added "px"
to the end. As the CSS standard has evolved, an increasingly large set of CSS properties now accept values that are unitless numbers, where this behavior is incorrect. It has become impractical to manage these exceptions in the jQuery.cssNumber
object. In addition, some CSS properties like line-height
can accept both a bare number 2
or a pixel value 2px
. jQuery cannot know the correct way to interpret $.css("line-height", 2)
and currently treats it as "2px"
.
Solution: Always pass string values to .css()
, and explicitly add units where required. For example, use $.css("line-height", "2")
to specify 200% of the current line height or $.css("line-height", "2px")
to specify pixels. When the numeric value is in a variable, ensure the value is converted to string, e.g. $.css("line-height", String(height))
and $.css("line-height", height+"px")
.
Cause: jQuery 3.5.0 changed the way it processes HTML strings. Previously, jQuery would attempt to fix self-closed tags like <i class="test" />
that the HTML5 specification says are not self-closed, turning it into <i class="test"></i>
. This processing can create a security problem with malicious strings, so the functionality had to be removed.
Solution: Search for the reported HTML strings and edit the tags to close them explicitly. In some cases the strings passed to jQuery may be created inside the program and thus not searchable. Migrate warning messages include a stack trace that can be used to find the location of the usage in the code.