Mobile Optimization
Forsta HX Platform - API Scripting Guide
Mobile Optimization
Device Detection:
/**
* isMobile - Detects if user is on a mobile device
* @returns {boolean} - Returns true if mobile device detected
* @description Uses regex to test navigator.userAgent against known
* mobile device identifiers. Includes smartphones and tablets.
* Note: User agent detection can be spoofed.
*/
function isMobile() {
// Test user agent string against common mobile device patterns
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
.test(navigator.userAgent);
}
/**
* isTablet - Detects if user is on a tablet device
* @returns {boolean} - Returns true if tablet device detected
* @description Checks for tablet-specific user agents (iPad, Android tablets)
* while excluding smaller mobile devices.
*/
function isTablet() {
return /iPad|Android/i.test(navigator.userAgent) &&
!isMobile();
}
// Apply mobile-specific logic
if(isMobile()) {
// Simplify complex grids
f(AQ1).addClass('mobile-simplified');
// Enable touch-friendly controls
$('.slider').css('height', '44px');
// Show one question at a time
$('.question').hide();
$('.question').first().show();
}
Touch Event Handling:
/**
* bindTouchOrClick - Attaches handler to both click and touch events
* @param {jQuery} element - The jQuery element to bind events to
* @param {Function} handler - The callback function to execute
* @description Creates cross-platform event handling that works on both
* desktop (click) and mobile (touchend) devices.
* Prevents default to avoid double-firing on some devices.
*/
function bindTouchOrClick(element, handler) {
// Bind to both click (desktop) and touchend (mobile) events
element.on('click touchend', function(e) {
e.preventDefault(); // Prevent default browser behavior
handler.call(this, e); // Execute handler with proper 'this' context
});
}
// Swipe detection for mobile navigation
var touchStartX = 0;
var touchEndX = 0;
f(AQ1).on('touchstart', function(e) {
touchStartX = e.changedTouches[0].screenX;
});
f(AQ1).on('touchend', function(e) {
touchEndX = e.changedTouches[0].screenX;
handleSwipe();
});
/**
* handleSwipe - Processes swipe gestures for mobile navigation
* @description Compares start and end X coordinates of touch.
* If difference exceeds 50px threshold, triggers navigation:
* - Swipe left (negative diff): go to next question
* - Swipe right (positive diff): go to previous question
*/
function handleSwipe() {
// Check for left swipe (end position < start position by 50+ pixels)
if(touchEndX < touchStartX - 50) {
// Swipe left - navigate forward
goToNextQuestion();
}
// Check for right swipe (end position > start position by 50+ pixels)
if(touchEndX > touchStartX + 50) {
// Swipe right - navigate backward
goToPreviousQuestion();
}
}
Orientation Change:
// Handle orientation changes
window.addEventListener('orientationchange', function() {
setTimeout(function() {
// Recalculate layouts
adjustLayout();
// Warn if portrait is required
if(window.orientation === 90 || window.orientation === -90) {
if(requiresPortrait()) {
showOrientationWarning();
}
}
}, 200);
});
/**
* showOrientationWarning - Displays a message asking user to rotate device
* @description Creates a fixed-position overlay div prompting the user
* to switch to portrait mode. Styled with orange background
* and centered on screen. Useful for surveys requiring portrait.
*/
function showOrientationWarning() {
// Create warning div with jQuery, styled inline for immediate display
var warning = $('<div class="orientation-warning">')
.text('Please rotate your device to portrait mode')
.css({
'position': 'fixed',
'top': '50%',
'left': '50%',
'transform': 'translate(-50%, -50%)',
'background': '#ff9800',
'padding': '20px',
'border-radius': '8px',
'z-index': 10000
});
$('body').append(warning);
}