gpt4 book ai didi

javascript - 如何在 JavaScript 中为所有元素覆盖 focus()?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:26:22 27 4
gpt4 key购买 nike

我想为 JavaScript 中的所有 HTML 元素覆盖函数 focus()

我该怎么做?

最佳答案

这个问题只是询问如何覆盖 HTML 元素的 .focus() 方法,所以这个问题会被首先回答。但是,还有其他方法可以触发对元素的“关注”,并在下面讨论覆盖这些方法。

另请注意,覆盖全局原型(prototype)可能不是一个好主意


覆盖 HTML 元素上的 .focus() 方法

您可以通过修改其原型(prototype)来覆盖所有 HTMLElement 的焦点函数。

HTMLElement.prototype.focus = function () {
// ... do your custom stuff here
}

如果您仍想运行默认焦点行为并运行您的自定义覆盖,您可以执行以下操作:

let oldHTMLFocus = HTMLElement.prototype.focus;
HTMLElement.prototype.focus = function () {
// your custom code
oldHTMLFocus.apply(this, arguments);
};

通过 HTML 元素上的处理程序覆盖焦点事件集

这与覆盖 .focus() 方法的方式类似。然而,在这种情况下,我们将针对 EventTarget 构造函数并修改 addEventListener 原型(prototype):

let oldAddListener = HTMLElement.prototype.addEventListener;
EventTarget.prototype.addEventListener = function () {
let scope = this;
let func = arguments[1];

if (arguments[0] === 'focus') {
arguments[1] = function (e) {
yourCustomFunction(scope);
func(e);
};
}

oldAddListener.apply(this, arguments);
};

如果您根本不想要原始行为,您可以删除 func 调用 (func(e))。


覆盖通过onfocus属性设置的焦点事件

这样做实际上很棘手,而且很可能会有一些无法预料的限制。也就是说,我找不到通过修改原型(prototype)等来覆盖它的方法。我能完成这项工作的唯一方法是使用 MutationObservers。 .它通过查找具有属性 onfocus 的所有元素来工作,并将第一个运行的函数设置为覆盖函数:

let observer = new MutationObserver(handleOnFocusElements);
let observerConfig = {
attributes: true,
childList: true,
subtree: true,
attributeFilter: ['onfocus']
};
let targetNode = document.body;

observer.observe(targetNode, observerConfig);

function handleOnFocusElements() {
Array
.from(document.querySelectorAll('[onfocus]:not([onfocus*="yourCustomFunction"])'))
.forEach(element => {
let currentCallbacks = element.getAttribute('onfocus');
element.setAttribute('onfocus', `yourCustomFunction(this); return; ${currentCallbacks}`);
});
}

如果您想完全阻止原始 onfocus 触发其事件,您可以在任何突变更改时完全清空 onfocus 属性,并将值设置为您想要的函数。


包含所有代码片段的示例:

(function() {

window.yourCustomFunction = function(target) {
console.log('OVERRIDE on element', target);
};

let observer = new MutationObserver(handleOnFocusElements);

let observerConfig = {
attributes: true,
childList: true,
subtree: true,
attributeFilter: ['onfocus']
};

let targetNode = document.body;

// Start overriding methods
// The HTML `.focus()` method
let oldHTMLFocus = HTMLElement.prototype.focus;
HTMLElement.prototype.focus = function() {
yourCustomFunction(this);
oldHTMLFocus.apply(this, arguments);
};

// Event Target's .addEventListener prototype
let oldAddListener = HTMLElement.prototype.addEventListener;
EventTarget.prototype.addEventListener = function() {
let scope = this;
let func = arguments[1];

if (arguments[0] === 'focus') {
arguments[1] = function(e) {
yourCustomFunction(scope);
func(e);
};
}

oldAddListener.apply(this, arguments);
};

// Handle the onfocus attributes
function handleOnFocusElements() {
Array
.from(document.querySelectorAll('[onfocus]:not([onfocus*="yourCustomFunction"])'))
.forEach(element => {
let currentCallbacks = element.getAttribute('onfocus');
element.setAttribute('onfocus', `yourCustomFunction(this); return; ${currentCallbacks}`);
});
}

window.addEventListener('load', () => {
handleOnFocusElements();
observer.observe(targetNode, observerConfig);
});
})();

let input = document.querySelector('input');

input.addEventListener('focus', function() {
console.log('Add Event Listener Focus');
});

function attributeHandler() {
console.log('Called From the Attribute Handler');
}
<input type="text" onfocus="attributeHandler()">

关于javascript - 如何在 JavaScript 中为所有元素覆盖 focus()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13159865/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com