Loading...
Loading...
Migrate jQuery 3.x to 4.0.0 safely in WordPress and legacy web projects. Covers all breaking changes: removed APIs ($.isArray, $.trim, $.parseJSON, $.type), focus event order changes, slim build differences, ES modules migration, and Trusted Types support. Use when: upgrading jQuery to 4.0, fixing "$.isArray is not a function" errors, WordPress jQuery migration, updating legacy JavaScript, or troubleshooting focus/blur event order issues.
npx skill4agent add jezweb/claude-skills jquery-4<!-- Development: Shows console warnings for deprecated features -->
<script src="https://code.jquery.com/jquery-4.0.0.js"></script>
<script src="https://code.jquery.com/jquery-migrate-4.0.2.js"></script>npm install jquery@4.0.0
# Or with migrate plugin for testing
npm install jquery@4.0.0 jquery-migrate@4.0.2| Removed | Native Replacement |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| Custom function (see below) |
| |
// Native replacement for $.camelCase
function camelCase(str) {
return str.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
}// OLD - No longer works in jQuery 4.0
$elems.push(elem);
$elems.sort(compareFn);
$elems.splice(index, count);
// NEW - Use array methods with call/apply
[].push.call($elems, elem);
[].sort.call($elems, compareFn);
[].splice.call($elems, index, count);
// Or convert to array first
const arr = $.makeArray($elems);
arr.push(elem);// jQuery 3.x order (non-standard):
// focusout → blur → focusin → focus
// jQuery 4.0 order (W3C standard):
// blur → focusout → focus → focusin// Example: code that may need adjustment
$input.on('blur focusout focus focusin', function(e) {
console.log(e.type); // Order changed in 4.0
});jquery-4.0.0.slim.min.js// If using slim build, replace Deferreds with Promises
// OLD - Deferred
const deferred = $.Deferred();
deferred.resolve(value);
deferred.promise();
// NEW - Native Promise
const promise = new Promise((resolve, reject) => {
resolve(value);
});toggleClass(boolean)toggleClass(undefined)// OLD - No longer works
$elem.toggleClass(true); // Added all classes
$elem.toggleClass(false); // Removed all classes
// NEW - Be explicit
$elem.addClass('class1 class2'); // Add classes
$elem.removeClass('class1 class2'); // Remove classes
// Or use toggleClass with class names
$elem.toggleClass('active', true); // Force add
$elem.toggleClass('active', false); // Force remove// OLD - Scripts auto-executed
$.get('script.js');
// NEW - Must specify dataType for auto-execution
$.get({
url: 'script.js',
dataType: 'script'
});
// Or use $.getScript (still works)
$.getScript('script.js');| Removed | Notes |
|---|---|
| Removed - define locally if needed |
| No longer needed - vendor prefixes obsolete |
| Removed - requestAnimationFrame handles this |
# Check current jQuery version in WordPress
wp eval "echo wp_scripts()->registered['jquery-core']->ver;"// Dequeue old jQuery and enqueue 4.0 (testing only)
function upgrade_jquery_for_testing() {
if (!is_admin()) {
wp_deregister_script('jquery-core');
wp_deregister_script('jquery');
wp_register_script('jquery-core',
'https://code.jquery.com/jquery-4.0.0.min.js',
array(), '4.0.0', true);
wp_register_script('jquery', false, array('jquery-core'), '4.0.0', true);
// Add migrate plugin for debugging
wp_enqueue_script('jquery-migrate',
'https://code.jquery.com/jquery-migrate-4.0.2.min.js',
array('jquery'), '4.0.2', true);
}
}
add_action('wp_enqueue_scripts', 'upgrade_jquery_for_testing', 1);// Common pattern in older plugins - BROKEN in 4.0
if ($.isArray(data)) { ... }
var json = $.parseJSON(response);
var cleaned = $.trim(userInput);
// Fix: Update to native methods
if (Array.isArray(data)) { ... }
var json = JSON.parse(response);
var cleaned = userInput.trim();// OLD jQuery type checking
if ($.type(value) === 'array') { ... }
if ($.type(value) === 'function') { ... }
if ($.type(value) === 'object') { ... }
if ($.type(value) === 'string') { ... }
if ($.type(value) === 'number') { ... }
// NEW Native type checking
if (Array.isArray(value)) { ... }
if (typeof value === 'function') { ... }
if (value !== null && typeof value === 'object' && !Array.isArray(value)) { ... }
if (typeof value === 'string') { ... }
if (typeof value === 'number') { ... }// Polyfill removed methods (temporary migration aid)
if (typeof $.isArray === 'undefined') {
$.isArray = Array.isArray;
}
if (typeof $.parseJSON === 'undefined') {
$.parseJSON = JSON.parse;
}
if (typeof $.trim === 'undefined') {
$.trim = function(str) {
return str == null ? '' : String.prototype.trim.call(str);
};
}
if (typeof $.now === 'undefined') {
$.now = Date.now;
}
if (typeof $.isFunction === 'undefined') {
$.isFunction = function(fn) {
return typeof fn === 'function';
};
}
if (typeof $.isNumeric === 'undefined') {
$.isNumeric = function(val) {
return !isNaN(parseFloat(val)) && isFinite(val);
};
}// ES Module import (new in 4.0)
import $ from 'jquery';
// Or with named export
import { $ } from 'jquery';
// In package.json, ensure module resolution
{
"type": "module"
}// jQuery 4.0 accepts TrustedHTML in DOM manipulation
import DOMPurify from 'dompurify';
// Create trusted HTML
const clean = DOMPurify.sanitize(untrustedHTML, {RETURN_TRUSTED_TYPE: true});
// Safe to use with jQuery 4.0
$('#container').html(clean);dataType: 'script'$.type()toggleClass(boolean)TypeError: $.isArray is not a functionArray.isArray()TypeError: $.parseJSON is not a functionJSON.parse()TypeError: $.trim is not a functionstr.trim()String.prototype.trim.call(str)TypeError: $.Deferred is not a functiondataType: 'script'toggleClass(true)| Feature | Full Build | Slim Build |
|---|---|---|
| Size (gzipped) | ~27.5k | ~19.5k |
| DOM Manipulation | Yes | Yes |
| Events | Yes | Yes |
| AJAX | Yes | No |
| Effects/Animation | Yes | No |
| Deferreds | Yes | No |
| Callbacks | Yes | No |
{
"dependencies": {
"jquery": "^4.0.0"
},
"devDependencies": {
"jquery-migrate": "^4.0.2"
}
}dataType: 'script'