Javascript simulates the html element scroll bar jscroll

Source: Internet
Author: User

By default, the scroll bars provided by mainstream browsers for html elements are not beautiful, and front-end developers want to beautify them with a uniform style through css. For example, ie can achieve simple beautification through styles. The Webkit kernel browser can control the Display Effect of the scroll bar, while firefox does not allow users to define styles for the scroll bar. However, front-end developers pursuing friendly user experience will not be blocked by inconsistent behaviors of these browsers. We can implement custom scroll bars through standard html element simulation.

Here, I wrote a user-defined scroll bar jscroll when I was not busy with my work. By default, jscroll provides only one scroll bar style. Some styles come from google webstore. Some css3 styles are mainly used to achieve rounded corners and shadow effects. To achieve consistent display of the scroll bar across browsers, the PIE. htc file is introduced in browsers that do not support CSS 3 for ie6, 7, and 8. The following describes the functions, compatibility, usage, and code implementation.

Functions and compatibility

Jscroll implements almost all functions of the system's default scroll bar, such: drag the scroll bar to view the content, scroll the scroll wheel to view the content, click the scroll bar to reach the top or bottom of the area to trigger the scroll bar scroll, keyboard up and down keys to trigger the scroll bar scroll. The latest browsers such as firefox, chrome, and ie9 + support the latest APIs of css3 and js, so there is no compatibility problem. Ie6, 7, and 8 do not support css3 compatibility by introducing the hack file of PIE. htc. Js is compatible with unsupported APIs through old APIs. Ie6 is the browser with the biggest compatibility problem. You cannot click the scroll bar to reach the area to trigger scroll bar, or use the upper or lower keys on the keyboard to trigger scroll of the scroll bar. This problem is mainly caused by the introduction of PIE that supports css3. if the hack file is not introduced to the htc file, all operations are supported. To ensure the consistency of the display effect, you have to choose not to support some features.

Usage

The most commonly used custom scroll bars are the page pop-up layer or an area on the page. Do not customize the scroll bars of the whole page. For elements that need to use jscroll, you need to add the custom attribute data-scroll = "true" to tell the program to use jscroll to replace the default system scroll bar, you also need to add custom properties data-width = "", data-height = "" to specify the width and height of the element to be displayed. Jscroll calculates the display width of the content and the height of the scroll bar based on the user-defined width and height, and adds interactive events.

Code Implementation

The implementation logic of jscroll is not complex. The js Code that implements specific functions is less than 400 lines, but it relies on some basic methods. Therefore, squid. js needs to be introduced as the basic method support. CSS for control of the scroll style is in a single jscroll-1.0.css file. You can modify and expand the file to meet your needs. The following is a simple analysis of each method to implement specific functions:

Init: function (selector, context ){
Selecotr = selector | 'data-scroll'
Context = context | document

Var elems = squid. getElementsByAttribute (selector, context)
This. initView (elems)
}

Init () is the initialization function. It obtains the elements that need to use a custom scroll bar based on the specified selector and context. selector is data-scroll by default, and the context is the current document by default. Here, no matter the custom attribute data-scroll = "true" or data-scroll = "false" of the element, the system uses the custom scroll bar to overwrite the default scroll bar of the system. The getElementsByAttribute () of squid () the method only provides the ability to search for elements and ignore attribute values by checking whether the element has a specified attribute. This method is not as powerful as the querySelectorAll () method provided by the jquery selector or advanced browser, because squid is only the most basic support. Find the element for customizing the scroll bar and call the initView method to initialize the overall structure and display of the scroll bar.

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 traverses the data-scroll element obtained on the page and determines whether a scroll bar appears for each element. It is determined by the hasScroll () method. If the element contains a scroll bar, call the create () method to create a custom scroll bar. After the initView () method ends, the initEvent () method is called.

// Whether a scroll bar exists
HasScroll: function (elem ){
Return elem. offsetHeight <elem. scrollHeight
}

The hasScroll () method is used to determine whether the element has a scroll bar and returns true or false. Here, the margin and padding of the element are ignored. By default, the default value of margin and padding for the scroll bar created through jscroll is 0.

// Create the overall structure of the scroll bar element
Create: function (elem ){
Var wrapper,
List,
// Scroll bar element
S,
// Height of the element with a scroll bar
Height = elem ['data-height'] | elem. getAttribute ('data-height '),
// Display width of the element with a scroll bar
Width = elem ['data-width'] | elem. getAttribute ('data-width '),
// The height of the scroll bar.
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'
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 ('hidefo', true)

List. appendChild (s)
Wrapper. appendChild (list)
// Wrap the elements that require a 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 allows you to adjust the overall structure of elements with custom scroll bars. First, you can create a wrapper element, it is used to wrap the elem element that will display the scroll bar, the list of area elements that can be rolled by the scroll bar, and the s element of the scroll bar. You can set the width and height of the wrapper element from the custom properties data-width and data-height set by the scroll bar element. The height displayed by the scroll bar element is calculated using the scrollbarHeight () method. The overall structure is not complex. After creating the overall structure of the custom scroll bar, add event processing for the scroll bar element s and the scroll bar to the area element list, which is implemented through the regEvent () method.

// Calculate the height of the scroll bar
ScrollbarHeight: function (elem, height ){
Var value = elem. scrollHeight;

Return (height/value) * height
}

The scrollbarHeight () method returns the height that the scroll bar element should display through a simple mathematical calculation.

InitEvent: function (){
Var that = this,
_ Default,
Elem,
Top,
Min,
Max,
Prev,
Parent,
Sbody,
Unit;

// Scroll bar
Squid. on (document, 'mousemove ', function (event ){
Elem = that. scrolling. elem
If (elem! = Null ){
Squid. addClass (elem, 'rolling ')
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. previussibling
Sbody = prev. tagName. toLowerCase () = 'div '? Prev: prev. previussibling
_ 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)
}
})

// Rolling ends
Squid. on (document, 'mouseup', function (event ){
Elem = that. scrolling. elem
If (elem ){
Prev = that. ie6? Elem. parentNode. parentNode. previussibling: elem. parentNode. previussibling
Sbody = prev. tagName. toLowerCase () = 'div '? Prev: prev. previussibling
Squid. removeClass (sbody. parentNode, 'unselectable ')
}

That. scrolling. elem = null
That. scrolling. diffy = 0
})
}

The initEvent () method adds the mousemove and mouseup events to the document element. The mousemove method follows the changes in the content viewed when the scroll bar element is dragged. The code first checks whether a scroll bar is being dragged to view the content. If yes, it calculates the position where the scroll bar is dragged, and then calculates where the view content should be. The judgment on ie6 in the Code is because the introduced PIE. htc file breaks the original structure (too much for cross-browser display effect consistency !!!). The mouseup event handler clears the scroll bar elements of the previous operation.

// Add a scroll bar event
RegEvent: function (elem ){
Var that = this,
Sbody = elem. firstChild,
List = sbody. nextSibling,
// Scroll bar element
S = list. firstChild,
// Minimum value of scroll bar
Min = 0,
// Maximum scroll value of the scroll bar
Max = list. offsetHeight-s. offsetHeight,
_ Default = parseInt (sbody ['data-height'] | sbody. getAttribute ('data-height'), 10 ),
Unit = (sbody. scrollHeight-_ default)/max,
// Firefox
Firefox = 'external binding 'in document.doc umentElement. style,
// Scroll wheel event
Mousewheel = firefox? 'Dommousescroll': 'mousewheel ',
// Operabrowser
Opera = window. oprea & navigator. userAgent. indexOf ('msie ') ===-1,
// Is firing mousedown event
Firing = false,
// Click the mouse to display the timer execution time
Interval,
// The height of the scroll bar from the container
Top,
// The current top value of the scroll bar
Cur,
// How many pixels each scroll
Speed = 18;

// Variable cache min, max
This. limits [s] = {
Min: 0,
Max: max
}
// Scroll event move scroll bar with mouse sliding
Squid. on (elem, mousewheel, function (event ){
Var delta;

If (event. wheelDelta ){
Delta = opera? -Event. Maid/120: event. Maid/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)

// Prevents scroll of the body element
Event. preventDefault ()
})

// Ie6, 7, and 8. If the mouse clicks twice consecutively and the interval is too short, the second event will not be triggered.
// Drag the scroll bar and click the scroll bar to reach the area.
Squid. on (list, 'mousedown ', function (event ){
Var target = event.tar get,
Y = event. clientY;

Target = event.tar get
If (target. tagName. toLowerCase () = 'shape ')
Target = s

// The Mouse clicking element is a 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 moving the mouse.
That. scrolling. elem = s
} Else if (target. className. match ('jscroll-list ')){
Firing = true
Interval = setInterval (function (){
If (firing ){
That. mouseHandle (list, y, unit)
}
}, 80)
}
})

// Release the scroll bar to stop scrolling.
Squid. on (list, 'mouseup', function (){
// Invoke elem releaseCapture
S. releaseCapture & s. releaseCapture ()

Firing = false
ClearInterval (interval)
})

// The scroll bar element obtains the focus and triggers the keyup event.
Squid. on (s, 'click', function (){
This. focus ()
})

// When the scroll bar gets the focus, the keyboard upper and lower keys are triggered and the scroll bar is rolled.
Squid. on (s, 'keylow', 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 ()
})
}

  • Three pages in total:
  • Previous Page
  • 1
  • 2
  • 3
  • Next Page

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.