Proje: Okul Platform · Hub: Okul Platform — Conventions
Dom7 (mobile $$) is NOT jQuery — selector/method gotchas
resources/assets/scripts/mobile/app.js uses $$ which is Dom7 (Framework7’s jQuery-lite), not jQuery. Most APIs look the same, but several jQuery-only conveniences are missing and throw at runtime.
Unsupported pseudo-selectors
Dom7 delegates .is() / .filter() to native Element.matches(), which only accepts valid CSS selectors. jQuery-invented pseudos throw DOMException: Element.matches: ':X' is not a valid selector.
Known breakers:
:visible— usewindow.getComputedStyle(el).display !== 'none':hidden— usewindow.getComputedStyle(el).display === 'none'or.css('display') === 'none'
Safe (standard CSS): :checked, :disabled, :focus, :first-child, etc.
Unsupported methods
.get(index)— use array access$$collection[index]instead (Dom7 doesn’t implement.get()). ThrowsTypeError: $form.find(...).get is not a function..removeData(key)— use.data(key, null)instead (Dom7 .data() accepts arbitrary values including null).$$.trim— use nativestr.trim()(Dom7 has no$$.trimutility).$$(function() {...})document-ready shorthand — not guaranteed. Usedocument.readyStatecheck ordocument.addEventListener('DOMContentLoaded', ...).
$$.ajax() is callback-based, NOT promise-returning
Dom7’s $$.ajax() does not return a deferred/promise. .always() / .done() / .fail() chain throws TypeError: $$.ajax(...).always is not a function.
Use options callbacks instead:
$$.ajax({
type: 'POST',
url: url,
data: data,
dataType: 'json',
success: function (data) { /* .done equivalent */ },
error: function (xhr) { /* .fail equivalent — xhr, not responseJSON auto-populated */ },
complete: function () { /* .always equivalent — cleanup, always runs */ }
});Also: Dom7’s error handler receives raw xhr; xhr.responseJSON may not be set automatically. Parse xhr.responseText yourself (try { JSON.parse(xhr.responseText) }).
Supported (verified in this codebase)
.data(key, value)including non-string values (timeouts, intervals, objects) — see existingscrollTimeoutpattern around app.js:1312..css('prop', val)as setter and getter..on(event, selector, handler)event delegation..closest(),.find(),.each(),.attr(),.val().$$.ajax()withdataType: 'json',always/done/failpromise chain.
Incident (2026-04-14)
Symptom: Mobile OTP login failed on submit with Uncaught DOMException: Element.matches: ':visible' is not a valid selector.
Root cause: I wrote $form.find('.otp-code-group').is(':visible') out of jQuery habit.
Fix: Native computed-style check. Also prophylactically swapped removeData → data(…, null).
Rule
Before using any selector/method in mobile app.js, ask: “is this standard CSS / standard DOM, or a jQuery convenience?” If the latter, find a native or Dom7-supported equivalent. Desktop general.js runs real jQuery — these gotchas only apply to mobile.
Related
- 2026-04-14-fe-style-js-locations — mobile/app.js konumu ve genel mobile JS kuralları
- 2026-04-14-mobile-login-modal-duplication — bu incident’in yaşandığı login akışı
- 2026-04-14-otp-value-field-validation — OTP form, incident’in tetikleyicisi