如何为浏览器本机dom对象创建代理?
我想拦截元素样式的设置。因此,我为dom对象创建了一个代理。但是,当我使用诸如getComputedStyle之类的函数时,它将导致错误。
from selenium.common.exceptions import StaleElementReferenceException
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
base_url = "https://startup-days-2019.events.startupinvest.ch"
driver = webdriver.Firefox()
wait = WebDriverWait(driver, 10)
driver.get(base_url + "/participants")
size = int(wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".opportunities-count-number"))).text)
participants = []
while len(participants) < size:
participant_cards = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".participants-main-container a")))
for card in participant_cards:
try:
href = card.get_attribute("href")
if href not in participants:
participants.append(href)
except StaleElementReferenceException:
pass
driver.execute_script("arguments[0].scrollIntoView();", participant_cards[len(participant_cards)-1])
for participant in participants:
driver.get(participants)
el是本机浏览器dom对象。在我的代码中,有许多方法的参数为el,这些方法可能会修改el。我想防止其中的某些方法修改el,因此我尝试代理el对象。但是在代理之后,dom对象的某些方法不能在代理对象上使用,例如getComputedStyler。
我在下面创建一个演示。
const setHandler = (target: any, prop: PropertyKey, value: any, _receiver?: any) => {
if (/*some condition*/) {
target[prop] = value
}
return true
}
const getHandler = (target: any, prop: PropertyKey, _receiver?: any) => {
return target[prop]
}
const style = new Proxy(el.style, {
get: getHandler,
set: setHandler
})
const classList = new Proxy(el.classList,{
get: getHandler,
set: setHandler
})
const proxy = new Proxy(el/*HTMLElement*/, {
get: (target, prop, _receiver) => {
if (prop === 'target') {
return target
}
if (prop === 'style') {
return style
}
if (prop === 'classList') {
return classList
}
return getHandler(target, prop, target)
},
set: setHandler
})
const style = getComputedStyle(el)
(function() {
const node = document.querySelector('#demo')
const proxy = new Proxy(node, {
getPrototypeOf(target){
return Object.getPrototypeOf(target)
},
get(target, prop, receiver){
let value = target[prop]
if (typeof value === 'function') {
value = Function.prototype.bind.call(value, target)
}
return value
},
set(target, prop,value, receiver){
target[prop] = value
},
apply(target, args, newTarget) {
return Object.apply(target,args)
},
})
console.log(proxy)
console.log(Object.getPrototypeOf(proxy))
console.log(proxy.style)
// error: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
const style = getComputedStyle(proxy)
console.log(style)
})()