谁能解释一下为什么下面的代码有效
const textarea = document.querySelector('textarea');
const submitButton = document.querySelector('button[aria-label="Submit"]');
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLTextAreaElement.prototype,
'value'
).set;
const event = new Event('input', { bubbles: true });
function typeAndSubmit(text) {
nativeInputValueSetter.call(textarea, text);
textarea.dispatchEvent(event);
submitButton.click()
}
typeAndSubmit('Hello');
而且这个只是改变了textarea.value,但没有提交
const textarea = document.querySelector('textarea');
const submitButton = document.querySelector('button[aria-label="Submit"]');
const event = new Event('input', { bubbles: true });
function typeAndSubmit(text) {
textarea.value = text
textarea.dispatchEvent(event);
submitButton.click()
}
typeAndSubmit('Hello');
我用谷歌搜索了与 React 相关的类似问题。但它不是 React,它是纯 javascript 和 html。我不太明白为什么会发生这种情况))
Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value')
提供HTMLTextAreaElement
原型中存在的 getter 和 setter 函数。
两者都可以在
HTMLTextAreaElement
实例范围内作为函数调用。
getter 是一个只有一个参数(一个值)的函数。它是负责设置
HTMLTextAreaElement
实例值的函数。
所以:
Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value)
.set.call([HTMLTextArea instance], value);
(相当于
HTMLTextAreaElement.prototype.set.call(...)
)
相当于
someTextArea = 'value'
document.addEventListener(`click`, handle);
// assign the HTMLTextAreaElement setter to a variable
// a bit less convoluted
const textSet = HTMLTextAreaElement.prototype.set;
function handle(evt) {
if (evt.target.dataset.set) {
console.clear();
const textArea = document.querySelector(`textarea`);
const text = evt.target.dataset.set;
if (evt.target.useSet) {
// call textSet for a HTMLTextAreaElement instance
return textSet.call(textArea, text);
// ^ instance
}
// use the HTMLTextAreaElement protoype setter
return textArea.value = text;
}
}
<textarea></textarea>
<p>
call textSet to set to
<button data-use-set="1"
data-set="Hello world (call to textSet)"
>'Hello world'</button>
<br>
use [textarea] = to set to
<button data-set="Hello world (setter used)"
>'Hello world'</button>
</p>