jQuery is loaded on all modern pages (2017+) via _includes/footer.html which loads jQuery 3.3.1 from CDN. This analysis identifies every jQuery usage to help understand what would need to be refactored to remove the dependency.
| Location | jQuery Usage | What It Does | Complexity to Remove |
|---|---|---|---|
_includes/footer.html |
|||
| Line 100 | $('body').attr('data-overlay-active','false') |
Closes overlay when clicking underlay | EASY - Use document.body.setAttribute() |
| Line 172-174 | Loads jQuery 3.3.1 + jquery-migrate + jquery-touch-events from CDN | Provides jQuery library and touch event support | N/A - This is what we’re removing |
| Line 178 | $.each(q,function(i,f){$(f)}) |
Processes queued jQuery calls from before library loaded | EASY - Part of the queue system, remove with jQuery |
_layouts/jobs/home.html |
|||
| Line 53 | window.q=[]; window.$=function(f){q.push(f)}; |
Creates queue for jQuery calls before library loads | EASY - Remove queue system entirely |
/scripts/scripts.js)| Line(s) | jQuery Usage | What It Does | Complexity to Remove |
|---|---|---|---|
| 40 | $(function () { ... }) |
DOM ready wrapper - wraps all initialization code | EASY - Use DOMContentLoaded event |
| 46-66 | $(document).on('click', '[data-overlay-trigger]', ...) |
Event delegation for overlay triggers (menu, slack, newsletter) | MEDIUM - Use document.addEventListener with event delegation pattern |
| 50-51 | $('body').attr('data-overlay-active') / $(this).attr('data-overlay-trigger') |
Gets/sets data attributes for overlay state | EASY - Use .getAttribute() / .setAttribute() |
| 57-59 | $("body").attr('data-overlay-active', _val) |
Sets overlay state on body | EASY - Use document.body.setAttribute() |
| 60-63 | $('.archive-nav__search').focus() / $('#email').focus() / $('#fieldEmail').focus() |
Focuses input fields when overlay opens | EASY - Use document.querySelector().focus() |
| 68-74 | $("[data-newletter-signup]").submit(...) |
Newsletter form submission handler | MEDIUM - Use querySelectorAll + forEach + addEventListener |
| 71 | $.post(form.action, $(form).serialize()) |
AJAX POST request with serialized form data | MEDIUM - Use fetch() API + FormData |
| 72 | $(this).parent().find(".js-signup-confirmation").show() |
Shows confirmation message | EASY - Use .parentElement.querySelector() + .style.display |
| 73 | $(this).remove() |
Removes form after submission | EASY - Use .remove() |
| 78 | $(".container").fitVids() |
Makes YouTube/Vimeo videos responsive | MEDIUM - FitVids plugin dependency (see plugins section) |
| 82-86 | $(window).width() / $('.masthead').height() |
Gets window width and masthead height for scroll offset | EASY - Use window.innerWidth / .offsetHeight |
| 91-92 | $('.nav--in-page').length / $('#top').scrollspy(...) |
Initializes Bootstrap scrollspy for in-page navigation | HARD - Bootstrap plugin dependency (see plugins section) |
| 97-108 | $(document).on('click tap', 'a[href^="#"]', ...) |
Smooth scrolling for anchor links with event delegation | MEDIUM - Use native event delegation + smooth scroll |
| 99-102 | $(this.hash) / $('[name=...]') / target.offset().top |
Finds target element and gets its position | EASY - Use querySelector + .getBoundingClientRect() |
| 112-114 | $(document).on("click tap", ".js-show-talk-details__show", ...) |
Toggles talk details visibility on conference pages | EASY - Use event delegation + .closest() + .classList.toggle() |
| 113 | $(this).closest('.talk').toggleClass("talk-toggled-to-display") |
Finds parent talk element and toggles class | EASY - Use .closest() + .classList.toggle() (both native) |
| 126-142 | $("#info h3[id]").each(...) |
Generates table of contents from H3 elements | EASY - Use querySelectorAll + forEach |
| 127-130 | el = $(this) / el.text() / el.attr("id") |
Gets text content and ID attribute | EASY - Use .textContent / .getAttribute() |
| 142 | $("[data-toc]").after(ToC) |
Inserts generated ToC after element | EASY - Use .insertAdjacentHTML() |
| 197-230 | $('.job-open').on('click', ...) |
Opens job detail modal (jobs page) | MEDIUM - Complex modal system with positioning |
| 202 | $(document).scrollTop() |
Saves scroll position | EASY - Use window.pageYOffset |
| 204-208 | $(this).closest('.job').hasClass() / .removeClass() / .find() / .attr() |
Checks state, manipulates classes and attributes | EASY - All have native equivalents |
| 212 | $(this).closest('.job').attr('id') |
Gets job ID for URL | EASY - Use .closest() + .getAttribute() |
| 215-227 | $(this).closest('.job').find('.job-info') / .width() / .height() / .css() |
Gets job info element, dimensions, and sets fixed positioning | MEDIUM - Use native DOM + .offsetWidth/Height + .style |
| 235-248 | $('.job-close').on('click', ...) |
Closes job detail modal | MEDIUM - Part of modal system |
| 241-243 | $(this).closest('.job').removeClass() / $('body').removeClass() / .find() / .attr() |
Closes modal, resets state | EASY - Native equivalents available |
| 252-274 | $('[data-target="ticket-tailor-modal"]').on('click', ...) |
Opens TicketTailor widget in modal | EASY - Use querySelectorAll + addEventListener |
| File | Line(s) | jQuery Usage | What It Does | Complexity |
|---|---|---|---|---|
_includes/participate.html |
||||
| 23-53 | Complete form handling with jQuery | Email signup form with validation | MEDIUM | |
| 27-36 | $('.get-involved .email-form input[type=email]').keyup(...) |
Validates email on keyup, enables/disables submit button | EASY - Use addEventListener('keyup') |
|
| 32 | $(this).val().match(/.@./) |
Gets input value for validation | EASY - Use .value |
|
| 39-51 | $('.get-involved .email-form').submit(...) |
Handles form submission | MEDIUM - Cross-iframe form submission | |
| 43 | $('#emailaddress', window.top.frames[0].document).val(...) |
Sets email in iframe form | MEDIUM - Cross-iframe DOM manipulation | |
| 46 | $('#email-form input[type=submit]', window.top.frames[0].document).click() |
Triggers submit in iframe | MEDIUM - Cross-iframe interaction | |
| 49-50 | $('.get-involved .email-form input, ...').hide() / .fadeIn() |
Shows/hides elements with animation | EASY - Use CSS transitions + .style.display |
|
_includes/jobs/jobs-unviewed-indicator.html |
||||
| 43 | $(jobs_current).not(jobs_stored).get().length |
Calculates array difference to find new jobs | EASY - Use filter() method on arrays |
|
| 55 | $('.masthead__link--jobs').addClass().append() |
Adds badge with unviewed job count to nav | EASY - Use .classList.add() + .insertAdjacentHTML() |
|
_includes/events/events-unviewed-indicator.html |
||||
| 29 | $(upcoming_current).not(upcoming_stored).get().length |
Calculates array difference to find new events | EASY - Use filter() method on arrays |
|
| 33 | $('.masthead__link--events').addClass().append() |
Adds badge with unviewed event count to nav | EASY - Use .classList.add() + .insertAdjacentHTML() |
|
_includes/mail-list-signup-form.html |
||||
| 38 | $(this).closest('form').toggleClass('conference') |
Toggles class when checkbox clicked | EASY - Use .closest() + .classList.toggle() |
|
| 42 | $(this).closest('form').toggleClass('evening') |
Toggles class when checkbox clicked | EASY - Use .closest() + .classList.toggle() |
|
| 46 | $(this).closest('form').toggleClass('job') |
Toggles class when checkbox clicked | EASY - Use .closest() + .classList.toggle() |
|
| 50 | $(this).closest('form').toggleClass('newsletter') |
Toggles class when checkbox clicked | EASY - Use .closest() + .classList.toggle() |
| Plugin | File(s) | What It Does | Complexity to Remove |
|---|---|---|---|
| FitVids | theme/javascripts/_fitvids.js |
Makes embedded videos (YouTube, Vimeo) responsive by wrapping them and calculating aspect ratios | MEDIUM - Can use CSS aspect-ratio property or modern responsive iframe techniques. Plugin is ~89 lines. |
scripts/scripts.js:78 |
Called as $(".container").fitVids() |
Already works with Zepto as fallback | |
| Bootstrap Scrollspy | theme/javascripts/_scrollspy.js |
Automatically highlights navigation items as you scroll past sections | HARD - 207 lines of Bootstrap code. Need to reimplement with IntersectionObserver API |
scripts/scripts.js:92 |
Called as $('#top').scrollspy({ target: '.nav--in-page', offset: navScrollOffset }) |
Used for in-page navigation on conference pages | |
| Bootstrap Affix | theme/javascripts/_affix.js |
Makes elements stick to viewport when scrolling | MEDIUM - Can use CSS position: sticky instead |
| Stickybits | theme/javascripts/_stickybits.js |
Polyfill for position: sticky |
EASY - Already checks for jQuery/Zepto, can work standalone. Modern browsers support sticky natively. |
| Tooltipster | js/tooltipster-master/ |
Tooltip library (full jQuery plugin) | HARD - Large plugin, but may not be actively used. Need to verify usage. |
| jQuery Touch Events | Loaded from CDN in footer | Adds touch event support (tap events) |
EASY - Use native touchstart/touchend or just click (works on mobile) |
| jQuery Migrate | Loaded from CDN in footer | Compatibility layer for older jQuery code | N/A - Only needed if using jQuery |
| Years | jQuery Version | Usage | Notes |
|---|---|---|---|
| 2011 | 1.4.3 | Smooth scrolling, basic interactions | Self-contained, not affecting modern site |
| 2012 | 1.8.0 | Parallax effects, inview plugin | Self-contained, not affecting modern site |
| 2013 | 1.8.0 | Similar to 2012 | Self-contained, not affecting modern site |
| 2014 | 1.8.0 | Similar to 2012-2013 | Self-contained, not affecting modern site |
| 2015 | 1.8.0 / 1.10.0 | Similar to previous years | Self-contained, not affecting modern site |
Note: Legacy years can be left as-is since they’re archived and self-contained.
| Library | File | Notes |
|---|---|---|
| List.js | Loaded from CDN | Used in _includes/filter-search-jobs.html for job filtering. Does NOT require jQuery - pure JavaScript library |
| TicketTailor Widget | /scripts/vendors/TTWidget.js |
Ticket purchasing widget. Does NOT require jQuery - standalone |
$() → querySelector() / querySelectorAll().attr() → .getAttribute() / .setAttribute().addClass() / .removeClass() / .toggleClass() → .classList methods.closest(), .find() → Native .closest(), .querySelector().width() / .height() → .offsetWidth / .offsetHeight.text() / .html() → .textContent / .innerHTML.show() / .hide() → .style.display.remove() → .remove() (native)$(array).not() → array.filter()$(document).on('click', selector, ...) → Custom delegation or individual listeners$.post() → fetch() API$(form).serialize() → FormData or manual serializationparticipate.html| Category | Files to Modify | Estimated Time |
|---|---|---|
| Core scripts refactoring | scripts/scripts.js |
4-6 hours |
| Include files | 4 files | 2-3 hours |
| Footer/layout updates | 2 files | 1 hour |
| Plugin replacements (FitVids, Stickybits) | 2 plugins | 2-3 hours |
| Scrollspy reimplementation | 1 plugin | 4-6 hours |
| Testing across all pages | All layouts | 3-4 hours |
| TOTAL | ~15 files | 16-23 hours |
| Risk | Impact | Mitigation |
|---|---|---|
| Breaking existing functionality | HIGH | Comprehensive testing, feature-by-feature replacement |
| Browser compatibility issues | MEDIUM | Use polyfills where needed, test on older browsers |
| Touch events not working | MEDIUM | Use native touch events or pointer events |
| Scrollspy behavior changes | MEDIUM | Thoroughly test navigation highlighting |
| Job modal positioning issues | MEDIUM | Test modal system extensively |
All proposed vanilla JS replacements are supported in:
For older browser support, may need polyfills for:
Element.closest() (IE11)fetch() (IE11)Recommendation: Drop IE11 support (it’s EOL as of June 2022) and target modern browsers only.