


jQuery iScroll.js Mobile Scroll Bar Beautification Plug-in Page 1/5_jquery
Official website: http://cubiq.org/iscroll-5
demo:
Scroll refresh: http://cubiq.org/dropbox/iscroll4/examples/pull-to-refresh/
iScroll is very powerful , currently I only use it to customize scroll bars. Here is a brief introduction to the use and precautions of iscrol when customizing scroll bars on mobile terminals.
1. Usage
iScroll initializes the elements to be scrolled, and does not limit the use of iScroll in one page the number of elements.
When using iScroll, the structure of the DOM tree should be simple enough, remove unnecessary tags, and avoid excessive tag nesting.
1. html part
1.1. The best and simplest iScroll structure
<div id="wrapper"> <ul> <li></li> ..... </ul> </div>
In this example, the ul tag will be scrolled. iScroll must cooperate with the wrapper outside the scrolling content to take effect.
1.2. Only the first child element in the wrapper can be scrolled
Because only the first child element in the wrapper can be scrolled, so let For scrolling multiple elements, the writing is as follows:
<div id="wrapper"> <div id="scroller"> <ul> <li></li> ... </ul> <ul> <li></li> ... </ul> </div> </div>
The scroller element can be scrolled, even if it contains two ul elements.
2. js calling part
2.1, use onDomContentLoaded event to implement scrolling
Applicable to scrolling content that only contains text and pictures, and all pictures have fixed sizes
<script src="iscroll.js"></script> <script> var myscroll; //myscroll是全局变量,可以在任意地方调用 function loaded(){ myscroll=new iScroll("wrapper"); } window.addEventListener("DOMContentLoaded",loaded,false); </script>
2.2. Use onLoad event to implement scrolling
Because DOMContentLoaded The event will be called after the DOM structure is loaded, so the length and width of the scroll area may not be determined before elements such as pictures are loaded. In this case, the onLoad event can be used to achieve this.
<script src="iscroll.js"><script> <script> var myscroll; function loaded(){ setTimeout(function(){ myscroll=new iScroll("wrapper"); },100 ); } window.addEventListener("load",loaded,false); </script>
In this case, iScroll will be initialized 100ms after the page resources (including images) are loaded. This should be a safer way to call iScroll.
2.3. Scroll bar loading in the pop-up frame
The pop-up frame is generally implemented by switching between display:none and display:block.
The element browser with display:none is not rendered, so the height of the scrolling content cannot be calculated.
So after the pop-up box calls show() to display it, the scroll bar area is instantiated. As follows:
$("#mobile_show_duobao_all_num").show(); new iScroll('tc-wrapper2', { scrollbarClass: 'myScrollbar' , hScrollbar:false, vScroll:true, hideScrollbar: false //是否隐藏滚动条 });
Tip: When the sliding screen appears, the compatibility problem of the entire page sliding is as follows:
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
2.4. iScroll passing parameters
The second parameter in iScroll allows you to customize some content, such as whether to hide the scroll bar, etc. . Commonly used parameters are as follows:
hScroll false disable horizontal scrolling true horizontal scrolling defaults to true
vScroll false delicate vertical scrolling true vertical scrolling defaults to true
hScrollbar false hides the scroll bar in the horizontal direction
vScrollbar false hides the scroll bar in the vertical direction
fixedScrollbar On iOS, when the element is dragged beyond the boundaries of the scroller, the scroll bar will shrink. Setting it to true can prevent the scroll bar from exceeding the boundaries of the
scroller. Visible area. Default is true on Android, false on iOS
fadeScrollbar false Specifies to hide the scroll bar when there is no fade effect
hideScrollbar Hide the scroll bar when there is no user interaction Default is true
bounce Enable or disable the border Bounce, the default is true
momentum Enable or disable inertia, the default is true, this parameter is very useful when you want to save resources
lockDirection false cancels the lock of the drag direction, true drags only in one direction Up (up/down or left/right)
2.5, general method
refresh This method should be called when the DOM tree changes
eg: setTimeout(function () { myScroll.refresh(); }, 0);
3. The css part
requires scrolling when customizing the scroll bar style Add a class parameter to the bar, as follows
var myscroll=new iScroll("wrapper",{ scrollbarClass: "myScrollbar" });
The scroll bar is composed of two elements: the container and the display. The container is the same height as the wrapper, and the display represents the scroll bar itself.
html results are as follows:
<div class="myScrollbarV"> <div></div> </div>
css is as follows, you can modify it yourself:
@charset "utf-8"; /* CSS Document */ /** * * Horizontal Scrollbar * */ .myScrollbarH { position:absolute; z-index:100; height:8px; bottom:1px; left:2px; right:7px } .myScrollbarH > div { position:absolute; z-index:100; height:100%; /* The following is probably what you want to customize */ background-image:-webkit-gradient(linear, 0 0, 100% 0, from(#a00), to(#f00)); background-image:-moz-linear-gradient(top, #f00, #900); background-image:-o-linear-gradient(top, #f00, #900); border:1px solid #900; -webkit-background-clip:padding-box; -moz-background-clip:padding-box; -o-background-clip:padding-box; background-clip:padding-box; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; -o-box-sizing:border-box; box-sizing:border-box; -webkit-border-radius:4px; -moz-border-radius:4px; -o-border-radius:4px; border-radius:4px; -webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); -moz-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); -o-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); } /** * * Vertical Scrollbar * */ .myScrollbarV { position:absolute; z-index:100; width:8px;bottom:7px;top:2px;right:1px } .myScrollbarV > div { position:absolute; z-index:100; width:100%; /* The following is probably what you want to customize */ background:-webkit-gradient(linear, 0 0, 100% 0, from(#f00), to(#900)); background-image:-moz-linear-gradient(top, #f00, #900); background-image:-o-linear-gradient(top, #f00, #900); border:1px solid #900; -webkit-background-clip:padding-box; -moz-background-clip:padding-box; -o-background-clip:padding-box; background-clip:padding-box; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; -o-box-sizing:border-box; box-sizing:border-box; -webkit-border-radius:4px; -moz-border-radius:4px; -o-border-radius:4px; border-radius:4px; -webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); -moz-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); -o-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5); }
2. Example
1. html+js
iScroll.js
/*! * iScroll v4.2.5 ~ Copyright (c) 2012 Matteo Spinelli, http://cubiq.org * Released under MIT license, http://cubiq.org/license */ (function(window, doc){ var m = Math, dummyStyle = doc.createElement('div').style, vendor = (function () { var vendors = 't,webkitT,MozT,msT,OT'.split(','), t, i = 0, l = vendors.length; for ( ; i < l; i++ ) { t = vendors[i] + 'ransform'; if ( t in dummyStyle ) { return vendors[i].substr(0, vendors[i].length - 1); } } return false; })(), cssVendor = vendor ? '-' + vendor.toLowerCase() + '-' : '', // Style properties transform = prefixStyle('transform'), transitionProperty = prefixStyle('transitionProperty'), transitionDuration = prefixStyle('transitionDuration'), transformOrigin = prefixStyle('transformOrigin'), transitionTimingFunction = prefixStyle('transitionTimingFunction'), transitionDelay = prefixStyle('transitionDelay'), // Browser capabilities isAndroid = (/android/gi).test(navigator.appVersion), isIDevice = (/iphone|ipad/gi).test(navigator.appVersion), isTouchPad = (/hp-tablet/gi).test(navigator.appVersion), has3d = prefixStyle('perspective') in dummyStyle, hasTouch = 'ontouchstart' in window && !isTouchPad, hasTransform = vendor !== false, hasTransitionEnd = prefixStyle('transition') in dummyStyle, RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize', START_EV = hasTouch ? 'touchstart' : 'mousedown', MOVE_EV = hasTouch ? 'touchmove' : 'mousemove', END_EV = hasTouch ? 'touchend' : 'mouseup', CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup', TRNEND_EV = (function () { if ( vendor === false ) return false; var transitionEnd = { '' : 'transitionend', 'webkit' : 'webkitTransitionEnd', 'Moz' : 'transitionend', 'O' : 'otransitionend', 'ms' : 'MSTransitionEnd' }; return transitionEnd[vendor]; })(), nextFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { return setTimeout(callback, 1); }; })(), cancelFrame = (function () { return window.cancelRequestAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || clearTimeout; })(), // Helpers translateZ = has3d ? ' translateZ(0)' : '', // Constructor iScroll = function (el, options) { var that = this, i; that.wrapper = typeof el == 'object' ? el : doc.getElementById(el); that.wrapper.style.overflow = 'hidden'; that.scroller = that.wrapper.children[0]; // Default options that.options = { hScroll: true, vScroll: true, x: 0, y: 0, bounce: true, bounceLock: false, momentum: true, lockDirection: true, useTransform: true, useTransition: false, topOffset: 0, checkDOMChanges: false, // Experimental handleClick: true, // Scrollbar hScrollbar: true, vScrollbar: true, fixedScrollbar: isAndroid, hideScrollbar: isIDevice, fadeScrollbar: isIDevice && has3d, scrollbarClass: '', // Zoom zoom: false, zoomMin: 1, zoomMax: 4, doubleTapZoom: 2, wheelAction: 'scroll', // Snap snap: false, snapThreshold: 1, // Events onRefresh: null, onBeforeScrollStart: function (e) { e.preventDefault(); }, onScrollStart: null, onBeforeScrollMove: null, onScrollMove: null, onBeforeScrollEnd: null, onScrollEnd: null, onTouchEnd: null, onDestroy: null, onZoomStart: null, onZoom: null, onZoomEnd: null }; // User defined options for (i in options) that.options[i] = options[i]; // Set starting position that.x = that.options.x; that.y = that.options.y; // Normalize options that.options.useTransform = hasTransform && that.options.useTransform; that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar; that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar; that.options.zoom = that.options.useTransform && that.options.zoom; that.options.useTransition = hasTransitionEnd && that.options.useTransition; // Helpers FIX ANDROID BUG! // translate3d and scale doesn't work together! // Ignoring 3d ONLY WHEN YOU SET that.options.zoom if ( that.options.zoom && isAndroid ){ translateZ = ''; } // Set some default styles that.scroller.style[transitionProperty] = that.options.useTransform ? cssVendor + 'transform' : 'top left'; that.scroller.style[transitionDuration] = '0'; that.scroller.style[transformOrigin] = '0 0'; if (that.options.useTransition) that.scroller.style[transitionTimingFunction] = ' cubic-bezier(0.33,0.66,0.66,1)'; if (that.options.useTransform) that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px)' + translateZ; else that.scroller.style.cssText += ';position:absolute;top:' + that.y + 'px;left:' + that.x + 'px'; if (that.options.useTransition) that.options.fixedScrollbar = true; that.refresh(); that._bind(RESIZE_EV, window); that._bind(START_EV); if (!hasTouch) { if (that.options.wheelAction != 'none') { that._bind('DOMMouseScroll'); that._bind('mousewheel'); } } if (that.options.checkDOMChanges) that.checkDOMTime = setInterval(function () { that._checkDOMChanges(); }, 500); }; // Prototype iScroll.prototype = { enabled: true, x: 0, y: 0, steps: [], scale: 1, currPageX: 0, currPageY: 0, pagesX: [], pagesY: [], aniTime: null, wheelZoomCount: 0, handleEvent: function (e) { var that = this; switch(e.type) { case START_EV: if (!hasTouch && e.button !== 0) return; that._start(e); break; case MOVE_EV: that._move(e); break; case END_EV: case CANCEL_EV: that._end(e); break; case RESIZE_EV: that._resize(); break; case 'DOMMouseScroll': case 'mousewheel': that._wheel(e); break; case TRNEND_EV: that._transitionEnd(e); break; } }, _checkDOMChanges: function () { if (this.moved || this.zoomed || this.animating || (this.scrollerW == this.scroller.offsetWidth * this.scale && this.scrollerH == this.scroller.offsetHeight * this.scale)) return; this.refresh(); }, _scrollbar: function (dir) { var that = this, bar; if (!that[dir + 'Scrollbar']) { if (that[dir + 'ScrollbarWrapper']) { if (hasTransform) that[dir + 'ScrollbarIndicator'].style[transform] = ''; that[dir + 'ScrollbarWrapper'].parentNode.removeChild(that[dir + 'ScrollbarWrapper']); that[dir + 'ScrollbarWrapper'] = null; that[dir + 'ScrollbarIndicator'] = null; } return; } if (!that[dir + 'ScrollbarWrapper']) { // Create the scrollbar wrapper bar = doc.createElement('div'); if (that.options.scrollbarClass) bar.className = that.options.scrollbarClass + dir.toUpperCase(); else bar.style.cssText = 'position:absolute;z-index:100;' + (dir == 'h' ? 'height:7px;bottom:1px; left:2px;right:' + (that.vScrollbar ? '7' : '2') + 'px' : 'width:7px;bottom:' + (that.hScrollbar ? '7' : '2') + 'px;top:2px;right:1px'); bar.style.cssText += ';pointer-events:none;' + cssVendor + 'transition-property:opacity;' + cssVendor + 'transition-duration:' + (that.options.fadeScrollbar ? '350ms' : '0') + '; overflow:hidden;opacity:' + (that.options.hideScrollbar ? '0' : '1'); that.wrapper.appendChild(bar); that[dir + 'ScrollbarWrapper'] = bar; // Create the scrollbar indicator bar = doc.createElement('div'); if (!that.options.scrollbarClass) { bar.style.cssText = 'position:absolute;z-index:100;background:rgba(0,0,0,0.5); border:1px solid rgba(255,255,255,0.9);' + cssVendor + 'background-clip:padding-box;' + cssVendor + 'box-sizing:border-box;' + (dir == 'h' ? 'height:100%' : 'width:100%') + ';' + cssVendor + 'border-radius:3px;border-radius:3px'; } bar.style.cssText += ';pointer-events:none;' + cssVendor + 'transition-property:' + cssVendor + 'transform;' + cssVendor + 'transition-timing-function:cubic-bezier(0.33,0.66,0.66,1);' + cssVendor + 'transition-duration:0;' + cssVendor + 'transform: translate(0,0)' + translateZ; if (that.options.useTransition) bar.style.cssText += ';' + cssVendor + 'transition-timing-function:cubic-bezier(0.33,0.66,0.66,1)'; that[dir + 'ScrollbarWrapper'].appendChild(bar); that[dir + 'ScrollbarIndicator'] = bar; } if (dir == 'h') { that.hScrollbarSize = that.hScrollbarWrapper.clientWidth; that.hScrollbarIndicatorSize = m.max(m.round(that.hScrollbarSize * that.hScrollbarSize / that.scrollerW), 8); that.hScrollbarIndicator.style.width = that.hScrollbarIndicatorSize + 'px'; that.hScrollbarMaxScroll = that.hScrollbarSize - that.hScrollbarIndicatorSize; that.hScrollbarProp = that.hScrollbarMaxScroll / that.maxScrollX; } else { that.vScrollbarSize = that.vScrollbarWrapper.clientHeight; that.vScrollbarIndicatorSize = m.max(m.round(that.vScrollbarSize * that.vScrollbarSize / that.scrollerH), 8); that.vScrollbarIndicator.style.height = that.vScrollbarIndicatorSize + 'px'; that.vScrollbarMaxScroll = that.vScrollbarSize - that.vScrollbarIndicatorSize; that.vScrollbarProp = that.vScrollbarMaxScroll / that.maxScrollY; } // Reset position that._scrollbarPos(dir, true); }, _resize: function () { var that = this; setTimeout(function () { that.refresh(); }, isAndroid ? 200 : 0); }, _pos: function (x, y) { if (this.zoomed) return; x = this.hScroll ? x : 0; y = this.vScroll ? y : 0; if (this.options.useTransform) { this.scroller.style[transform] = 'translate(' + x + 'px,' + y + 'px) scale(' + this.scale + ')' + translateZ; } else { x = m.round(x); y = m.round(y); this.scroller.style.left = x + 'px'; this.scroller.style.top = y + 'px'; } this.x = x; this.y = y; this._scrollbarPos('h'); this._scrollbarPos('v'); }, _scrollbarPos: function (dir, hidden) { var that = this, pos = dir == 'h' ? that.x : that.y, size; if (!that[dir + 'Scrollbar']) return; pos = that[dir + 'ScrollbarProp'] * pos; if (pos < 0) { if (!that.options.fixedScrollbar) { size = that[dir + 'ScrollbarIndicatorSize'] + m.round(pos * 3); if (size < 8) size = 8; that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px'; } pos = 0; } else if (pos > that[dir + 'ScrollbarMaxScroll']) { if (!that.options.fixedScrollbar) { size = that[dir + 'ScrollbarIndicatorSize'] - m.round((pos - that[dir + 'ScrollbarMaxScroll']) * 3); if (size < 8) size = 8; that[dir + 'ScrollbarIndicator'].style[dir == 'h' ? 'width' : 'height'] = size + 'px'; pos = that[dir + 'ScrollbarMaxScroll'] + (that[dir + 'ScrollbarIndicatorSize'] - size); } else { pos = that[dir + 'ScrollbarMaxScroll']; } } that[dir + 'ScrollbarWrapper'].style[transitionDelay] = '0'; that[dir + 'ScrollbarWrapper'].style.opacity = hidden && that.options.hideScrollbar ? '0' : '1'; that[dir + 'ScrollbarIndicator'].style[transform] = 'translate(' + (dir == 'h' ? pos + 'px,0)' : '0,' + pos + 'px)') + translateZ; }, _start: function (e) { var that = this, point = hasTouch ? e.touches[0] : e, matrix, x, y, c1, c2; if (!that.enabled) return; if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e); if (that.options.useTransition || that.options.zoom) that._transitionTime(0); that.moved = false; that.animating = false; that.zoomed = false; that.distX = 0; that.distY = 0; that.absDistX = 0; that.absDistY = 0; that.dirX = 0; that.dirY = 0; // Gesture start if (that.options.zoom && hasTouch && e.touches.length > 1) { c1 = m.abs(e.touches[0].pageX-e.touches[1].pageX); c2 = m.abs(e.touches[0].pageY-e.touches[1].pageY); that.touchesDistStart = m.sqrt(c1 * c1 + c2 * c2); that.originX = m.abs(e.touches[0].pageX + e.touches[1].pageX - that.wrapperOffsetLeft * 2) / 2 - that.x; that.originY = m.abs(e.touches[0].pageY + e.touches[1].pageY - that.wrapperOffsetTop * 2) / 2 - that.y; if (that.options.onZoomStart) that.options.onZoomStart.call(that, e); } if (that.options.momentum) { if (that.options.useTransform) { // Very lame general purpose alternative to CSSMatrix matrix = getComputedStyle(that.scroller, null)[transform].replace(/[^0-9\-.,]/g, '').split(','); x = +(matrix[12] || matrix[4]); y = +(matrix[13] || matrix[5]); } else { x = +getComputedStyle(that.scroller, null).left.replace(/[^0-9-]/g, ''); y = +getComputedStyle(that.scroller, null).top.replace(/[^0-9-]/g, ''); } if (x != that.x || y != that.y) { if (that.options.useTransition) that._unbind(TRNEND_EV); else cancelFrame(that.aniTime); that.steps = []; that._pos(x, y); if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); } } that.absStartX = that.x; // Needed by snap threshold that.absStartY = that.y; that.startX = that.x; that.startY = that.y; that.pointX = point.pageX; that.pointY = point.pageY; that.startTime = e.timeStamp || Date.now(); if (that.options.onScrollStart) that.options.onScrollStart.call(that, e); that._bind(MOVE_EV, window); that._bind(END_EV, window); that._bind(CANCEL_EV, window); }, _move: function (e) { var that = this, point = hasTouch ? e.touches[0] : e, deltaX = point.pageX - that.pointX, deltaY = point.pageY - that.pointY, newX = that.x + deltaX, newY = that.y + deltaY, c1, c2, scale, timestamp = e.timeStamp || Date.now(); if (that.options.onBeforeScrollMove) that.options.onBeforeScrollMove.call(that, e); // Zoom if (that.options.zoom && hasTouch && e.touches.length > 1) { c1 = m.abs(e.touches[0].pageX - e.touches[1].pageX); c2 = m.abs(e.touches[0].pageY - e.touches[1].pageY); that.touchesDist = m.sqrt(c1*c1+c2*c2); that.zoomed = true; scale = 1 / that.touchesDistStart * that.touchesDist * this.scale; if (scale < that.options.zoomMin) scale = 0.5 * that.options.zoomMin * Math.pow(2.0, scale / that.options.zoomMin); else if (scale > that.options.zoomMax) scale = 2.0 * that.options.zoomMax * Math.pow(0.5, that.options.zoomMax / scale); that.lastScale = scale / this.scale; newX = this.originX - this.originX * that.lastScale + this.x, newY = this.originY - this.originY * that.lastScale + this.y; this.scroller.style[transform] = 'translate(' + newX + 'px,' + newY + 'px) scale(' + scale + ')' + translateZ; if (that.options.onZoom) that.options.onZoom.call(that, e); return; } that.pointX = point.pageX; that.pointY = point.pageY; // Slow down if outside of the boundaries if (newX > 0 || newX < that.maxScrollX) { newX = that.options.bounce ? that.x + (deltaX / 2) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX; } if (newY > that.minScrollY || newY < that.maxScrollY) { newY = that.options.bounce ? that.y + (deltaY / 2) : newY >= that.minScrollY || that.maxScrollY >= 0 ? that.minScrollY : that.maxScrollY; } that.distX += deltaX; that.distY += deltaY; that.absDistX = m.abs(that.distX); that.absDistY = m.abs(that.distY); if (that.absDistX < 6 && that.absDistY < 6) { return; } // Lock direction if (that.options.lockDirection) { if (that.absDistX > that.absDistY + 5) { newY = that.y; deltaY = 0; } else if (that.absDistY > that.absDistX + 5) { newX = that.x; deltaX = 0; } } that.moved = true; that._pos(newX, newY); that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; if (timestamp - that.startTime > 300) { that.startTime = timestamp; that.startX = that.x; that.startY = that.y; } if (that.options.onScrollMove) that.options.onScrollMove.call(that, e); }, _end: function (e) { if (hasTouch && e.touches.length !== 0) return; var that = this, point = hasTouch ? e.changedTouches[0] : e, target, ev, momentumX = { dist:0, time:0 }, momentumY = { dist:0, time:0 }, duration = (e.timeStamp || Date.now()) - that.startTime, newPosX = that.x, newPosY = that.y, distX, distY, newDuration, snap, scale; that._unbind(MOVE_EV, window); that._unbind(END_EV, window); that._unbind(CANCEL_EV, window); if (that.options.onBeforeScrollEnd) that.options.onBeforeScrollEnd.call(that, e); if (that.zoomed) { scale = that.scale * that.lastScale; scale = Math.max(that.options.zoomMin, scale); scale = Math.min(that.options.zoomMax, scale); that.lastScale = scale / that.scale; that.scale = scale; that.x = that.originX - that.originX * that.lastScale + that.x; that.y = that.originY - that.originY * that.lastScale + that.y; that.scroller.style[transitionDuration] = '200ms'; that.scroller.style[transform] = 'translate(' + that.x + 'px,' + that.y + 'px) scale(' + that.scale + ')' + translateZ; that.zoomed = false; that.refresh(); if (that.options.onZoomEnd) that.options.onZoomEnd.call(that, e); return; } if (!that.moved) { if (hasTouch) { if (that.doubleTapTimer && that.options.zoom) { // Double tapped clearTimeout(that.doubleTapTimer); that.doubleTapTimer = null; if (that.options.onZoomStart) that.options.onZoomStart.call(that, e); that.zoom(that.pointX, that.pointY, that.scale == 1 ? that.options.doubleTapZoom : 1); if (that.options.onZoomEnd) { setTimeout(function() { that.options.onZoomEnd.call(that, e); }, 200); // 200 is default zoom duration } } else if (this.options.handleClick) { that.doubleTapTimer = setTimeout(function () { that.doubleTapTimer = null; // Find the last touched element target = point.target; while (target.nodeType != 1) target = target.parentNode; if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') { ev = doc.createEvent('MouseEvents'); ev.initMouseEvent('click', true, true, e.view, 1, point.screenX, point.screenY, point.clientX, point.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 0, null); ev._fake = true; target.dispatchEvent(ev); } }, that.options.zoom ? 250 : 0); } } that._resetPos(400); if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); return; } if (duration < 300 && that.options.momentum) { momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX; momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y - that.minScrollY : 0), that.options.bounce ? that.wrapperH : 0) : momentumY; newPosX = that.x + momentumX.dist; newPosY = that.y + momentumY.dist; if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist:0, time:0 }; if ((that.y > that.minScrollY && newPosY > that.minScrollY) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist:0, time:0 }; } if (momentumX.dist || momentumY.dist) { newDuration = m.max(m.max(momentumX.time, momentumY.time), 10); // Do we need to snap? if (that.options.snap) { distX = newPosX - that.absStartX; distY = newPosY - that.absStartY; if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) { that.scrollTo(that.absStartX, that.absStartY, 200); } else { snap = that._snap(newPosX, newPosY); newPosX = snap.x; newPosY = snap.y; newDuration = m.max(snap.time, newDuration); } } that.scrollTo(m.round(newPosX), m.round(newPosY), newDuration); if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); return; } // Do we need to snap? if (that.options.snap) { distX = newPosX - that.absStartX; distY = newPosY - that.absStartY; if (m.abs(distX) < that.options.snapThreshold && m.abs(distY) < that.options.snapThreshold) that.scrollTo(that.absStartX, that.absStartY, 200); else { snap = that._snap(that.x, that.y); if (snap.x != that.x || snap.y != that.y) that.scrollTo(snap.x, snap.y, snap.time); } if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); return; } that._resetPos(200); if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e); }, _resetPos: function (time) { var that = this, resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x, resetY = that.y >= that.minScrollY || that.maxScrollY > 0 ? that.minScrollY : that.y < that.maxScrollY ? that.maxScrollY : that.y; if (resetX == that.x && resetY == that.y) { if (that.moved) { that.moved = false; if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); // Execute custom code on scroll end } if (that.hScrollbar && that.options.hideScrollbar) { if (vendor == 'webkit') that.hScrollbarWrapper.style[transitionDelay] = '300ms'; that.hScrollbarWrapper.style.opacity = '0'; } if (that.vScrollbar && that.options.hideScrollbar) { if (vendor == 'webkit') that.vScrollbarWrapper.style[transitionDelay] = '300ms'; that.vScrollbarWrapper.style.opacity = '0'; } return; } that.scrollTo(resetX, resetY, time || 0); }, _wheel: function (e) { var that = this, wheelDeltaX, wheelDeltaY, deltaX, deltaY, deltaScale; if ('wheelDeltaX' in e) { wheelDeltaX = e.wheelDeltaX / 12; wheelDeltaY = e.wheelDeltaY / 12; } else if('wheelDelta' in e) { wheelDeltaX = wheelDeltaY = e.wheelDelta / 12; } else if ('detail' in e) { wheelDeltaX = wheelDeltaY = -e.detail * 3; } else { return; } if (that.options.wheelAction == 'zoom') { deltaScale = that.scale * Math.pow(2, 1/3 * (wheelDeltaY ? wheelDeltaY / Math.abs(wheelDeltaY) : 0)); if (deltaScale < that.options.zoomMin) deltaScale = that.options.zoomMin; if (deltaScale > that.options.zoomMax) deltaScale = that.options.zoomMax; if (deltaScale != that.scale) { if (!that.wheelZoomCount && that.options.onZoomStart) that.options.onZoomStart.call(that, e); that.wheelZoomCount++; that.zoom(e.pageX, e.pageY, deltaScale, 400); setTimeout(function() { that.wheelZoomCount--; if (!that.wheelZoomCount && that.options.onZoomEnd) that.options.onZoomEnd.call(that, e); }, 400); } return; } deltaX = that.x + wheelDeltaX; deltaY = that.y + wheelDeltaY; if (deltaX > 0) deltaX = 0; else if (deltaX < that.maxScrollX) deltaX = that.maxScrollX; if (deltaY > that.minScrollY) deltaY = that.minScrollY; else if (deltaY < that.maxScrollY) deltaY = that.maxScrollY; if (that.maxScrollY < 0) { that.scrollTo(deltaX, deltaY, 0); } }, _transitionEnd: function (e) { var that = this; if (e.target != that.scroller) return; that._unbind(TRNEND_EV); that._startAni(); }, /** * * Utilities * */ _startAni: function () { var that = this, startX = that.x, startY = that.y, startTime = Date.now(), step, easeOut, animate; if (that.animating) return; if (!that.steps.length) { that._resetPos(400); return; } step = that.steps.shift(); if (step.x == startX && step.y == startY) step.time = 0; that.animating = true; that.moved = true; if (that.options.useTransition) { that._transitionTime(step.time); that._pos(step.x, step.y); that.animating = false; if (step.time) that._bind(TRNEND_EV); else that._resetPos(0); return; } animate = function () { var now = Date.now(), newX, newY; if (now >= startTime + step.time) { that._pos(step.x, step.y); that.animating = false; if (that.options.onAnimationEnd) that.options.onAnimationEnd.call(that); // Execute custom code on animation end that._startAni(); return; } now = (now - startTime) / step.time - 1; easeOut = m.sqrt(1 - now * now); newX = (step.x - startX) * easeOut + startX; newY = (step.y - startY) * easeOut + startY; that._pos(newX, newY); if (that.animating) that.aniTime = nextFrame(animate); }; animate(); }, _transitionTime: function (time) { time += 'ms'; this.scroller.style[transitionDuration] = time; if (this.hScrollbar) this.hScrollbarIndicator.style[transitionDuration] = time; if (this.vScrollbar) this.vScrollbarIndicator.style[transitionDuration] = time; }, _momentum: function (dist, time, maxDistUpper, maxDistLower, size) { var deceleration = 0.0006, speed = m.abs(dist) / time, newDist = (speed * speed) / (2 * deceleration), newTime = 0, outsideDist = 0; // Proportinally reduce speed if we are outside of the boundaries if (dist > 0 && newDist > maxDistUpper) { outsideDist = size / (6 / (newDist / speed * deceleration)); maxDistUpper = maxDistUpper + outsideDist; speed = speed * maxDistUpper / newDist; newDist = maxDistUpper; } else if (dist < 0 && newDist > maxDistLower) { outsideDist = size / (6 / (newDist / speed * deceleration)); maxDistLower = maxDistLower + outsideDist; speed = speed * maxDistLower / newDist; newDist = maxDistLower; } newDist = newDist * (dist < 0 ? -1 : 1); newTime = speed / deceleration; return { dist: newDist, time: m.round(newTime) }; }, _offset: function (el) { var left = -el.offsetLeft, top = -el.offsetTop; while (el = el.offsetParent) { left -= el.offsetLeft; top -= el.offsetTop; } if (el != this.wrapper) { left *= this.scale; top *= this.scale; } return { left: left, top: top }; }, _snap: function (x, y) { var that = this, i, l, page, time, sizeX, sizeY; // Check page X page = that.pagesX.length - 1; for (i=0, l=that.pagesX.length; i<l; i++) { if (x >= that.pagesX[i]) { page = i; break; } } if (page == that.currPageX && page > 0 && that.dirX < 0) page--; x = that.pagesX <div class="pagenum tc">当前1/5页 <strong>1</strong> <a href="80039_2.htm">2</a> <a href="80039_3.htm">3</a> <a href="80039_4.htm">4</a> <a href="80039_5.htm">5</a> <a href="80039_2.htm">下一页</a> <a href="80039_all.htm">阅读全文</a> </div>
The above is the jQuery iScroll.js mobile scroll bar beautification plug-in No. 1/ 5 pages of jquery content. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!

C and JavaScript achieve interoperability through WebAssembly. 1) C code is compiled into WebAssembly module and introduced into JavaScript environment to enhance computing power. 2) In game development, C handles physics engines and graphics rendering, and JavaScript is responsible for game logic and user interface.

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Atom editor mac version download
The most popular open source editor

Dreamweaver Mac version
Visual web development tools

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function