rect增加scroll_position属性

This commit is contained in:
g1879 2024-07-06 09:42:45 +08:00
parent 07de9eb131
commit 89af82dc2f
8 changed files with 64 additions and 44 deletions

View File

@ -107,12 +107,12 @@ def location_in_viewport(page, loc_x, loc_y):
def offset_scroll(ele, offset_x, offset_y):
"""接收元素及偏移坐标,把坐标滚动到页面中间,返回该点绝对坐标
"""接收元素及偏移坐标,把坐标滚动到页面中间,返回该点坐标
有偏移量时以元素左上角坐标为基准没有时以click_point为基准
:param ele: 元素对象
:param offset_x: 偏移量x
:param offset_y: 偏移量y
:return: 绝对坐标
:return: 绝对坐标和相对坐标
"""
loc_x, loc_y = ele.rect.location
cp_x, cp_y = ele.rect.click_point
@ -122,7 +122,11 @@ def offset_scroll(ele, offset_x, offset_y):
clientWidth = ele.owner._run_js('return document.body.clientWidth;')
clientHeight = ele.owner._run_js('return document.body.clientHeight;')
ele.owner.scroll.to_location(lx - clientWidth // 2, ly - clientHeight // 2)
return lx, ly
cl_x, cl_y = ele.rect.viewport_location
ccp_x, ccp_y = ele.rect.viewport_click_point
cx = cl_x + offset_x if offset_x else ccp_x
cy = cl_y + offset_y if offset_y else ccp_y
return lx, ly, cx, cy
def make_absolute_link(link, baseURI=None):

View File

@ -6,7 +6,7 @@
@License : BSD 3-Clause.
"""
from pathlib import Path
from typing import Union, Optional
from typing import Union, Optional, Tuple
from .._base.base import DrissionElement, BaseParser
from .._elements.chromium_element import ChromiumElement
@ -24,7 +24,7 @@ def format_html(text: str) -> str: ...
def location_in_viewport(page: ChromiumBase, loc_x: float, loc_y: float) -> bool: ...
def offset_scroll(ele: ChromiumElement, offset_x: float, offset_y: float) -> tuple: ...
def offset_scroll(ele: ChromiumElement, offset_x: float, offset_y: float) -> Tuple[int, int, int, int]: ...
def make_absolute_link(link: str, baseURI: str = None) -> str: ...

View File

@ -53,7 +53,7 @@ class Clicker(object):
try:
self._ele.scroll.to_see()
if self._ele.states.is_enabled and self._ele.states.is_displayed:
rect = self._ele.rect.corners
rect = self._ele.rect.viewport_corners
can_click = True
except NoRectError:
if by_js is False:
@ -90,14 +90,17 @@ class Clicker(object):
r = self._ele.owner._run_cdp('DOM.getNodeForLocation', x=int(x), y=int(y),
includeUserAgentShadowDOM=True, ignorePointerEventsNone=True)
if r['backendNodeId'] != self._ele._backend_id:
vx, vy = self._ele.rect.midpoint
vx, vy = self._ele.rect.viewport_midpoint
lx, ly = self._ele.rect._get_page_coord(vx, vy)
else:
vx, vy = self._ele.rect.click_point
vx, vy = self._ele.rect.viewport_click_point
lx, ly = self._ele.rect._get_page_coord(vx, vy)
except CDPError:
vx, vy = self._ele.rect.midpoint
vx, vy = self._ele.rect.viewport_midpoint
lx, ly = self._ele.rect._get_page_coord(vx, vy)
self._click(vx, vy)
self._click(lx, ly, vx, vy)
return True
if by_js is not False:
@ -110,8 +113,7 @@ class Clicker(object):
def right(self):
"""右键单击"""
self._ele.owner.scroll.to_see(self._ele)
x, y = self._ele.rect.click_point
self._click(x, y, 'right')
self._click(*self._ele.rect.click_point, *self._ele.rect.viewport_click_point, button='right')
def middle(self, get_tab=True):
"""中键单击默认返回新出现的tab对象
@ -119,9 +121,8 @@ class Clicker(object):
:return: Tab对象或None
"""
self._ele.owner.scroll.to_see(self._ele)
x, y = self._ele.rect.click_point
curr_tid = self._ele.tab.browser.tab_ids[0]
self._click(x, y, 'middle')
self._click(*self._ele.rect.click_point, *self._ele.rect.viewport_click_point, button='middle')
if get_tab:
tid = self._ele.tab.browser.wait.new_tab(curr_tab=curr_tid)
if not tid:
@ -142,8 +143,7 @@ class Clicker(object):
w, h = self._ele.rect.size
offset_x = w // 2
offset_y = h // 2
x, y = offset_scroll(self._ele, offset_x, offset_y)
self._click(x, y, button, count)
self._click(*offset_scroll(self._ele, offset_x, offset_y), button=button, count=count)
def multi(self, times=2):
"""多次点击
@ -198,19 +198,18 @@ class Clicker(object):
return (self._ele.tab.browser.get_mix_tab(tid) if self._ele.tab._type == 'MixTab'
else self._ele.tab.browser.get_tab(tid))
def _click(self, loc_x, loc_y, button='left', count=1):
def _click(self, loc_x, loc_y, view_x, view_y, button='left', count=1):
"""实施点击
:param loc_x: 绝对x坐标
:param loc_y: 绝对y坐标
:param view_x: 视口x坐标
:param view_y: 视口y坐标
:param button: 'left' 'right' 'middle' 'back' 'forward'
:param count: 点击次数
:return: None
"""
self._ele.owner.actions.move_to((loc_x, loc_y), duration=.1)
sx, sy = self._ele.owner.rect.scrollbar_position
x = loc_x - sx
y = loc_y - sy
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=x,
y=y, button=button, clickCount=count, _ignore=AlertExistsError)
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=x,
y=y, button=button, _ignore=AlertExistsError)
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mousePressed', x=view_x,
y=view_y, button=button, clickCount=count, _ignore=AlertExistsError)
self._ele.owner._run_cdp('Input.dispatchMouseEvent', type='mouseReleased', x=view_x,
y=view_y, button=button, _ignore=AlertExistsError)

View File

@ -45,4 +45,9 @@ class Clicker(object):
def for_new_tab(self, by_js: bool = False, timeout: float = 3) -> Union[ChromiumTab, MixTab]: ...
def _click(self, client_x: float, client_y: float, button: str = 'left', count: int = 1) -> None: ...
def _click(self, loc_x: float,
loc_y: float,
view_x: float,
view_y: float,
button: str = 'left',
count: int = 1) -> None: ...

View File

@ -39,20 +39,17 @@ class ElementRect(object):
@property
def location(self):
"""返回元素左上角的绝对坐标"""
cl = self.viewport_location
return self._get_page_coord(cl[0], cl[1])
return self._get_page_coord(*self.viewport_location)
@property
def midpoint(self):
"""返回元素中间点的绝对坐标"""
cl = self.viewport_midpoint
return self._get_page_coord(cl[0], cl[1])
return self._get_page_coord(*self.viewport_midpoint)
@property
def click_point(self):
"""返回元素接受点击的点的绝对坐标"""
cl = self.viewport_click_point
return self._get_page_coord(cl[0], cl[1])
return self._get_page_coord(*self.viewport_click_point)
@property
def viewport_location(self):
@ -96,6 +93,13 @@ class ElementRect(object):
pr = self._ele.owner._run_js('return window.devicePixelRatio;')
return (vx + ex) * pr, (ey + vy) * pr
@property
def scroll_position(self):
"""返回滚动条位置,格式:(x, y)"""
r = self._ele._run_js('return this.scrollLeft.toString() + " " + this.scrollTop.toString();')
w, h = r.split(' ')
return int(w), int(h)
def _get_viewport_rect(self, quad):
"""按照类型返回在可视窗口中的范围
:param quad: 方框类型margin border padding
@ -177,7 +181,7 @@ class TabRect(object):
return int(w), int(h)
@property
def scrollbar_position(self):
def scroll_position(self):
"""返回滚动条位置,格式:(x, y)"""
r = self._get_page_rect()['visualViewport']
return r['pageX'], r['pageY']
@ -238,7 +242,9 @@ class FrameRect(object):
return self._frame.frame_ele.rect.viewport_corners
@property
def scrollbar_position(self):
def scroll_position(self):
"""返回滚动条位置,格式:(x, y)"""
r = self._frame._run_cdp_loaded('Page.getLayoutMetrics')['visualViewport']
return r['pageX'], r['pageY']
r = self._frame.doc_ele._run_js('return this.documentElement.scrollLeft.toString() + " " '
'+ this.documentElement.scrollTop.toString();')
w, h = r.split(' ')
return int(w), int(h)

View File

@ -56,6 +56,9 @@ class ElementRect(object):
@property
def viewport_corners(self) -> Tuple[Tuple[float, float], ...]: ...
@property
def scroll_position(self) -> Tuple[float, float]: ...
def _get_viewport_rect(self, quad: str) -> Union[list, None]: ...
def _get_page_coord(self, x: float, y: float) -> Tuple[float, float]: ...
@ -90,7 +93,7 @@ class TabRect(object):
def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ...
@property
def scrollbar_position(self) -> Tuple[int, int]: ...
def scroll_position(self) -> Tuple[int, int]: ...
def _get_page_rect(self) -> dict: ...
@ -121,3 +124,6 @@ class FrameRect(object):
@property
def viewport_corners(self) -> Tuple[Tuple[float, float], ...]: ...
@property
def scroll_position(self) -> Tuple[float, float]: ...

View File

@ -16,11 +16,11 @@ class Scroller(object):
:param ele: 元素对象
"""
self._driver = ele
self.t1 = self.t2 = 'this'
self._t1 = self._t2 = 'this'
self._wait_complete = False
def _run_js(self, js):
js = js.format(self.t1, self.t2, self.t2)
js = js.format(self._t1, self._t2, self._t2)
self._driver._run_js(js)
self._wait_scrolled()
@ -125,8 +125,8 @@ class PageScroller(Scroller):
:param owner: 页面对象
"""
super().__init__(owner)
self.t1 = 'window'
self.t2 = 'document.documentElement'
self._t1 = 'window'
self._t2 = 'document.documentElement'
def to_see(self, loc_or_ele, center=None):
"""滚动页面直到元素可见
@ -165,7 +165,7 @@ class FrameScroller(PageScroller):
:param frame: ChromiumFrame对象
"""
super().__init__(frame.doc_ele)
self.t1 = self.t2 = 'this.documentElement'
self._t1 = self._t2 = 'this.documentElement'
def to_see(self, loc_or_ele, center=None):
"""滚动页面直到元素可见

View File

@ -13,8 +13,8 @@ from .._pages.chromium_base import ChromiumBase
class Scroller(object):
def __init__(self, page_or_ele: Union[ChromiumBase, ChromiumElement]):
self.t1: str = ...
self.t2: str = ...
self._t1: str = ...
self._t2: str = ...
self._driver: Union[ChromiumBase, ChromiumElement] = ...
self._wait_complete: bool = ...
@ -64,7 +64,7 @@ class FrameScroller(PageScroller):
:param frame: ChromiumFrame对象
"""
self._driver = frame.doc_ele
self.t1 = self.t2 = 'this.documentElement'
self._t1 = self._t2 = 'this.documentElement'
self._wait_complete = False
def to_see(self, loc_or_ele, center=None):