jQuery 4.0.0 on täällä: mitä muuttui ja mihin päivityksessä kannattaa varautua
jQuery täytti hiljattain 20 vuotta: John Resig esitteli kirjaston BarCampissa New Yorkissa 14.1.2006. Nyt jQuery-tiimi on julkaissut pitkän kehityssyklin ja useiden ennakkoversioiden jälkeen lopullisen jQuery 4.0.0 -version.
Tämä on ensimmäinen major-versio lähes kymmeneen vuoteen. Mukana on modernisointeja, pienempiä ja isompia siivouksia sekä myös muutoksia, jotka voivat rikkoa vanhaa koodia. Hyvä uutinen on, että julkaisun mukaan valtaosa projekteista pystyy päivittämään melko vähillä muutoksilla – kunhan käy olennaiset kohdat läpi.
Päivitystyökalut
jQuery-tiimi on julkaissut päivitystä varten upgrade guide -oppaan sekä jQuery Migrate -pluginin. Jos törmäät ongelmiin, ne kannattaa raportoida jQueryn GitHub-issueihin.
Miten jQuery 4.0.0 -julkaisu on saatavilla?
4.0.0 löytyy kuten ennenkin sekä jQueryn omasta CDN:stä että npm:stä. Kolmansien osapuolten CDN:t päivittyvät tyypillisesti hieman viiveellä (julkaisuaikataulut eivät ole jQuery-tiimin hallinnassa). Jos haluat lähteä liikkeelle heti, käytä jQueryn omaa CDN:ää.
Suorat CDN-linkit (täysi build)
- https://code.jquery.com/jquery-4.0.0.js
- https://code.jquery.com/jquery-4.0.0.min.js
npm-asennus
npm install jquery@4.0.0
Merkittävimmät muutokset: mitä sinun pitää oikeasti tietää?
1) IE<11-tuki poistui (IE11 vielä mukana – toistaiseksi)
jQuery 4.0 tiputtaa tuen IE10:lle ja sitä vanhemmille. Moni kysyy, miksei IE11:stä luovuttu saman tien: tiimi etenee vaiheittain, ja seuraava askel on suunnitelmien mukaan jQuery 5.0:ssa.
Samassa yhteydessä tuki poistui myös joukolta muita todella vanhoja selaimia: Edge Legacy (vanha, ei-Chromium Edge), iOS-versiot aiempaa viimeistä kolmea vanhemmat, Firefox-versiot aiempaa viimeistä kahta vanhemmat (poikkeuksena Firefox ESR) sekä Android Browser.
Jos vanha selain on pakko tukea
Jos sinun täytyy tukea mitään näistä poistuneista selaimista, käytännön suositus on pysyä jQuery 3.x -linjassa.
2) Trusted Types ja CSP: turvallisempi HTML-käsittely ja vähemmän CSP-kompastuksia
jQuery 4.0 tuo tuen Trusted Types -mallille. Käytännössä tämä tarkoittaa, että jos sovelluksesi käyttää selaimen tarjoamaa TrustedHTML-tyyppiä (ks. MDN: TrustedHTML), sen voi syöttää jQueryn DOM-manipulaatiometodeille tavalla, joka ei riko require-trusted-types-for-Content Security Policy -direktiiviä.
Lisäksi jQuery on muuttanut tapaa, jolla se tekee asynkronisia skriptipyyntöjä: aiemmin osa AJAX-skriptikuljetuksesta käytti jo <script>-tageja (mm. attribuuttien kuten crossdomain säilyttämiseksi), mutta nyt suurin osa asynkronisista script-requesteista tehdään <script>-tagin kautta. Tavoite on vähentää CSP-virheitä, joita syntyy inline-scriptien käytöstä.
Muutama poikkeus on edelleen olemassa: joissain tapauksissa jQuery käyttää yhä XHR:ää asynkronisiin skriptipyyntöihin, esimerkiksi silloin kun "headers"-optio on käytössä. Tällöin julkaisun suositus on käyttää scriptAttrs-vaihtoehtoa headers-option sijaan.
3) Lähdekoodi siirtyi AMD:stä ES moduleihin (ESM) ja paketointi Rollupilla
Yksi isoimmista “konehuoneen” muutoksista on se, että jQueryn main-haaran lähdekoodi on migroitu AMD-moduuliformaatista ES moduleihin (ESM). Tämä on merkittävää, koska jQueryn lähdekoodi on kyllä julkaistu npm:ssä ja GitHubissa, mutta sitä ei aiemmin voinut tuoda suoraan moduuleina ilman RequireJS:ää (joka oli pitkään jQueryn valinta build-työkaluksi).
Nyt jQuery paketoidaan Rollupilla, ja testit ajetaan erikseen myös ES module -muodolle. Tämän seurauksena jQuery istuu paremmin moderneihin build-työkaluihin ja työnkulkuihin – ja toimii myös selaimissa suoraan <script type=module> -latauksella.
4) Poistettuja (pitkään deprekoituja) API:ja – siirry natiiveihin vastineisiin
Major-julkaisu on jQuerylle se hetki, jolloin vuosia deprekoidut asiat voidaan oikeasti poistaa. 4.0:ssa poistettiin joukko funktioita, jotka olivat joko alun perinkin sisäisiä tai joille on nykyään natiivivastine kaikissa tuetuissa selaimissa.
Poistetut funktiot ovat:
jQuery.isArrayjQuery.parseJSONjQuery.trimjQuery.typejQuery.nowjQuery.isNumericjQuery.isFunctionjQuery.isWindowjQuery.camelCasejQuery.nodeNamejQuery.cssNumberjQuery.cssPropsjQuery.fx.interval
Käytännön korvaajat ovat tutut natiivit, kuten Array.isArray(), JSON.parse(), String.prototype.trim() ja Date.now().
Deprekoitujen API:jen poistaminen yhdistettynä vanhan IE-koodin siivoukseen pienensi jQueryn kokoa yli 3 kt gzippattuna.
5) Sisäiset Array-metodit poistettiin jQuery-prototyypistä: push, sort, splice
jQueryn prototyyppi on pitkään sisältänyt Array-metodeja, jotka eivät käyttäytyneet kuten muut jQuery-metodit ja olivat käytännössä tarkoitettu vain sisäiseen käyttöön. Nämä metodit ovat push, sort ja splice, ja ne on nyt poistettu jQuery-prototyypistä.
Jos sinulla on ollut koodia, joka kutsuu näitä suoraan jQuery-kokoelmalle, julkaisussa annettu esimerkki korvaajasta on:
// ennen (ei enää toimi jQuery 4:ssa)
// $elems.push( elem )
// jälkeen
[].push.call( $elems, elem );
6) Focus/blur-eventtien järjestys muuttui vastaamaan W3C-speksiä
Fokuseventtien järjestys on vuosia ollut selainten välillä epäyhtenäinen (focusin, focusout, focus, blur). Uusimmissa selaimissa, joita jQuery 4.0 tukee, eventtijärjestys on vihdoin yhtenäistynyt – mutta se ei ole sama kuin se “tasainen” järjestys, jonka jQuery aikoinaan valitsi.
jQuery 4.0 ei enää yliaja natiivia käyttäytymistä. Se tarkoittaa, että kaikki selaimet IE:tä lukuun ottamatta noudattavat nykyistä W3C-määrittelyä, jossa järjestys on:
- blur
- focusout
- focus
- focusin
Aiemmissa jQuery-versioissa järjestys oli: focusout, blur, focusin, focus. Julkaisun ironinen huomio: ainoa selain, joka koskaan noudatti vanhaa W3C-speksiä (ennen 2023 päivitystä), oli Internet Explorer.
7) Slim-build on entistä “slimmer”: Deferreds ja Callbacks poistettu
jQueryn slim-build (”kevennetty” paketti) pieneni jQuery 4.0.0:ssa entisestään, kun siitä poistettiin Deferreds ja Callbacks. Koko on nyt noin 19,5 kt gzippattuna.
Deferred-objektit ovat jo pitkään tukeneet Promises A+ -standardia, joten monessa tapauksessa voit siirtyä suoraan natiiveihin Promiseihin. Natiivit Promiset ovat saatavilla kaikissa jQuery 4.0:n tukemissa selaimissa paitsi IE11.
Huomio: Deferredeissä on joitain lisäominaisuuksia, joita natiivit Promiset eivät tarjoa, mutta iso osa käytöstä on silti migroitavissa Promise-metodeihin.
Jos IE11 on vielä tuettavana
Jos sinun pitää tukea IE11:ä, käytä mieluummin täyttä jQuery-buildia tai lisää polyfill natiiveille Promiseille.
Slim-buildin linkit
- https://code.jquery.com/jquery-4.0.0.slim.js
- https://code.jquery.com/jquery-4.0.0.slim.min.js
Päivitysstrategia käytännössä: miten minimoit riskin?
- Lue virallinen päivitysohje: https://jquery.com/upgrade-guide/4.0/
- Ota käyttöön jQuery Migrate ja käy konsolivaroitukset läpi: https://github.com/jquery/jquery-migrate/
- Testaa erityisesti: fokus/blur-eventtiketjut (UI-komponentit, validoinnit), CSP/Trusted Types -ympäristöt, sekä kaikki koodi joka kutsui poistettuja
jQuery.*apureita. - Jos projekti on sidottu hyvin vanhoihin selaimiin (IE10-, Edge Legacy, Android Browser), pidä jQuery 3.x tuotannossa ja suunnittele rinnalla refaktorointi.
Changelog ja tekniset kohokohdat (tiivistettynä, mutta kattavasti linkitettynä)
Jos haluat käydä muutokset commit-tasolla, virallinen vertailu on: Full changelog: 4.0.0. Alla on julkaisutiedotteen keskeiset osa-alueet ja esimerkkimuutoksia.
Ajax
- Don’t treat array data as binary (992a1911)
- Allow
processData: trueeven for binary data (ce264e07) - Support binary data (including FormData) (a7ed9a7b)
- Support
headersfor script transport even when cross-domain (#5142, 6d136443) - Support
nullas success functions injQuery.get(#4989, 74978b7e) - Don’t auto-execute scripts unless dataType provided (#4822, 025da4dd)
- Make responseJSON work for erroneous same-domain JSONP requests (68b4ec59)
- Execute JSONP error script responses (#4771, a1e619b0)
- Avoid CSP errors in the script transport for async requests (#3969, 07a8e4a1)
- Drop the json to jsonp auto-promotion logic (#1799, #3376, e7b3bc48)
- Overwrite s.contentType with content-type header value, if any (#4119, 7fb90a6b)
- Deprecate AJAX event aliases, inline event/alias into deprecated (23d53928)
- Do not execute scripts for unsuccessful HTTP responses (#4250, 50871a5a)
- Simplify jQuery.ajaxSettings.xhr (#1967, abdc89ac)
Attributes
- Make
.attr( name, false )remove for all non-ARIA attrs (#5388, 063831b6) - Shave off a couple of bytes (b40a4807)
- Don’t stringify attributes in the setter (#4948, 4250b628)
- Drop the
toggleClass(boolean|undefined)signature (#3388, a4421101) - Refactor val(): don’t strip carriage return, isolate IE workarounds (ff281991)
- Don’t set the type attr hook at all outside of IE (9e66fe9a)
CSS
- Fix dimensions of table
<col>elements (#5628, eca2a564) - Drop the cache in finalPropName (640d5825)
- Tests: Fix tests & support tests under CSS Zoom (#5489, 071f6dba)
- Fix reliableTrDimensions support test for initially hidden iframes (b1e66a5f)
- Selector: Align with 3.x, remove the outer
selector.jswrapper (53cf7244) - Make the reliableTrDimensions support test work with Bootstrap CSS (#5270, 65b85031)
- Make
offsetHeight( true ), etc. include negative margins (#3982, bce13b72) - Return
undefinedfor whitespace-only CSS variable values (#5120) (7eb00196) - Don’t trim whitespace of undefined custom property (#5105, ed306c02)
- Skip falsy values in
addClass( array ), compress code (#4998, a338b407) - Justify use of rtrim on CSS property values (655c0ed5)
- Trim whitespace surrounding CSS Custom Properties values (#4926, efadfe99)
- Include
show,hide&togglemethods in the jQuery slim build (297d18dd) - Remove the opacity CSS hook (865469f5)
- Workaround buggy getComputedStyle on table rows in IE/Edge (#4490, 26415e08)
- Don’t automatically add “px” to properties with a few exceptions (#2795, 00a9c2e5)
Core
- Remove obsolete workarounds, update support comments (e2fe97b7)
- Switch
$.parseHTMLfromdocument.implementationtoDOMParser(0e123509) - Fix the exports setup to make bundlers work with ESM & CommonJS (#5416, 60f11b58)
- Add more info about named exports (5f869590)
- Simplify code post browser support reduction (93ca49e6)
- Move the factory to separate exports (46f6e3da)
- Use named exports in
src/(#5262, f75daab0) - Fix regression in jQuery.text() on HTMLDocument objects (#5264, a75d6b52)
- Selector: Move jQuery.contains from the selector to the core module (024d8719)
- Drop the root parameter of jQuery.fn.init (d2436df3)
- Don’t rely on splice being present on input (9c6f64c7)
- Manipulation: Add basic TrustedHTML support (#4409, de5398a6)
- Report browser errors in parseXML (#4784, 89697325)
- Make jQuery.isXMLDoc accept falsy input (#4782, fd421097)
- Drop support for Edge Legacy (i.e. non-Chromium Microsoft Edge) (#4568, e35fb62d)
- Fire iframe script in its context, add doc param in globalEval (#4518, 4592595b)
- Exclude callbacks & deferred modules in the slim build as well (fbc44f52)
- Migrate from AMD to ES modules 🎉 (d0ce00cd)
- Use Array.prototype.flat where supported (#4320, 9df4f1de)
- Remove private copies of push, sort & splice from the jQuery prototype (b59107f5)
- Implement .even() & .odd() to replace POS :even & :odd (78420d42)
- Deprecate jQuery.trim (#4363, 5ea59460)
- Remove IE-specific support tests, rely on document.documentMode (#4386, 3527a384)
- Drop support for IE <11, iOS <11, Firefox <65, Android Browser & PhantomJS (#3950, #4299, cf84696f)
- Remove deprecated jQuery APIs (#4056, 58f0c00b)
Data
- Refactor to reduce size (805cdb43)
- Event:Manipulation: Prevent collisions with Object.prototype (#3256, 9d76c0b1)
- Separate data & css/effects camelCase implementations (#3355, 8fae2120)
Deferred
- Rename
getStackHooktogetErrorHook(#5201, 258ca1ec) - Respect source maps in jQuery.Deferred.exceptionHook (#3179, 0b9c5037)
- Rename master to primary (a32cf632)
Deprecated
- Define
.hover()using non-deprecated methods (fd6ffc5e) - Remove jQuery.trim (0b676ae1)
- Fix AMD parameter order (f810080e)
Dimensions
Docs
- Fix some minor issues in comments (e4d4dd81)
- update herodevs link in README (#5695, 093e63f9)
- Align CONTRIBUTING.md with
3.x-stable(d9281061) - Update CONTRIBUTING.md (4ef25b0d)
- add version support section to README (cbc2bc1f)
- Update remaining HTTP URLs to HTTPS (7cdd8374)
- Fix module links in the package README (ace646f6)
- update watch task in CONTRIBUTING.md (77d6ad71)
- Fix typos found by codespell (620870a1)
- remove stale gitter badge from readme (67cb1af7)
- Remove the “Grunt build” section from the PR template (988a5684)
- Remove stale badge from README (bcd9c2bc)
- Update the README of the published package (edccabf1)
- Remove git.io from a GitHub Actions comment (016872ff)
- Update webpack website in README (01819bc3)
- add link to patchwelcome and help wanted issues (924b7ce8)
- add link to preview the new CLAs (683ceb8f)
- Fix incorrect
trac-NUMBERreferences (eb9ceb2f) - remove expired links from old jquery source (#4997) (ed066ac7)
- Remove links to Web Archive from source (#4981, e24f2dcf)
- Replace
#NUMBERTrac issue references withtrac-NUMBER(5d5ea015) - Update the URL to the latest jQuery build in CONTRIBUTING.md (9bdb16cd)
- Remove the CLA checkbox in the pull request template (e1248931)
- update irc to Libera and fix LAMP dead link (175db73e)
- Update Frequently Reported Issues in the GitHub issue template (7a6fae6a)
- Change JS Foundation mentions to OpenJS Foundation (11611967)
- add SECURITY.md, show security email address (2ffe54ca)
- Fix typos (1a7332ce)
- Update the link to the jsdom repository (a62309e0)
- Use https for hyperlinks in README (73415da2)
- Remove a mention of the event/alias.js module from README (3edfa1bc)
- Update links to EdgeHTML issues to go through Web Archive (1dad1185)
- direct users to GitHub docs for cloning the repo (f1c16de2)
- Change OS X to macOS in README (5a3e0664)
- Update most URLs to HTTPS (f09d9210)
- Convert link to Homebrew from HTTP to HTTPS (e0022f23)
Effect / Effects
- Fix a unnecessary conditional statement in .stop() (#4374, 110802c7)
- Remove jQuery.fx.interval (6c2c7362)
Event
- Use
.preventDefault()in beforeunload (7c123dec) - Increase robustness of an inner native event in leverageNative (#5459, 527fb3dc)
- Avoid collisions between jQuery.event.special & Object.prototype (bcaeb000)
- Simplify the check for saved data in leverageNative (dfe212d5)
- Make trigger(focus/blur/click) work with native handlers (#5015, 6ad3651d)
- Simulate focus/blur in IE via focusin/focusout (#4856, #4859, #4950, ce60d318)
- Don’t break focus triggering after
.on(focus).off(focus)(#4867, e539bac7) - Make focus re-triggering not focus the original element back (#4382, dbcffb39)
- Don’t crash if an element is removed on blur (#4417, 5c2d0870)
- Remove the event.which shim (#3235, 1a5fff4c)
- remove jQuery.event.global (18db8717)
- Only attach events to objects that accept data — for real (#4397, d5c505e3)
- Stop shimming focusin & focusout events (#4300, 8a741376)
- Prevent leverageNative from registering duplicate dummy handlers (eb6c0a7c)
- Fix handling of multiple async focus events (#4350, ddfa8376)
Manipulation
- Make jQuery.cleanData not skip elements during cleanup (#5214, 3cad5c43)
- Generalize a test to support IE (88690ebf)
- Support $el.html(selfRemovingScript) (#5378) (#5377, 937923d9)
- Extract domManip to a separate file (ee6e8740)
- Don’t remove HTML comments from scripts (#4904, 2f8f39e4)
- Respect script crossorigin attribute in DOM manipulation (#4542, 15ae3614)
- Avoid concatenating strings in buildFragment (9c98e4e8)
- Make jQuery.htmlPrefilter an identity function (90fed4b4)
- Selector: Use the nodeName util where possible to save size (4504fc3d)
Offset
- Increase search depth when finding the ‘real’ offset parent (556eaf4a)
Release
- 4.0.0 (4f2fae08)
- remove dist files from main branch (c838cfb5)
- 4.0.0-rc.2 (97525193)
- Update AUTHORS.txt (c128d5d8)
- Fix release issues uncovered during the 4.0.0-rc.1 release (a5b0c431)
- remove dist files from main branch (9d06c6dd)
- 4.0.0-rc.1 (586182f3)
- Run
npm publishin the post-release phase (ff1f0eaa) - Only run browserless tests during the release (fb5ab0f5)
- Temporarily disable running tests on release (3f79644b)
- publish tmp/release/dist folder when releasing (#5658, a865212d)
- correct build date in verification; other improvements (53ad94f3)
- remove dist files from main branch (be048a02)
- 4.0.0-beta.2 (51fffe9f)
- ensure builds have the proper version (3e612aee)
- set preReleaseBase in config file (1fa8df5d)
- fix running pre/post release scripts in windows (5518b2da)
- update AUTHORS.txt (862e7a18)
- migrate release process to release-it (jquery/jquery-release#114, 2646a8b0)
- add factory files to release distribution (#5411, 1a324b07)
- use buildDefaultFiles directly and pass version (b507c864)
- copy dist-module folder as well (63767650)
- only published versioned files to cdn (3a0ca684)
- remove scripts and dev deps from dist package.json (7eac932d)
- update build command in Release.generateArtifacts (3b963a21)
- add support for md5 sums in windows (f088c366)
- remove the need to install grunt globally (b2bbaa36)
- upgrade release dependencies (967af732)
- Remove an unused chalk dependency (bfb6897c)
- Use an in-repository dist README fixture (358b769a)
- Update AUTHORS.txt (1b74660f)
- update AUTHORS.txt (cf9fe0f6)
Selector
- Remove the workaround for
:has; test both on iPhone & iPad (65e35450) - Properly deprecate
jQuery.expr[ ":" ]/jQuery.expr.filters(329661fd) - Make
selector.jsmodule depend onattributes/attr.js(#5379, e06ff088) - Eliminate
selector.jsdepenencies from various modules (e8b7db4b) - Re-expose jQuery.find.{tokenize,select,compile,setDocument} (#5259, 338de359)
- Stop relying on CSS.supports( “selector(…)” ) (#5194, 68aa2ef7)
- Backport jQuery selection context logic to selector-native (#5185, 2e644e84)
- Make selector lists work with
qSAagain (#5177, 09d988b7) - Implement the
uniqueSortchainable method (#5166, 5266f23c) - Re-introduce selector-native.js (4c1171f2)
- Manipulation: Fix DOM manip within template contents (#5147, 3299236c)
- Drop support for legacy pseudos, test custom pseudos (8c7da22c)
- Use jQuery
:hasifCSS.supports(selector(...))non-compliant (#5098, d153c375) - Remove the “a:enabled” workaround for Chrome <=77 (c1ee33ad)
- Make empty attribute selectors work in IE again (#4435, 05184cc4)
- Use shallow document comparisons in uniqueSort (#4441, 15750b0a)
- Add a test for throwing on post-comma invalid selectors (6eee5f7f)
- Make selectors with leading combinators use qSA again (ed66d5a2)
- Use shallow document comparisons to avoid IE/Edge crashes (#4441, aa6344ba)
- reduce size, simplify setDocument (29a9544a)
- Leverage the :scope pseudo-class where possible (#4453, df6a7f7f)
- Bring back querySelectorAll shortcut usage (cef4b731)
- Inline Sizzle into the selector module (47835965)
- Port Sizzle tests to jQuery (79b74e04)
Support
Traversing
- Fix
contents()on<object>s with children in IE (ccbd6b93) - Fix
contents()on<object>s with children (#4384, 4d865d96)
20-vuotisreunion ja julkaisukuva
Moni jQueryn kehittäjä ja kontribuuttori tapasi 20-vuotisreunion merkeissä Dallasissa, ja John Resig oli mukana Zoomin kautta. Julkaisupostaus tehtiin samalla kun porukka oli koolla.

Yhteenveto: milloin päivittää ja mitä testata ensin?
Jos olet jQuery 3.x -maailmassa ja tuet moderneja selaimia, 4.0.0 tuo järkevää siivousta: ESM-yhteensopivuus, parempi CSP/Trusted Types -tarina, pienempi footprint ja vanhojen apu-API:jen poistuminen pakottaa kohti natiiveja ratkaisuja.
Käytännössä ensimmäiset regressioriskit osuvat yleensä kolmeen paikkaan: (1) poistettuihin jQuery.* apureihin, (2) fokus-eventtien järjestykseen sekä (3) ympäristöihin, joissa CSP on tiukka tai Trusted Types on käytössä. Näiden ympärille kannattaa rakentaa smoke-testit ennen kuin vaihtaa CDN-linkit tuotannossa.
Emilia Korhonen
Suomen tiimin päätoimittaja, mobile-first ja responsiivisen suunnittelun asiantuntija. Yksinkertaisuuden ja toiminnallisuuden harmonia on tavoitteeni.
Kaikki julkaisut