Upd.
Поскольку выяснилось, что для каждого элемента селектора надо вызывать ф-ю один раз, а не всего один раз глобально, понадобится книга учёта, где элементы будут отмечаться: выполнил / не выполнил ещё пока.
Не факт, что нужно на каждый кадр отрисовки заново искать в DOM элементы по селектору - это медленно.
Всё решение надо переписать с нуля, а тратить на это время нет желания.
Плохой старый ответ. Игнорировать.
Поскольку все эти макароны имеют дело только с одним элементом, можно просто обернуть этот треш в один мусорный пакет, в который передавать параметром селектор. И в рамках этого же пакета держать переменную-флаг, для обозначения, выполнили хоть раз ту функцию или ещё нет.
Warning этот вариант сработает вообще всего 1 раз, даже если элементов класса несколько. Похоже, ТС хотел иного: «1 раз для каждого найденного элемента класса».
мусорный пакет с макаронами(function(selector){ // ДОБАВЛЕНО
var done = false; // ДОБАВЛЕНО
function sAnim(el, fun, offset = 0) {
let self = document.querySelectorAll(el);
let winScrollY = window.scrollY;
let winHeight = window.innerHeight;
for (var i = 0; i < self.length; i++) {
let el = self[i];
let pos = el.getBoundingClientRect().top;
let top = pos.top + pageYOffset;
if (winScrollY > top - winHeight + winHeight / 100 * offset && winScrollY - winHeight < top - winHeight) {
//Нужно выполнить только 1 раз
if(done) return; // ДОБАВЛЕНО
fun(el);
done = true; // ДОБАВЛЕНО
}
}
}
function showHuntInSelecter(el) {
el.classList.add('show-hint');
setTimeout(function() {
el.classList.remove('show-hint');
}, 4000)
}
var scroll = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60)
};
var lastPosition = -1;
function loop() {
if (lastPosition == window.pageYOffset) {
scroll(loop);
return false;
} else lastPosition = window.pageYOffset;
// Функции при скролле
sAnim(selector, showHuntInSelecter, 30); // РЕДАКТИРОВАНО
// Функции при скролле
scroll(loop);
};
loop();
})('.selecter') // ДОБАВЛЕНО