Skip to content

Commit 92c833a

Browse files
committed
拖拽可拖拽到绝对坐标或相对位置,并增加随机抖动、调整拖拽速度功能
1 parent f8af77d commit 92c833a

File tree

1 file changed

+48
-13
lines changed

1 file changed

+48
-13
lines changed

DrissionPage/driver_element.py

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -240,24 +240,59 @@ def set_attr(self, attr: str, value: str) -> bool:
240240
except:
241241
raise
242242

243-
def drag_to(self, ele_or_loc: Union[tuple, WebElement, DrissionElement]) -> bool:
243+
def drag(self, x: int, y: int, speed: int = 40, shake: bool = True) -> bool:
244+
"""拖拽当前元素到相对位置
245+
:param x: x变化值
246+
:param y: y变化值
247+
:param speed: 速度
248+
:param shake: 是否随机抖动
249+
:return: 是否推拽成功
250+
"""
251+
x += self.location['x'] + self.size['width'] // 2
252+
y += self.location['y'] + self.size['height'] // 2
253+
return self.drag_to((x, y), speed, shake)
254+
255+
def drag_to(self,
256+
ele_or_loc: Union[tuple, WebElement, DrissionElement],
257+
speed: int = 40,
258+
shake: bool = True) -> bool:
244259
"""拖拽当前元素,目标为另一个元素或坐标元组
245-
:param ele_or_loc: 另一个元素或相对当前位置
260+
:param ele_or_loc: 另一个元素或坐标元组,坐标为元素中点的坐标
261+
:param speed: 拖动的速度,默认为None即瞬间到达
262+
:param shake: 是否随机抖动
246263
:return: 是否拖拽成功
247264
"""
248-
from selenium.webdriver import ActionChains
249-
loc1 = self.location
250-
actions = ActionChains(self._driver)
251-
252-
if isinstance(ele_or_loc, DriverElement):
253-
actions.drag_and_drop(self.inner_ele, ele_or_loc.inner_ele)
254-
elif isinstance(ele_or_loc, WebElement):
255-
actions.drag_and_drop(self.inner_ele, ele_or_loc)
265+
# x, y:目标坐标点
266+
if isinstance(ele_or_loc, DriverElement) or isinstance(ele_or_loc, WebElement):
267+
target_x = ele_or_loc.location['x'] + ele_or_loc.size['width'] // 2
268+
target_y = ele_or_loc.location['y'] + ele_or_loc.size['height'] // 2
256269
elif isinstance(ele_or_loc, tuple):
257-
actions.drag_and_drop_by_offset(self.inner_ele, ele_or_loc[0], ele_or_loc[1])
270+
target_x, target_y = ele_or_loc
258271
else:
259-
raise KeyError('Need WebElement object or coordinate information.')
260-
actions.perform()
272+
raise KeyError('Need DriverElement, WebElement object or coordinate information.')
273+
274+
current_x = self.location['x'] + self.size['width'] // 2
275+
current_y = self.location['y'] + self.size['height'] // 2
276+
width = target_x - current_x
277+
height = target_y - current_y
278+
num = 0 if not speed else int(((abs(width) ** 2 + abs(height) ** 2) ** .5) // speed)
279+
points = [(int(current_x + i * (width / num)), int(current_y + i * (height / num))) for i in range(1, num)]
280+
points.append((target_x, target_y))
281+
282+
from selenium.webdriver import ActionChains
283+
from random import randint
284+
actions = ActionChains(self.driver)
285+
loc1 = self.location
286+
for x, y in points:
287+
if shake:
288+
x += randint(-3, 4)
289+
y += randint(-3, 4)
290+
dx = x - current_x
291+
dy = y - current_y
292+
actions.drag_and_drop_by_offset(self.inner_ele, dx, dy)
293+
current_x, current_y = x, y
294+
295+
actions.release().perform()
261296
loc2 = self.location
262297
if loc1 == loc2:
263298
return False

0 commit comments

Comments
 (0)