Mainstream browsers default to the HTML elements provided by the scroll bar is not beautiful, and the front-end developers want to their CSS through the unified style of beautification is also not achievable. For example, IE can be achieved by the style of simple landscaping, WebKit kernel browser can control the display of scrollbars, Firefox does not allow users to define the style of the scroll bar. But the front-end developers who pursue a friendly user experience are not blocked by the inconsistent behavior of these browsers. We can implement custom scroll bars ourselves through standard HTML element simulations.
This is what you write when you're not busy at work. A user can customize the scroll bar Jscroll, hereinafter referred to as Jscroll. Jscroll default provides only one scroll bar style, some of which are from Google Webstore, and some CSS3 styles are mainly used to achieve rounded corners and shadow effects. To achieve consistency in the display of scroll bars across browsers, PIE.HTC files are introduced for IE6, 7, 8 browsers that do not support CSS3. Below on the implementation of the features and compatibility, the use of methods, specific code implementation to do a tutorial.
Implementing Functionality and compatibility
Jscroll implements almost all the features of the system's default scroll bar, such as dragging the scroll bar to view content, scrolling the mouse wheel to view the content, clicking on the scroll bar to reach the top or bottom of the area to trigger the scroll bar scrolling, keyboard up and down keys to trigger the scroll bar scroll. Firefox, Chrome, ie9+ and other latest browsers support CSS3 and JS's latest APIs, so there is no compatibility issue. IE6, 7, 8 does not support CSS3 by introducing PIE.HTC hack files for compatibility processing. JS aspect for unsupported APIs through the old API to do the compatibility. The browser with the maximum compatibility problem is IE6 and does not support clicking on the scroll bar to reach the area to trigger the scroll bar scrolling, nor does it support the keyboard up and down keys to trigger scroll bar scrolling. The cause of this problem is mainly because of the introduction of the PIE.HTC file supporting CSS3, if the hack file is not introduced, all operations can support, unable to do in order to show the consistency of the results, had to choose not to support part of the function.
How to use
The most common use of a custom scroll bar should be the page pop-up layer, or an area on the page, and never customize the scroll bar for the entire page. For elements that require the use of jscroll, you need to add a custom attribute data-scroll= "True" to tell the program to use Jscroll to replace the system default scroll bar, and also to add custom attributes Data-width= "", Data-height= "" To specify the width and height of the element to display. Jscroll calculates the display width of the content and the height of the scroll bar and adds interactive events based on the user-defined width and height.
Specific code implementation
Jscroll implementation logic is not complex, the implementation of the specific functions of the JS code less than 400 lines, but here rely on some basic methods, so need to introduce squid.js as a basic method of support. CSS for the control of the scrollbar style in a separate jscroll-1.0.css file, the user can modify the extension to meet their own needs. Here is a simple analysis of each method that implements the specific functionality:
Copy Code code as follows:
Init:function (Selector, context) {
SELECOTR = Selector | | ' Data-scroll '
Context = Context | | Document
var elems = Squid.getelementsbyattribute (selector, context)
This.initview (Elems)
}
Init () is an initialization function that obtains the elements that require the use of a custom scrollbar according to the specified selector and context, selector default is Data-scroll, which is the current document by default. Here regardless of element custom property data-scroll= "True" or data-scroll= "false" will overwrite the system default scroll bar with the custom scroll bar, squid's Getelementsbyattribute () Method simply provides a way to find elements by whether they have a specified attribute and ignores property values, which is not as powerful as the jquery selector or the Queryselectorall () method provided by the advanced browser, because squid here is only the most basic support. Call the Initview method after you find the element that needs to customize the scroll bar to initialize the scroll bar's overall structure and display.
Copy Code code as follows:
Initview:function (Elems) {
var i = 0,
Length = Elems.length,
Elem
for (; i < length; i++) {
Elem = Elems[i]
if (This.hasscroll (Elem)) {
This.create (Elem)
}
}
This.initevent ()
}
The Initview () method first iterates through the elements obtained on the page with the custom attribute Data-scroll, determining whether each element will have a scrollbar, which is judged by the Hasscroll () method. If the element appears in a scroll bar, call the Create () method to create a custom scroll bar, respectively. The Initevent () method is called at the end of the Initview () method.
Copy Code code as follows:
Is there a scroll bar
Hasscroll:function (elem) {
Return Elem.offsetheight < Elem.scrollheight
}
The Hasscroll () method is used to determine whether the element will have scroll bars, return True or false. This ignores the margin and padding of the elements, and the default margin and padding of the scroll bars created by Jscroll are 0.
Copy Code code as follows:
Create a scroll bar element overall structure
Create:function (elem) {
var wrapper,
List
scroll bar Element
S
Height with scroll bar element display
Height = elem[' data-height '] | | Elem.getattribute (' Data-height '),
Width with scroll bar element display
width = elem[' data-width '] | | Elem.getattribute (' Data-width '),
scroll bar Display Height
Value
Wrapper
wrapper = document.createelement (' div ')
Wrapper.classname = ' Jscroll-wrapper '
Forbid select text, for IE9
/*
* Wrapper.onselectstart = function () {
* Return False
* }
*/
Squid.css (Wrapper, {
Height:height + ' px ',
Width:width + ' px '
})
Squid.addclass (Elem, ' jscroll-body ')
Overwrite the user define style
Squid.css (Elem, {
Overflow: ' Visible ',
Position: ' Absolute ',
Height: ' Auto ',
Width: (width-40) + ' px ',
padding: ' 0 20px 0 23px '
})
List
List = document.createelement (' div ')
List.classname = ' jscroll-list unselectable ' <BR> list.unselectable = ' on '
Squid.css (list, {
Height: (height-5) + ' px '
})
scroll bar
s = document.createelement (' div ')
S.classname = ' Jscroll-drag unselectable '
s.unselectable = ' on '
S.setattribute (' TabIndex ', ' 1 ')
S.setattribute (' Hidefocus ', true)
List.appendchild (s)
Wrapper.appendchild (list)
Wrap the elements that need to appear in the scroll bar
Elem.parentNode.replaceChild (wrapper, Elem)
Wrapper.insertbefore (Elem, list)
scroll bar height
Value = This.scrollbarheight (elem, height)
Squid.css (S, {
Height:value + ' px '
})
Add Event
This.regevent (wrapper)
}
The Create () method user adjusts the creation of an element's overall structure with a custom scrollbar, first by creating a wrapper element that wraps the element list of elements elem and scrollbars that will appear in the scroll bar, and the scroll bar element s. Sets the width and height of the wrapper element, respectively, from the custom properties Data-width and data-height that appear in the scroll bar element. The Scrollbarheight () method is used to calculate the height of the scroll bar element and the overall structure is not complicated. After you create a custom scrollbar overall structure, you add event handling for the scroll bar elements s and scroll bars to the AREA element list, which is implemented by the Regevent () method.
Copy Code code as follows:
Calculate the height of a scroll bar
Scrollbarheight:function (elem, height) {
var value = Elem.scrollheight;
Return (height/value) * height
}
The Scrollbarheight () method returns the height that the scrollbar element should display by simple mathematical calculations.
Copy Code code as follows:
Initevent:function () {
var that = this,
_default,
Elem
Top
Min
Max
Prev
Parent
Sbody,
Unit
scroll bar scrolling
Squid.on (document, ' MouseMove ', function (event) {
Elem = That.scrolling.elem
if (elem!== null) {
Squid.addclass (Elem, ' scrolling ')
top = Event.clienty-that.scrolling.diffy
Parent = That.ie6? Elem.parentNode.parentNode:elem.parentNode
Min = that.limits[elem].min
max = That.limits[elem].max
Prev = parent.previoussibling
Sbody = prev.tagName.toLowerCase () = = ' div '? Prev:prev.previousSibling
_default = parseint (sbody[' data-height ') | | sbody.getattribute (' data-height '), 10)
Unit = (Sbody.scrollheight-_default)/MAX
Squid.addclass (Sbody.parentnode, ' unselectable ')
if (Top < min) {
top = min
}else if (Top > Max) {
top = max
}
Elem.style.top = top + ' px '
That.doscroll (sbody, top * unit)
}
})
Scroll End
Squid.on (document, ' MouseUp ', function (event) {
Elem = That.scrolling.elem
if (elem) {
Prev = that.ie6? Elem.parentNode.parentNode.previousSibling:elem.parentNode.previousSibling
Sbody = prev.tagName.toLowerCase () = = ' div '? Prev:prev.previousSibling
Squid.removeclass (Sbody.parentnode, ' unselectable ')
}
That.scrolling.elem = null
That.scrolling.diffy = 0
})
}
The Initevent () method enables you to add MouseMove and MouseUp events to the document element, MouseMove implements the changes that are viewed when you drag a scrollbar element to scroll. The code first determines whether there is an action to view the content by dragging the scroll bar, and if so, calculates where the scroll bar is dragged, and then calculates where to view the content. The IE6 in the code is due to the introduction of PIE.HTC files that destroy the original structure (in order to achieve a cross-browser display effect of the same, pay too much!!! )。 The MouseUp event handler implements the scroll bar element that clears the last action.
Copy Code code as follows:
Add scroll bar Event
Regevent:function (elem) {
var that = this,
Sbody = Elem.firstchild,
List = sbody.nextsibling,
scroll bar Element
s = list.firstchild,
Scroll bar Scrolling Minimum value
Min = 0,
Scroll bar Scroll Maximum value
max = List.offsetheight-s.offsetheight,
_default = parseint (sbody[' data-height ') | | sbody.getattribute (' data-height '), 10),
Unit = (Sbody.scrollheight-_default)/MAX,
Firefox browser
Firefox = ' mozbinding ' in Document.documentElement.style,
Mouse Wheel Event
MouseWheel = firefox? ' Dommousescroll ': ' MouseWheel ',
Opera browser
Opera = Window.oprea && navigator.userAgent.indexOf (' msie ') = = 1,
Is firing MouseDown event
Firing = False,
Mouse clicks, Timer execution time
Interval
scroll bar distance to container height
Top
Scroll bar Current top value
Cur
How many pixels per scroll
Speed = 18;
Variable cache min, max
This.limits[s] = {
min:0,
Max:max
}
Scroll event mouse Sliding wheel move scroll bar
Squid.on (Elem, MouseWheel, function (event) {
var Delta;
if (Event.wheeldelta) {
Delta = Opera? -event.wheeldelta/120:event.wheeldelta/120
}else{
Delta =-EVENT.DETAIL/3
}
cur = parseint (S.style.top | | 0, 10)
Scroll up
if (Delta > 0) {
top = Cur-speed
if (Top < min) {
top = min
}
}else{//Scroll down
top = cur + speed
if (Top > Max) {
top = max
}
}
S.style.top = top + ' px '
That.doscroll (sbody, top * unit)
Block the BODY element scroll bar from scrolling
Event.preventdefault ()
})
IE6, 7, 8, if the mouse clicks two consecutive times and the time interval is too short, the second event does not trigger
Drag the scroll bar and click on the scroll bar to reach the area
Squid.on (list, ' MouseDown ', function (event) {
var target = Event.target,
y = event.clienty;
target = Event.target
if (target.tagName.toLowerCase () = = = ' Shape ')
target = s
Mouse click element is scroll bar
if (target = = = s) {
Invoke Elem SetCapture
S.setcapture && s.setcapture ()
That.scrolling.diffy = Y-s.offsettop
Determines whether the scroll bar is being dragged while the mouse is moving
That.scrolling.elem = S
}else if (target.className.match (' jscroll-list ')) {
Firing = True
Interval = setinterval (function () {
if (firing) {
That.mousehandle (list, Y, unit)
}
}, 80)
}
})
Mouse release scroll bar stop scrolling
Squid.on (list, ' MouseUp ', function () {
Invoke Elem ReleaseCapture
S.releasecapture && s.releasecapture ()
Firing = False
Clearinterval (interval)
})
Scroll bar element gets focus, can trigger KeyUp event
Squid.on (S, ' click ', function () {
This.focus ()
})
When the scroll bar gets the focus, triggers the keyboard up and down key, and the scroll bar scrolls
Squid.on (S, ' KeyDown ', function (event) {
var keycode = Event.keycode,
state = false;
cur = parseint (S.style.top | | 0, 10)
Switch (keycode) {
Case 38:
top = Cur-speed
if (Top < min) {
top = min
}
State = True
Break
Case 40:
top = cur + speed
if (Top > Max) {
top = max
}
State = True
Break
Default
Break
}
if (state) {
S.style.top = top + ' px '
That.doscroll (sbody, top * unit)
}
Event.preventdefault ()
})
}
The Regevent () method implements the following functions, which should be the core approach to the Jscroll component:
1. Mouse in the area containing the scroll bar, scrolling up and down the mouse wheel, viewing the contents of the scroll wheel up and down function
2. Click on the scroll bar to reach the area, that is, above or below the scroll bar, scroll bars and the contents of the view scroll up or down. The mouse clicks the scroll bar to reach the area not to loosen, may continuously scroll the scroll bar and the view content, by calls the Mousehandle () method to implement this function concretely.
3. Click on the scroll bar element, you can use the keyboard up and down keys to trigger the scroll bar and view the contents of the scroll
Copy Code code as follows:
The scroll bar scrolls when the mouse clicks the scroll bar to reach the top or bottom of the area.
Mousehandle:function (Elem, place, unit) {
var prev = elem.previoussibling,
Contains scroll bar display content elements
A = prev.tagName.toLowerCase () = = ' div '? Prev:prev.previousSibling,
//
n = elem.firstchild,
scroll bar Element
s = this.ie6? N.lastchild:n.tagname.tolowercase () = = = ' div '? N:n.nextsibling,
scroll bar height
Height
list element from top value of body
Value
scroll bar distance to container height
Top
The top value of the scroll bar from the body
STop,
Scroll bar Scrolling Minimum value
Min
Scroll bar Scroll Maximum value
Max
Each click of the scroll bar to reach the area, the scroll bar down or up to move 10px
Step = 10,
Click the scroll bar to reach the top or bottom of the range is less than distance, the scroll bar can automatically move to the top or the lowest end
Distance = 20;
Min = this.limits[s].min
max = This.limits[s].max
Height = s.offsetheight
top = parseint (S.style.top | | 0, 10)
Value = Squid.getoffset (elem). Top
STop = Squid.getoffset (s). Top
Click below the scroll bar and scroll down
if (Place > STop) {
if (value + Elem.offsetheight-place < distance && (Elem.offsetheight-height-top) < distance) {
top = max
}else{
if ([STop + height + step] <= place) {
Top + = Step
}else{
top = Place-value-height
}
}
}else{
The scroll bar automatically scrolls to the top when the mouse clicks the area from the top of the scroll bar to the length of the scrollbar
if (Place-value < distance && Top < distance) {
top = min
}else{
Scroll bar from top height of page minus mouse Clienty value greater than step
if (stop-place >= step) {
Top-= Step
}else{
top = Place-value
}
}
}
if (Top < min) {
top = min
}else if (Top > Max) {
top = max
}
S.style.top = top + ' px '
This.doscroll (A, top * unit)
}
Mousehandle () method to determine the location of the mouse click position in the page coordinates, and the scroll bar element in the page position to judge whether the scroll bar is clicked on the upper area or the lower area. If you click on the area below the scroll bar scroll down, otherwise scroll up, the scroll bar automatically scrolls to the minimum or maximum value for the clicked position in the upper area or below the area below the distance value.
Display effects
The control's demo uses the Taobao User Registration protocol content, because Firefox, Chrome and other advanced browsers can guarantee good compatibility and display effect, so here only show IE low version browser display effect, ie browser screen screenshot as follows:
IE6 under
After initialization
In the process of scrolling
Scroll to bottom
Ie7
After the scroll bar is initialized
In the process of scrolling
Scroll to the bottom
Ie9
Before you start scrolling
In the process of scrolling
Scroll to the bottom
Summary : The basic function of the implementation of the code is so much, may not analyze the meticulous, which involves the most of the calculation of the position, the binding of the event processing. If you have any questions, you are welcome to communicate, learn and communicate with each other.
Note : The pie.htc file path should be correct, the reference written as an absolute path, otherwise IE6, 7, 8 without the CSS3 effect (if so I do in the code of the compatibility processing is meaningless!) , you can modify it in the Jscroll-1.0.css file if you need to change the reference path. Finally attach the source code, welcome to download the trial of interest.