Browse All Resources
Actionable Insights
AI in CX
AI-powered Innovation
Alorica Advisory Services
Alorica Analytics
Alorica Anywhere
Alorica Automation
Alorica Experiences Practice
Alorica IQ
Alorica Way
Back Office
bpo global delivery
Communications
Community
Contact Optimization
Content Management
Content Moderation
Continuity
Culture & CSR
Customer Care
Customer Experience
Customer Experience Strategies
CX
cx strategies
Digital-first
Efficiency & Optimization
Financial Solutions
fraud
Geo Optimization
Geographic Expansion
Growth
healthcare
healthcare leader
healthcare solutions
Innovation
Loan Servicing
Loyalty & Engagement
Market Challenges
Marketplace Services
Multilingual Support
North America
Omnichannel
Outcomes
Quality Assurance
Revenue Generation
Speed to Proficiency
Tech Support
Technical Support
Technology
Trust & Safety
usa
Voice Translation
Workforce Growth
Workforce Optimization
All
Banking & Financial Services
BFSI
Communications
Energy & Utilities
Healthcare
Public Sector
Retail and Consumer Goods
Technology
Travel & Hospitality
All
Calculators
Case Studies
Fact Sheets
Market Research
Podcasts
Strategic Guides & Trend Reports
Thought Leadership
Webinars & Fireside Chats
All
(function () {
let initialized = false;
let lastState = "";
let isBuilding = false;
/* ================================
GET PAGINATION
================================ */
function getPagination() {
return document.querySelector(
".elementor-pagination"
);
}
/* ================================
GET CURRENT PAGE
================================ */
function getCurrentPage(pagination) {
const current = pagination.querySelector(
"[aria-current='page']"
);
if (!current) return 1;
return parseInt(
current.textContent.replace(/\D/g, ""),
10
) || 1;
}
/* ================================
GET TOTAL PAGES
Only from visible pagination
links — NOT data-max-page
because that value is wrong
================================ */
function getTotalPages(pagination) {
let maxFound = 1;
pagination.querySelectorAll(".page-numbers").forEach(function (el) {
if (
el.classList.contains("prev") ||
el.classList.contains("next") ||
el.classList.contains("first-page") ||
el.classList.contains("last-page") ||
el.classList.contains("dots") ||
el.classList.contains("current")
) {
return;
}
const num = parseInt(el.textContent.replace(/\D/g, ""), 10);
if (!isNaN(num) && num > maxFound) {
maxFound = num;
}
});
return maxFound;
}
/* ================================
GET E-PAGE KEY
================================ */
function getEPageKey() {
/* From current URL */
const params = new URLSearchParams(
window.location.search
);
for (const key of params.keys()) {
if (key.startsWith('e-page-')) {
return key;
}
}
/* From pagination links */
const pagination = getPagination();
if (pagination) {
const links = pagination.querySelectorAll(
"a.page-numbers"
);
for (const link of links) {
try {
const url = new URL(link.href);
for (
const key of url.searchParams.keys()
) {
if (key.startsWith('e-page-')) {
return key;
}
}
} catch (e) { }
}
}
/* From anchor next page */
const anchor = document.querySelector(
".e-load-more-anchor"
);
if (anchor) {
const nextUrl =
anchor.getAttribute('data-next-page') ||
'';
try {
const url = new URL(nextUrl);
for (
const key of url.searchParams.keys()
) {
if (key.startsWith('e-page-')) {
return key;
}
}
} catch (e) { }
}
return null;
}
/* ================================
BUILD URL FOR PAGE NUMBER
================================ */
function buildPageURL(pageNumber) {
const pagination = getPagination();
if (pagination) {
// Page 1
if (pageNumber === 1) {
const firstLink = [...pagination.querySelectorAll("a.page-numbers")]
.find(a => {
const n = parseInt(a.textContent.replace(/\D/g, ""), 10);
return n === 1;
});
if (firstLink) {
return firstLink.href;
}
}
// Last page
let lastLink = null;
let max = 1;
pagination.querySelectorAll("a.page-numbers").forEach(function(a) {
const n = parseInt(a.textContent.replace(/\D/g, ""), 10);
if (!isNaN(n) && n >= max) {
max = n;
lastLink = a;
}
});
if (pageNumber === max && lastLink) {
return lastLink.href;
}
}
// Fallback (works even if links aren't available)
const url = new URL(window.location.href);
let path = url.pathname;
path = path.replace(/\/\d+\/?$/, "/");
if (!path.endsWith("/")) {
path += "/";
}
if (pageNumber > 1) {
path += pageNumber + "/";
}
url.pathname = path;
return url.toString();
}
/* ================================
REBUILD BUTTONS
Disconnect observer before
modifying DOM to prevent
infinite loop
================================ */
let observer = null;
function rebuildButtons() {
/* Prevent re-entry */
if (isBuilding) return;
const pagination = getPagination();
if (!pagination) return;
const currentPage = getCurrentPage(
pagination
);
const totalPages = getTotalPages(pagination);
const stateKey =
currentPage + "|" + totalPages;
/* Skip if nothing changed */
if (stateKey === lastState) return;
lastState = stateKey;
isBuilding = true;
/* ============================
DISCONNECT OBSERVER
before touching DOM
to prevent infinite loop
============================ */
if (observer) {
observer.disconnect();
}
/* Remove old buttons */
pagination.querySelector(
".first-page"
)?.remove();
pagination.querySelector(
".last-page"
)?.remove();
/* Skip if only 1 page */
if (totalPages >= 2) {
/* FIRST button */
const isFirstDisabled = currentPage = totalPages;
let lastBtn;
if (isLastDisabled) {
lastBtn = document.createElement("span");
lastBtn.className =
"page-numbers last-page";
} else {
lastBtn = document.createElement("a");
lastBtn.href = buildPageURL(totalPages);
lastBtn.className =
"page-numbers last-page";
}
pagination.prepend(firstBtn);
pagination.appendChild(lastBtn);
}
isBuilding = false;
/* ============================
RECONNECT OBSERVER
after DOM changes done
============================ */
if (observer) {
reconnectObserver();
}
}
/* ================================
SCROLL TO GRID
================================ */
function scrollToGrid() {
const grid = document.querySelector(
".custom-pagination-grid, " +
".insights-loop-grid, " +
".elementor-widget-loop-grid, " +
"[data-widget_type='loop-grid.post']"
);
if (!grid) return;
const header = document.querySelector(
"header, " +
".site-header, " +
".elementor-location-header, " +
"[data-elementor-type='header']"
);
window.scrollTo({
top:
grid.getBoundingClientRect().top +
window.pageYOffset -
(header ? header.offsetHeight : 80) -
20,
behavior: "smooth"
});
}
/* ================================
SETUP MUTATION OBSERVER
================================ */
let observerTarget = null;
let debounceTimer = null;
function reconnectObserver() {
if (!observerTarget) return;
observer.observe(observerTarget, {
childList: true,
subtree: true
});
}
function setupObserver() {
observerTarget = document.querySelector(
".elementor-widget-loop-grid, " +
".custom-pagination-grid, " +
"[data-widget_type='loop-grid.post']"
);
if (!observerTarget) return;
observer = new MutationObserver(
function (mutations) {
/* Skip if we are building */
if (isBuilding) return;
/* Check if mutations are
from our own button changes */
let relevantChange = false;
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (
node.nodeType !== 1
) continue;
/* Skip our own buttons */
if (
node.classList &&
(
node.classList.contains(
'first-page'
) ||
node.classList.contains(
'last-page'
)
)
) continue;
/* This is a real change
from Elementor AJAX */
relevantChange = true;
break;
}
if (relevantChange) break;
for (
const node of mutation.removedNodes
) {
if (node.nodeType !== 1) continue;
/* Skip removals of our buttons */
if (
node.classList &&
(
node.classList.contains(
'first-page'
) ||
node.classList.contains(
'last-page'
)
)
) continue;
relevantChange = true;
break;
}
if (relevantChange) break;
}
if (!relevantChange) return;
/* Debounce the rebuild */
clearTimeout(debounceTimer);
debounceTimer = setTimeout(
function () {
lastState = "";
rebuildButtons();
},
400
);
}
);
reconnectObserver();
}
/* ================================
INITIALIZE
================================ */
function init() {
if (initialized) return;
initialized = true;
/* Initial build */
rebuildButtons();
/* Setup observer */
setupObserver();
/* ============================
CLICK HANDLER
============================ */
document.addEventListener(
"click",
function (e) {
const link = e.target.closest(
".elementor-pagination a"
);
if (!link) return;
lastState = "";
setTimeout(function () {
rebuildButtons();
scrollToGrid();
}, 800);
}
);
/* ============================
ONE-TIME POLL
Short window only on load
Stop after 5 seconds
============================ */
let pollCount = 0;
const poll = setInterval(function () {
pollCount++;
if (pollCount >= 6) {
clearInterval(poll);
return;
}
if (!isBuilding) {
rebuildButtons();
}
}, 1000);
}
window.addEventListener("load", init);
})();