禁用特定元素的JavaScript

6

是否可能仅禁用特定元素的JavaScript?

假设id为foo的div具有一些JavaScript代码,可能是行内,内部或外部JavaScript代码。

现在,解除该元素的所有JavaScript代码(可能还包括子元素)。


不,我认为DOM元素在浏览器解析后才能访问。我认为没有办法进入处理过程以防止js块。 - Cheery
请记住,如果替换元素,即使是用自身替换,任何绑定在该元素上的事件都将丢失。这对于委托事件并没有帮助,但在您的情况下可能有用。还可以解析各种内联处理程序的属性并将其删除。 - charlietfl
@charlietfl - 这取决于"事件绑定"的方式以及元素被替换的方式。 - RobG
@RobG 我明白这一点,我只是在传达一个概念。还有可能会遇到许多时间问题,例如事件何时绑定。 - charlietfl
虽然可以通过跳过一些步骤来删除使用内联代码、属性分配和addEventListener分配的特定元素上的侦听器,但是使用attachEvent添加的侦听器可能更棘手。另外,如何防止事件委托? - RobG
显示剩余3条评论
4个回答

1
假设没有使用jQuery(或许它也能工作?),那么解决方案就是这么简单: element.innerHTML = element.innerHTML; 也就是将节点包含的所有内容的文本表示设置为当前节点包含的所有内容的文本表示。这样的文本赋值会清除任何通过element.addEventListener绑定的处理程序。您还可以使用element.removeAttribute('inlineEventName')来清除html本身中的任何内容。 您只需将.innerHTML或.outerHTML设置为其已有内容的副本,然后循环遍历处理程序名称数组,并重复调用.removeAttribute即可。对于任何目标的子节点进行迭代,然后再次(这次针对每个项目)循环遍历要杀死的处理程序名称数组。也许有一种方法可以遍历处理程序名称列表,但我不知道 - 我只会创建一个包含所有找到的名称的数组,然后逐步遍历该数组,根据需要进行清除。您将在初始替换中删除所有JS附加的处理程序,然后需要删除节点及其所有子节点的内联处理程序。
这是一个快速的示例,它禁用了body及其子元素中的所有内容。您会注意到第一次运行时,“kill”通知会触发两次-一次来自内联处理程序,一次来自js添加的处理程序。第二次运行时,通知仅从内联处理程序触发。尝试移除它或像我之前建议的那样使用“ .removeAttribute ”来消除该处理程序。
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}

window.addEventListener('load', onDocLoaded, false);

function onDocLoaded()
{
    byId('mFileInput').addEventListener('change', onFileChosen, false);
    byId('mBtn').addEventListener('click', killPageJs, false);
}
function killPageJs(evt)
{
    alert('killed');
    document.body.innerHTML = document.body.innerHTML;
}

// fileVar is an object as returned by <input type='file'>
// imgElem is an <img> element - can be on/off screen (doesn't need to be added to the DOM)
function loadImgFromFile(fileVar, imgElem)
{
    var fileReader = new FileReader();
    fileReader.onload = onFileLoaded;
    fileReader.readAsBinaryString(fileVar);
    function onFileLoaded(fileLoadedEvent)
    {
        var result,data;
        data = fileLoadedEvent.target.result;
        result = "data:";
        result += fileVar.type;
        result += ";base64,";
        result += btoa(data);
        imgElem.src = result;
        imgElem.origType = fileVar.type;    // unnecessary for loading the image, used by a current project.
    }
}

function onFileChosen(evt)
{
    if (this.files.length != 0)
    {
        var tgtImg = byId('tgt');
        var curFile = this.files[0];
        loadImgFromFile(curFile, tgtImg);
    }
}

</script>
<style>
</style>
</head>
<body>
    <button id='mBtn' onclick='killPageJs();'>Kill</button><hr>
    <input id='mFileInput' type='file'/><br>
    <img id='tgt' />
</body>
</html>

不,没有办法访问/循环处理程序。您可以通过删除属性来删除onClick处理程序等,但是您无法找到或删除使用addEventListener设置的任何处理程序。 - user663031
想到了。addEventListner 的那些很琐碎,因为它们随着初始文本替换而消失。 - enhzflep

0

是的,你可以这样做。

document.querySelector("element id or class here").style.pointerEvents = "none";

@LajosArpad 这怎么不是一个答案呢?它似乎直接回答了原帖的问题。 - leigero

0

CSS pointer-events 属性

关闭 CSS pointer-events 属性。

#foo { pointer-events: none; }

请查看https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events

当然,这样做并不会关闭某些类型的事件处理程序,比如说一个输入元素上的onchange处理程序。另一方面,它的优点是可以针对特定的后代元素重新启用pointer-events

不支持IE<11。

添加新事件处理程序

或者你也可以尝试以下方法:

elt.addEventListener('click', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    return false;
});

这不会阻止已经直接附加到元素的任何事件处理程序运行,但它将停止事件冒泡,从而处理委托类型的情况。它将抑制添加到元素的任何未来事件处理程序的运行。它还将抑制事件的默认行为(例如单击链接)。

您必须针对每个事件类型单独执行此操作。没有办法定义适用于多个或所有事件的事件处理程序(您可能也不想这样做)。


0
你可以使用Jquery的.off()函数来移除事件处理程序。
调用没有参数的.off()将删除附加到元素的所有处理程序。

https://api.jquery.com/off/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接