1//FIX SCROLL BAR ISSUE IOS NOT SUPPORTED 2 //extends -- inherits all from HTMLElement 3 class CustomScrollBar extends HTMLElement { 4 //initialize any default state/base element 5 constructor() { 6 super(); 7 } 8 9 //perform 10 connectedCallback() { 11 12 //encapsulate the markup/styles of custom element and can be access in JS outside the custom element>>custom-scrollbar 13 this.attachShadow({ mode: "open" }); 14 15 //this.datase >> DOMStringMap of custom-scrollbar 16 this.targetElId = this.dataset.targetId; 17 this.trackColor = this.dataset.trackColor || "#E5E5E5"; 18 this.trackWidth = this.dataset.trackWidth || "6px"; 19 this.thumbColor = this.dataset.thumbColor || "#B3B3B3"; 20 21 //scrollableElement-# 22 this.targetEl = document.querySelector(`#${this.targetElId}`); 23 24 //css for <custom-scrollbar 25 const style = document.createElement("style"); 26 style.textContent = ` 27 .custom-scrollbar { 28 width: ${this.trackWidth}; 29 height: 100%; 30 position: absolute; 31 top: 0; 32 right: 0; 33 z-index: 1; 34 } 35 36 .custom-scrollbar__track { 37 width: 100%; 38 height: 100%; 39 background-color: ${this.trackColor}; 40 } 41 42 .custom-scrollbar__thumb { 43 width: 100%; 44 background-color: ${this.thumbColor}; 45 border-radius: ${this.trackWidth}; 46 position: absolute; 47 top: 0; 48 animation: top 0.25s ease-in; 49 } 50 51 .custom-scrollbar__thumb:hover { 52 // background-color: red; 53 } 54 `; 55 //add css to #shadow-root(open) HTML 56 this.shadowRoot.appendChild(style); 57 58 //css for <head> 59 const style2 = document.createElement("style"); 60 style2.textContent = ` 61 .prevent-scroll { 62 -webkit-touch-callout: none; 63 -webkit-user-select: none; 64 -khtml-user-select: none; 65 -moz-user-select: none; 66 -ms-user-select: none; 67 user-select: none; 68 } 69 `; 70 // add css to document head 71 document.head.appendChild(style2); 72 73 //data-target-id not found 74 if (!this.targetEl) { 75 console.warn( 76 `CustomScrollBar: target element with id "${this.targetElId}" not found`,this, this.dataset.targetId 77 ); 78 return; 79 } 80 81 const observer = new IntersectionObserver((entries) => { 82 entries.forEach((entry) => { 83 if (entry.isIntersecting) { 84 this.setTargetElCSS(); 85 this.setScrollThumbHeight(); 86 } 87 }); 88 }); 89 90 observer.observe(this.targetEl); 91 92 this.shadowRoot.innerHTML += ` 93 <div class="custom-scrollbar"> 94 <div class="custom-scrollbar__track"> 95 <div class="custom-scrollbar__thumb"></div> 96 </div> 97 </div> 98 `; 99 100 this.targetEl.addEventListener("scroll", () => { 101 this.moveScrollThumb(); 102 }); 103 } 104 105 moveScrollThumb() { 106 const scrollBarThumb = this.shadowRoot.querySelector(".custom-scrollbar__thumb"); 107 const scrollBarTrackHeight = this.shadowRoot.querySelector(".custom-scrollbar__track").offsetHeight; 108 const scrollThumbTop = (this.targetEl.scrollTop / this.targetEl.scrollHeight) * scrollBarTrackHeight; 109 scrollBarThumb.style.top = `${scrollThumbTop}px`; 110 // console.log(scrollBarTrackHeight); 111 112 } 113 114 setTargetElCSS() { 115 this.targetEl.style.overflowY = "scroll"; 116 this.targetEl.style.position = "relative"; 117 this.targetEl.style["-ms-overflow-style"] = "none"; /* Firefox */ 118 this.targetEl.style.scrollbarWidth = "none"; /* Firefox */ 119 } 120 121 setScrollThumbHeight() { 122 // get the scroll bar element 123 const scrollBarTrack = this.shadowRoot.querySelector( 124 ".custom-scrollbar__track" 125 ); 126 const scrollBarThumb = this.shadowRoot.querySelector( 127 ".custom-scrollbar__thumb" 128 ); 129 130 // get the scroll bar track height 131 const scrollBarTrackHeight = scrollBarTrack.offsetHeight; 132 133 // get the target element height 134 const targetElHeight = this.targetEl.offsetHeight; 135 // console.log("targetElHeigh",targetElHeight); 136 137 // get the target element scroll height 138 const targetElScrollHeight = this.targetEl.scrollHeight; 139 // console.log("targetElScrollHeight",targetElScrollHeight); 140 141 // calculate the scroll thumb height 142 const scrollThumbHeight = 143 (targetElHeight / targetElScrollHeight) * scrollBarTrackHeight; 144 145 // >>>>set the scroll thumb height 146 //hide scroll less than 300 height 147 if(targetElHeight < 300){ 148 this.style.opacity = "0"; 149 } 150 //show scroll less than 300 height 151 else{ 152 scrollBarThumb.style.height = `${scrollThumbHeight}px`; 153 this.style.opacity = ""; 154 } 155 156 // attach click-drag event on the thumb 157 let isDragging = false;
158 let currentY; 159 160 // scrollbar LOgic 161 ['mousedown', 'touchstart'].forEach( eventjs => 162 scrollBarThumb.addEventListener(eventjs, (e) => { 163 isDragging = true; 164 165 //the distance when the mousedown/touchstart 166 if(eventjs == "touchstart"){currentY = e.touches[0].clientY;} 167 else{currentY = e.clientY;} 168 169 // prevent dragging highlights 170 this.preventContentHighlight("remove"); 171 172 // console.log("clicked", currentY); 173 }) 174 ); 175 176 ['mouseup','touchend'].forEach( eventjs => 177 document.addEventListener(eventjs, function(){ 178 isDragging = false; 179 180 // remove prevent dragging highlights 181 // this.preventContentHighlight("add"); 182 183 // console.log("unclicked"); 184 },false) 185 ); 186 187 ['mousemove', 'touchmove'].forEach( eventjs => 188 document.addEventListener(eventjs, (e) => { 189 if (!isDragging) return; 190 191 let distanceY; 192 if(eventjs == "touchmove"){distanceY = e.touches[0].clientY;} 193 else{distanceY = e.clientY;} 194 195 //the distance between when the mouse down and when its moving (always -1to1) 196 const deltaY = distanceY - currentY; 197 currentY = distanceY; 198 199 //moving the content 200 this.targetEl.scrollTop += 201 deltaY * (targetElScrollHeight / scrollBarTrackHeight); 202 203 // console.log("hold", currentY); 204 }) 205 ); 206 207 } 208 209 // prevent content highlight when dragging the thumb 210 preventContentHighlight(action) { 211 if (action) { 212 this.targetEl.classList.add("prevent-scroll"); 213 } else { 214 this.targetEl.classList.add("prevent-scroll"); 215 } 216 } 217 } 218 219 //customElements.define(name, constructor, options); options -- extends 220 customElements.define("custom-scrollbar", CustomScrollBar); 221
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.