webkit滚动条浅析

来源:互联网 发布:用手机发布淘宝宝贝 编辑:程序博客网 时间:2024/04/30 14:15

  基于chromium24所使用的webkit内核。废话不说直接上图


widget类可以理解为与平台有关的窗口小部件。可以看到它有3个子类,表示3种不同的窗口部件:ScrollView是用于正在显示网页内容的,PluginView是某些插件会用到的,Scrollbar就是滚动条。所以从widget这个角度来将,Scrollbar与FrameView应该是同一级别。ScrollView可以有孩子节点,而PluginView,Scrollbar则不能有孩子。

滚动条必须与一个滚动的区域(ScrollableArea)关联起来,这样才能起效果。可以看到ScrollView和RenderLayer都继承自ScrollableArea。这样对应着我们平时最常见的两种滚动条:一是网页全局的滚动条, 二是某一元素overflow属性所带的滚动条。这两种滚动条的创建,绘制及事件响应流程都不相同。

Scrollbar是一个基类,不同的平台可以继承该类,提供自己不同的实现。ScrollbarTheme定义了Scrollbar的风格,不同的实现可以来继承,真正的paint在该类中。

1. 网页全局滚动条

与Scrollbar相关联的ScrollableArea是FrameView。当网页内容的长度或者宽度超出viewport的时候,就需要创建滚动条了。

创建:

#0  WebCore::Scrollbar::createNativeScrollbar (scrollableArea=0x4c6a77fc, orientation=WebCore::VerticalScrollbar, size=WebCore::RegularScrollbar)
    at third_party/WebKit/Source/WebCore/platform/Scrollbar.cpp:56
#1  0x57f38588 in WebCore::ScrollView::createScrollbar (this=<optimized out>, orientation=<optimized out>) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:157
#2  0x580d0228 in WebCore::FrameView::createScrollbar (this=0x4c6a77d8, orientation=WebCore::VerticalScrollbar) at third_party/WebKit/Source/WebCore/page/FrameView.cpp:533
#3  0x57f39c7e in WebCore::ScrollView::setHasVerticalScrollbar (this=0x4c6a77d8, hasBar=<optimized out>) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:140
#4  0x57f39fe2 in updateScrollbars (desiredOffset=..., this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:579
#5  WebCore::ScrollView::updateScrollbars (this=0x4c6a77d8, desiredOffset=...) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:506
#6  0x57f3a526 in setContentsSize (newSize=..., this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:346
#7  WebCore::ScrollView::setContentsSize (this=0x4c6a77d8, newSize=...) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:335
#8  0x580d4618 in setContentsSize (size=..., this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/page/FrameView.cpp:543
#9  WebCore::FrameView::setContentsSize (this=0x4c6a77d8, size=...) at third_party/WebKit/Source/WebCore/page/FrameView.cpp:536
#10 0x580d09a4 in WebCore::FrameView::adjustViewSize (this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/page/FrameView.cpp:572
#11 0x580d3cb6 in layout (allowSubtree=<optimized out>, this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/page/FrameView.cpp:1201
#12 WebCore::FrameView::layout

滚动事件:

#0  WebCore::Scrollbar::offsetDidChange (this=0x4c420920) at third_party/WebKit/Source/WebCore/platform/Scrollbar.cpp:139
#1  0x57f3b12e in WebCore::ScrollableArea::scrollPositionChanged (this=0x4c6a77fc, position=<optimized out>) at third_party/WebKit/Source/WebCore/platform/ScrollableArea.cpp:186
#2  0x57f3716a in WebCore::ScrollAnimator::notifyPositionChanged (this=<optimized out>) at third_party/WebKit/Source/WebCore/platform/ScrollAnimator.cpp:149
#3  0x57f37142 in WebCore::ScrollAnimator::scrollToOffsetWithoutAnimation (this=<optimized out>, offset=<optimized out>) at third_party/WebKit/Source/WebCore/platform/ScrollAnimator.cpp:79
#4  0x57f3aee0 in WebCore::ScrollableArea::scrollToOffsetWithoutAnimation (this=<optimized out>, offset=...) at third_party/WebKit/Source/WebCore/platform/ScrollableArea.cpp:141
#5  0x57f3a330 in updateScrollbars (desiredOffset=..., this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:664
#6  WebCore::ScrollView::updateScrollbars (this=0x4c6a77d8, desiredOffset=...) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:506
#7  0x57f3a4ec in setScrollPosition (scrollPoint=<optimized out>, this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:461
#8  WebCore::ScrollView::setScrollPosition (this=0x4c6a77d8, scrollPoint=<optimized out>) at third_party/WebKit/Source/WebCore/platform/ScrollView.cpp:439
#9  0x580d1d4a in WebCore::FrameView::setScrollPosition (this=0x4c6a77d8, scrollPoint=...) at third_party/WebKit/Source/WebCore/page/FrameView.cpp:1774
#10 0x57c9b368 in scrollBy (s=<optimized out>, this=0x4c6a77d8) at third_party/WebKit/Source/WebCore/platform/ScrollView.h:190
#11 WebKit::WebViewImpl::applyScrollAndScale (this=0x59460a60, scrollDelta=<optimized out>, pageScaleDelta=1) at third_party/WebKit/Source/WebKit/chromium/src/WebViewImpl.cpp:4676
#12 0x58357928 in WebKit::WebLayerTreeViewImpl::applyScrollAndScale 


2. 元素overflow属性滚动条

当一个元素需要显示滚动条时,该元素的render节点(及其子节点)会被创建一个单独的RenderLayer,该RenderLayer就是Scrollbar相关联的ScrollableArea。


创建:

#0  WebCore::Scrollbar::createNativeScrollbar (scrollableArea=0x4c2c3484, orientation=WebCore::HorizontalScrollbar, size=WebCore::RegularScrollbar)
    at third_party/WebKit/Source/WebCore/platform/Scrollbar.cpp:56
#1  0x5814cd24 in WebCore::RenderLayer::createScrollbar (this=0x4c2c3484, orientation=WebCore::HorizontalScrollbar) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:2373
#2  0x5814cdc2 in WebCore::RenderLayer::setHasHorizontalScrollbar (this=<optimized out>, hasScrollbar=<optimized out>) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:2420
#3  0x5814ce88 in WebCore::RenderLayer::updateScrollbarsAfterStyleChange (this=0x4c2c3484, oldStyle=0x0) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:4895
#4  0x5814dcd0 in WebCore::RenderLayer::styleChanged (this=0x4c2c3484, oldStyle=0x0) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:4939
#5  0x58156396 in WebCore::RenderLayerModelObject::styleDidChange (this=0x4c2c3418, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0)
    at third_party/WebKit/Source/WebCore/rendering/RenderLayerModelObject.cpp:160
#6  0x5812e27c in WebCore::RenderBox::styleDidChange (this=0x4c2c3418, diff=<optimized out>, oldStyle=0x0) at third_party/WebKit/Source/WebCore/rendering/RenderBox.cpp:209
#7  0x58119128 in WebCore::RenderBlock::styleDidChange (this=0x4c2c3418, diff=WebCore::StyleDifferenceEqual, oldStyle=0x0) at third_party/WebKit/Source/WebCore/rendering/RenderBlock.cpp:327
#8  0x58164c6a in WebCore::RenderObject::setStyle (this=0x4c2c3418, style=<optimized out>) at third_party/WebKit/Source/WebCore/rendering/RenderObject.cpp:1786
#9  0x58163ffa in WebCore::RenderObject::setAnimatableStyle (this=0x4c2c3418, style=<optimized out>) at third_party/WebKit/Source/WebCore/rendering/RenderObject.cpp:1687
#10 0x57dc8fe8 in WebCore::NodeRendererFactory::createRenderer (this=0x58af740c) at third_party/WebKit/Source/WebCore/dom/NodeRenderingContext.cpp:219
#11 0x57dc90ac in WebCore::NodeRendererFactory::createRendererIfNeeded (this=0x58af740c) at third_party/WebKit/Source/WebCore/dom/NodeRenderingContext.cpp:252
#12 0x57dc4f24 in WebCore::Node::createRendererIfNeeded (this=<optimized out>) at third_party/WebKit/Source/WebCore/dom/Node.cpp:1411
#13 0x57db91ce in WebCore::Element::attach 


绘制:

#0  WebCore::Scrollbar::paint (this=0x4c17c450, context=0x58af6928, damageRect=...) at third_party/WebKit/Source/WebCore/platform/Scrollbar.cpp:191
#1  0x5814d6dc in WebCore::RenderLayer::paintOverflowControls (this=0x4c2c3484, context=0x58af6928, paintOffset=..., damageRect=..., paintingOverlayControls=true)
    at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:2767
#2  0x5814fb12 in WebCore::RenderLayer::paintLayerContents (this=0x4c2c3484, rootLayer=0x4c2c3104, context=0x58af6928, parentPaintDirtyRect=<optimized out>, subPixelAccumulation=..., paintBehavior=0, 
    paintingRoot=0x0, region=0x0, overlapTestRequests=0x0, paintFlags=245) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3338
#3  0x5814ff0e in WebCore::RenderLayer::paintLayer (this=0x4c2c3484, rootLayer=0x4c2c3104, context=0x58af6928, paintDirtyRect=..., subPixelAccumulation=..., paintBehavior=0, paintingRoot=0x0, region=0x0, 
    overlapTestRequests=0x0, paintFlags=245) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3132
#4  0x58150388 in paintList (paintFlags=<optimized out>, overlapTestRequests=<optimized out>, region=<optimized out>, paintingRoot=<optimized out>, paintBehavior=<optimized out>, 
    paintDirtyRect=<optimized out>, context=<optimized out>, rootLayer=<optimized out>, list=<optimized out>, this=<optimized out>) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3397
#5  WebCore::RenderLayer::paintList (this=0x4c2c3238, list=0x4c4c8358, rootLayer=0x4c2c3104, context=0x58af6928, paintDirtyRect=..., paintBehavior=0, paintingRoot=0x0, region=0x0, 
    overlapTestRequests=0x0, paintFlags=245) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3379
#6  0x5814fab6 in WebCore::RenderLayer::paintLayerContents (this=0x4c2c3238, rootLayer=0x4c2c3104, context=0x58af6928, parentPaintDirtyRect=<optimized out>, subPixelAccumulation=..., paintBehavior=0, 
    paintingRoot=0x0, region=0x0, overlapTestRequests=0x0, paintFlags=245) at third_party/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3330
#7  0x5814ff0e in WebCore::RenderLayer::paintLayer


滚动事件:

#0  WebCore::Scrollbar::offsetDidChange (this=0x4c3e6f48) at third_party/WebKit/Source/WebCore/platform/Scrollbar.cpp:139
#1  0x57f3b0e4 in WebCore::ScrollableArea::scrollPositionChanged (this=0x4c172484, position=...) at third_party/WebKit/Source/WebCore/platform/ScrollableArea.cpp:172
#2  0x57f3716a in WebCore::ScrollAnimator::notifyPositionChanged (this=<optimized out>) at third_party/WebKit/Source/WebCore/platform/ScrollAnimator.cpp:149
#3  0x57f37124 in WebCore::ScrollAnimator::scroll (this=0x4c38e158, orientation=<optimized out>, step=<optimized out>, multiplier=17) at third_party/WebKit/Source/WebCore/platform/ScrollAnimator.cpp:70
#4  0x57f3aeb6 in WebCore::ScrollableArea::scroll (this=<optimized out>, direction=<optimized out>, granularity=WebCore::ScrollByPixel, multiplier=17)
    at third_party/WebKit/Source/WebCore/platform/ScrollableArea.cpp:136
#5  0x58126a50 in WebCore::RenderBox::scroll (this=<optimized out>, direction=WebCore::ScrollDown, granularity=WebCore::ScrollByPixel, multiplier=17, stopNode=0x58af63ac)
    at third_party/WebKit/Source/WebCore/rendering/RenderBox.cpp:566
#6  0x580c7cd0 in scrollNode (stopNode=0x58af63ac, node=<optimized out>, negativeDirection=WebCore::ScrollDown, positiveDirection=WebCore::ScrollUp, granularity=WebCore::ScrollByPixel, delta=-17)
    at third_party/WebKit/Source/WebCore/page/EventHandler.cpp:271
#7  scrollNode (stopNode=0x58af63ac, node=<optimized out>, negativeDirection=WebCore::ScrollDown, positiveDirection=WebCore::ScrollUp, granularity=WebCore::ScrollByPixel, delta=-17)
    at third_party/WebKit/Source/WebCore/page/EventHandler.cpp:3862
#8  WebCore::EventHandler::defaultWheelEventHandler (this=0x4be646b8, startNode=<optimized out>, wheelEvent=0x4cac1550) at third_party/WebKit/Source/WebCore/page/EventHandler.cpp:2450
#9  0x57dc62f8 in defaultEventHandler (event=0x4cac1550, this=0x4c222b50) at third_party/WebKit/Source/WebCore/dom/Node.cpp:2737
#10 WebCore::Node::defaultEventHandler (this=0x4c222b50, event=0x4cac1550) at third_party/WebKit/Source/WebCore/dom/Node.cpp:2686
#11 0x57dbbd86 in WebCore::EventDispatcher::dispatchEventPostProcess (this=0x58af6460, event=..., preDispatchEventHandlerResult=0x0) at third_party/WebKit/Source/WebCore/dom/EventDispatcher.cpp:344
#12 0x57dbc346 in WebCore::EventDispatcher::dispatchEvent (this=0x58af6460, prpEvent=<optimized out>) at third_party/WebKit/Source/WebCore/dom/EventDispatcher.cpp:259
#13 0x57dbba0e in WebCore::EventDispatchMediator::dispatchEvent (this=<optimized out>, dispatcher=<optimized out>) at third_party/WebKit/Source/WebCore/dom/EventDispatchMediator.cpp:52
#14 0x57dd7f92 in WebCore::WheelEventDispatchMediator::dispatchEvent (this=0x4e0bf298, dispatcher=<optimized out>) at third_party/WebKit/Source/WebCore/dom/WheelEvent.cpp:132
#15 0x57dbbfb2 in WebCore::EventDispatcher::dispatchEvent (node=<optimized out>, mediator=...) at third_party/WebKit/Source/WebCore/dom/EventDispatcher.cpp:127
#16 0x57dc6664 in WebCore::Node::dispatchWheelEvent (this=0x4c222b50, event=<optimized out>) at third_party/WebKit/Source/WebCore/dom/Node.cpp:2652
#17 0x580c9b86 in WebCore::EventHandler::handleWheelEvent (this=0x4be646b8, e=...) at third_party/WebKit/Source/WebCore/page/EventHandler.cpp:2424
#18 0x580c9c28 in WebCore::EventHandler::handleGestureScrollCore (this=0x4be646b8, gestureEvent=<optimized out>, granularity=<optimized out>, latchedWheel=<optimized out>)
    at third_party/WebKit/Source/WebCore/page/EventHandler.cpp:2637
#19 0x580cc082 in WebCore::EventHandler::handleGestureEvent (this=0x4be646b8, gestureEvent=...) at third_party/WebKit/Source/WebCore/page/EventHandler.cpp:2537
#20 0x57c9ef66 in WebKit::WebViewImpl::handleGestureEvent

另外,从CSS盒模型的角度看,该种Scrollbar位于border和padding之间,border位置大小不变,它占据了一部分content和padding的空间,但又不属于它们任何一个。


0 0
原创粉丝点击