8889841cue-remote-scroll.js000064400000033053150443507600010310 0ustar00function ueRemoteScrollControl(){ //objects var g_objWidget, g_objItems, g_objMessage; //classes var g_activeClass, g_classItem; //helpers var g_documentHeight, g_distanceFromPageTopPx, g_positionsArrayPercents, g_positionsArrayPx, g_positionsArrayId, g_activeIndex, g_windowHeight; //attr var g_dataPositionType, g_debugItemsPosition; /** * get scrolled amount */ function getScrollDistancePx(){ g_documentHeight = jQuery(document).height(); var distanceFromPageTop = jQuery(window).scrollTop(); return(distanceFromPageTop); } /** * show error */ function showError(errorText){ if(!g_objMessage.length) return(false); g_objMessage.addClass("ue-error"); g_objMessage.text(errorText); } /** * get data from items */ function getDataFromItems(dataType){ if(!dataType) throw new Error("Wrong data type!"); var dataArray = []; if(!g_objItems.length) return(false); g_objItems.each(function(index, item){ var objItem = jQuery(this); var data = objItem.data(dataType); if(data == undefined) return(true); dataArray.push(data); }); return(dataArray); } /** * set active item by its position */ function setActiveItem(objItem){ g_objItems.removeClass(g_activeClass); objItem.addClass(g_activeClass); } /** * trigger change event */ function doChangeItem(distanceFromPageTop, position, objItem, isItemActive, direction){ if(distanceFromPageTop >= position && isItemActive == false && direction == "down"){ //trigger custom change event g_objWidget.trigger("ue_change"); //set active item setActiveItem(objItem); } if(distanceFromPageTop <= position && isItemActive == false && direction == "up"){ //trigger custom change event g_objWidget.trigger("ue_change"); //set active item setActiveItem(objItem); } } /** * get position for element id parent scroll type */ function getPositionElementId(position){ //consider window height so items were positioned at the end of the screen position = getActualPositionWidgetId(position) - g_windowHeight / 2; return(position); } /** * get item position for position type percents */ function getPositionPercents(position, objItem){ var elementHeightPx = getPercentScrolltypeParentValue("height", objItem); //px var elementOffsetTopPx = getPercentScrolltypeParentValue("top", objItem); //px var elementScrollPositionPx = elementHeightPx * position / 100; //px position = elementOffsetTopPx + elementScrollPositionPx - g_windowHeight / 2; return(position); } /** * get objitem from the widget by its data attr and value */ function getObjItemByPosition(dataPositionAttr, position){ var objItem = g_objWidget.find("[data-position-"+dataPositionAttr+"="+position+"]"); return(objItem); } /** * get scroll direction */ function getScrollDirection(currentScrollTop){ var direction; if(currentScrollTop > g_distanceFromPageTopPx) direction = "down"; if(currentScrollTop < g_distanceFromPageTopPx) direction = "up"; return(direction); } /** * set active item and trigger change event */ function changeOnScroll(array, dataPositionAttr){ //update some vars g_activeIndex = getActiveIndex(); g_windowHeight = jQuery(window).height(); var positionsNum = array.length; //if no items - exit if(positionsNum == 0) return(true); for(let i=0; i= g_activeIndex) doChangeItem(currentScrollTop, position, objItem, isItemActive, direction); //if scrolling up if(direction == "up" && i < g_activeIndex){ //consider that scrolling up requires to have position of next item var nextItemPosition = array[i+1]; if(dataPositionAttr == "percents") position = getPositionPercents(nextItemPosition, objItem); if(dataPositionAttr == "id") position = getPositionElementId(nextItemPosition); if(dataPositionAttr == "px") position = nextItemPosition; doChangeItem(currentScrollTop, position, objItem, isItemActive, direction); } } //update scroll distances after execution prev funnctions to allow detecting the scroll distance g_distanceFromPageTopPx = getScrollDistancePx(); } /** * change item */ function changeItem(){ if(!g_objItems.length) return(false); //change item accordiong to its scroll type g_objItems.each(function(){ if(g_dataPositionType == "percents") changeOnScroll(g_positionsArrayPercents, "percents"); if(g_dataPositionType == "px") changeOnScroll(g_positionsArrayPx, "px"); if(g_dataPositionType == "id") changeOnScroll(g_positionsArrayId, "id"); }); } /** * set items left position */ function setItemsLeftPosition(objItem){ //set left position var widgetOffsetLeft = g_objWidget.offset().left; var leftPosition = -widgetOffsetLeft + 100; // add extra 100px to give extra space from left screen side objItem.css({"left": leftPosition+"px"}); } /** * get parent height */ function getParentHeight(objItem, parentSelector1){ var objElement; objElement = objItem.parents(parentSelector1); if(!objElement.length) objElement = objItem.parents(".e-con"); if(!objElement.length){ var itemIndex = objItem.index(); var errorText = "Can't find parent element with Remote Scroll Item Number: "+itemIndex; showError(errorText); return(false); } var elementHeight = objElement.height(); return(elementHeight); } /** * get parent offset top */ function getParentOffsetTop(objItem, parentSelector1){ var objElement; objElement = objItem.parents(parentSelector1); if(!objElement.length) objElement = objItem.parents(".e-con"); if(!objElement.length){ var itemIndex = objItem.index(); var errorText = "Can't find parent element with Remote Scroll Item Number: "+itemIndex; showError(errorText); return(false); } var elementOffsetTop = objElement.offset().top; return(elementOffsetTop); } /** * get percent parent value */ function getPercentScrolltypeParentValue(value, objItem){ var dataScrollParentType = g_objWidget.data("scroll-parent-type"); var calculatedValue; if(dataScrollParentType == "page"){ if(value == "height") calculatedValue = g_documentHeight; if(value == "top") calculatedValue = 0; } if(dataScrollParentType == "section"){ if(value == "height") calculatedValue = getParentHeight(objItem, ".elementor-section"); if(value == "top") calculatedValue = getParentOffsetTop(objItem, ".elementor-section"); } if(dataScrollParentType == "el_id"){ elementId = g_objWidget.data("scroll-element-id"); objElementId = jQuery("#"+elementId); if(value == "height") calculatedValue = objElementId.height(); if(value == "top") calculatedValue = objElementId.offset().top; } return(calculatedValue); } /** * get item position percents */ function getItemPositionPercents(objItem, widgetOffsetTop){ var itemPosition = objItem.data("position-percents"); var elementHeight = getPercentScrolltypeParentValue("height", objItem); //height of relative element var elementOffsetTop = getPercentScrolltypeParentValue("top", objItem); //top position of related elemnt g_windowHeight = jQuery(window).height(); //consider window height so items were positioned at the end of the screen var pixelsFromTop = elementOffsetTop + elementHeight * itemPosition / 100 - widgetOffsetTop + g_windowHeight / 2; return(pixelsFromTop); } /** * get item position px */ function getItemPositionPx(objItem, widgetOffsetTop){ var itemPosition = objItem.data("position-px"); g_windowHeight = jQuery(window).height(); //consider window height so items were positioned at the end of the screen var pixelsFromTop = itemPosition - widgetOffsetTop + g_windowHeight / 2; return(pixelsFromTop); } /** * get actual position of elemet by id */ function getActualPositionWidgetId(itemPositionId){ var objElementId = jQuery("#"+itemPositionId); if(!objElementId.length){ var errorText = "Couldn't find id of the element: "+itemPositionId+". Please add a valid id."; showError(errorText); } var elementIdTopPosition = objElementId.offset().top; return(elementIdTopPosition); } /** * get item position px */ function getItemPositionWidgetId(objItem, widgetOffsetTop){ var itemPositionId = objItem.data("position-id"); var elementIdTopPosition = getActualPositionWidgetId(itemPositionId); //returns offset top of element var pixelsFromTop = elementIdTopPosition - widgetOffsetTop; return(pixelsFromTop); } /** * set debug items in the middle */ function setDebugItemsInMiddle(){ if(g_debugItemsPosition == false) return(false); var objItemsWrapper = g_objWidget.find(".ue-remote-scroll-items"); objItemsWrapper.addClass("ue-fixed"); } /** * set items position for debug mode */ function setItemsPostion(){ if(!g_objItems.length) return(false); //set debug items in the middle of the screen if needed if(g_debugItemsPosition == "middle"){ setDebugItemsInMiddle(); return(false); } g_objItems.each(function(){ var objItem = jQuery(this); //set hardcoded left position of items (equal to all items) setItemsLeftPosition(objItem); //set top position of items according to each item position type var widgetOffsetTop = g_objWidget.offset().top; //consider widget offset top to make visible items in debug mode var pixelsFromTop; if(g_dataPositionType == "percents"); pixelsFromTop = getItemPositionPercents(objItem, widgetOffsetTop); if(g_dataPositionType == "px") pixelsFromTop = getItemPositionPx(objItem, widgetOffsetTop); if(g_dataPositionType == "id") pixelsFromTop = getItemPositionWidgetId(objItem, widgetOffsetTop); objItem.css({"top": pixelsFromTop+"px"}); }); } /** * get active index */ function getActiveIndex(){ var objActiveItem = g_objWidget.find("."+g_classItem+"."+g_activeClass); if(!objActiveItem.length) return(null); var currentIndex = objActiveItem.index(); return(currentIndex); } /** * init class */ this.init = function(widgetId){ //init vars //classes g_activeClass = "ue-active"; g_classItem = "ue-remote-scroll-item"; //objects g_objWidget = jQuery("#"+widgetId); g_objItems = g_objWidget.find("."+g_classItem); g_objMessage = g_objWidget.find(".ue-message"); if(!g_objItems.length) throw new Error("No remote scroll items found."); //helpers g_documentHeight = jQuery(document).height(); g_windowHeight = jQuery(window).height(); g_distanceFromPageTopPx = getScrollDistancePx(); g_positionsArrayPercents = getDataFromItems("position-percents"); g_positionsArrayPx = getDataFromItems("position-px"); g_positionsArrayId = getDataFromItems("position-id"); g_activeIndex = getActiveIndex(); //attr g_dataPositionType = g_objWidget.data("position-type"); g_debugItemsPosition = "middle"; //sets the debug items position in debug mode: middle, bottom; //set items position for debug setItemsPostion(); //init events jQuery(window).on("resize", function(){ changeItem(); setItemsPostion(); }); var animFrameId; jQuery(window).on('scroll', function(){ if (animFrameId) cancelAnimationFrame(animFrameId); animFrameId = requestAnimationFrame(changeItem); }); } }