* HKILD Section Engagement Tracking for Wix * * Tracks: * - Time spent in each section (using Intersection Observer) * - Button clicks in each section * * Sends data to Wix Collection: hkild_section_engagement * * Installation: * 1. Add this code to Wix Custom Code element * 2. Place on PD mobile page */ (function() { 'use strict'; // Configuration const config = { collectionId: 'section_engagement', sections: [ { id: 'hero', name: 'Hero + Stats', selector: '.hero, [class*="hero"]' }, { id: 'honest-check', name: '報讀前問自己', selector: '[class*="honest"]' }, { id: 'four-advantages', name: '四大核心優勢', selector: '[class*="advantage"]' }, { id: 'course-content', name: '理論實戰並重', selector: '[class*="course"], [class*="content"]' }, { id: 'live-practice', name: '實戰練習', selector: '[class*="practice"], [class*="live"]' }, { id: 'graduation', name: '畢業成果', selector: '[class*="graduate"], [class*="graduation"]' }, { id: 'outcomes', name: '課程成果', selector: '[class*="outcome"]' }, { id: 'testimonials', name: '學員真實分享', selector: '[class*="testimonial"]' }, { id: 'schedule', name: '開班時間', selector: '[class*="schedule"], [class*="time"]' }, { id: 'faq', name: '常見問題', selector: '[class*="faq"], [class*="question"]' } ], flushInterval: 30000 // Send data every 30 seconds }; // Track state const state = { sections: {}, pendingData: [], flushTimer: null }; // Initialize section tracking state config.sections.forEach(section => { state.sections[section.id] = { name: section.name, timeSpent: 0, entered: 0, left: 0, lastEntered: null, isCurrentlyIn: false }; }); /** * Format date as YYYY-MM-DD */ function getDateString() { const now = new Date(); return now.toISOString().split('T')[0]; } /** * Get ISO timestamp */ function getTimestamp() { return new Date().toISOString(); } /** * Send data to Wix Collection */ async function sendDataToWix(data) { try { // Use Wix Data API to insert item const response = await fetch(`https://www.wixapis.com/v1/contacts/me`, { method: 'GET', headers: { 'Authorization': wixLocation.authorization } }); if (response.ok) { // If we can authenticate, send data const insertResponse = await fetch( `https://www.wixapis.com/wix-data/v2/items/${config.collectionId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': wixLocation.authorization }, body: JSON.stringify({ dataItem: { data: { section_id: data.sectionId, page_url: window.location.href, time_spent: data.timeSpent, button_clicks: data.buttonClicks || 0, last_updated: new Date().toISOString().split('T')[0], visitor_id: data.visitorId || 'anonymous' } } }) } ); if (insertResponse.ok) { console.log('✅ Tracking data sent to Wix:', data); } else { console.warn('⚠️ Failed to send tracking data to Wix:', insertResponse.status); } } } catch (error) { console.warn('⚠️ Could not send to Wix API:', error.message); // Fallback: store in localStorage as backup saveToLocalStorage(data); } } /** * Fallback: save to localStorage */ function saveToLocalStorage(data) { try { const key = 'hkild_user_behavior'; const existing = JSON.parse(localStorage.getItem(key) || '{}'); const today = getDateString(); if (!existing[today]) { existing[today] = { sections: {}, buttonClicks: [] }; } // Update section data existing[today].sections[data.sectionId] = { timeSpent: data.timeSpent, entered: data.entered, left: data.left }; localStorage.setItem(key, JSON.stringify(existing)); } catch (e) { console.warn('localStorage not available:', e); } } /** * Flush pending data to Wix */ async function flushData() { if (state.pendingData.length === 0) return; const dataToSend = [...state.pendingData]; state.pendingData = []; for (const data of dataToSend) { await sendDataToWix(data); // Small delay between requests await new Promise(resolve => setTimeout(resolve, 100)); } } /** * Record section entry */ function recordSectionEntry(sectionId) { if (!state.sections[sectionId]) return; const section = state.sections[sectionId]; section.entered++; section.lastEntered = Date.now(); section.isCurrentlyIn = true; console.log(`📍 Entered: ${section.name}`); } /** * Record section exit */ function recordSectionExit(sectionId) { if (!state.sections[sectionId]) return; const section = state.sections[sectionId]; if (section.lastEntered) { const elapsed = Math.round((Date.now() - section.lastEntered) / 1000); section.timeSpent += elapsed; section.left++; console.log(`📍 Exited: ${section.name} (${elapsed}s)`); } section.isCurrentlyIn = false; // Queue data to send const dataToSend = { date: getDateString(), sectionId: sectionId, sectionName: section.name, timeSpent: section.timeSpent, entered: section.entered, left: section.left, timestamp: getTimestamp() }; state.pendingData.push(dataToSend); } /** * Record button click in section */ function recordButtonClick(sectionId, buttonText) { const dataToSend = { date: getDateString(), sectionId: sectionId, sectionName: state.sections[sectionId]?.name || 'Unknown', buttonText: buttonText, timestamp: getTimestamp() }; state.pendingData.push(dataToSend); console.log(`🔘 Button clicked in ${sectionId}: ${buttonText}`); } /** * Setup Intersection Observer for section tracking */ function setupIntersectionObserver() { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { recordSectionEntry(entry.target.dataset.sectionId); } else { recordSectionExit(entry.target.dataset.sectionId); } }); }, { threshold: 0.1 // Trigger when 10% of section is visible }); // Observe all sections config.sections.forEach(section => { const elements = document.querySelectorAll(section.selector); elements.forEach(el => { el.dataset.sectionId = section.id; observer.observe(el); }); }); console.log('✅ Intersection Observer initialized'); } /** * Setup button click tracking */ function setupButtonTracking() { document.addEventListener('click', (event) => { const button = event.target.closest('button, a[role="button"]'); if (!button) return; // Find which section this button is in let section = button.closest('[data-section-id]'); if (section) { const sectionId = section.dataset.sectionId; const buttonText = button.textContent.trim().substring(0, 50); recordButtonClick(sectionId, buttonText); } }, true); console.log('✅ Button tracking initialized'); } /** * Initialize everything */ function initialize() { console.log('🚀 HKILD Tracking Initialized'); // Setup observers setupIntersectionObserver(); setupButtonTracking(); // Auto-flush data periodically state.flushTimer = setInterval(flushData, config.flushInterval); // Flush on page unload window.addEventListener('beforeunload', flushData); // Expose for debugging window.hkildTracking = { getState: () => state, flushData: flushData, recordButtonClick: recordButtonClick, recordSectionEntry: recordSectionEntry, recordSectionExit: recordSectionExit }; } // Start when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); } else { initialize(); } })();
top of page

~HA最新職位~Patient Care Assistant /ClinicalAssistant (New Territories East Cluster)(REF.NO.NTE2407053)

  • 作家相片: Admin
    Admin
  • 2024年8月2日
  • 讀畢需時 1 分鐘

~HA職位詳情~

Patient Care Assistant (Clinical Assistant) - (REF. NO.: NTE2407053)

Pay:HK$21,739 - 24,701 per month (Up to 5% of total basic salary as end-of-contract gratuity may be offered to contract staff upon completion of the contract subject to satisfactory performance.)

Key Responsibilities :

(a) blood-taking and related duties which include taking blood specimen and preparing blood specimen labels/blood-taking materials, blood culture, blood taking for Pediatric patients, blood glucose analysis using blood glucose meter etc.

(b) ECG for patients and related duties.

(c) Intravenous (IV) cannulation insertion and assessing the appropriate IV site.

(d) taking care and monitoring patients condition while performing the blood-taking, ECG or IV process and reporting to senior in case of abnormal situations.

Application Deadline : 13 August 2024

留言


香港生命開展學會 Hong Kong institute of Life Development

E-mail: info@hkild.com  

Tel: 852- 6906 3436

Address: Unit C 13/F Nathan Tower, 518-520 Nathan Road, Kowloon

九龍油麻地彌敦道518-520號 (彌敦行) 13 樓 C 室

Stationary photo

©2013 by HKILD.  All Rights Reserved.

bottom of page