怎样用js移除当前元素受父元素影响的事件?

<body onselectstart="return false" class="whiteBg">
<div>123</div>
</body>

div元素无法选择,受body的onselectstart影响。
实际上并不知道是哪个父元素。

用js如何移除这个事件?

阅读 2.6k
5 个回答

那就试试只把div的传播事件去掉(如果有的话)

const div = document.querySelector('div');
div.onselectstart = null;
document.getElementsByTagName('body')[0].onselectstart = null
function removeSelectStart(element) {
    if (element.onselectstart) {
        element.onselectstart = null;
    }
    if (element.parentElement) {
        removeSelectStart(element.parentElement);
    }
}

removeSelectStart(document.getElementById('yourElementId'));

按你题目的描述,如果是在不知道事件绑定在哪个祖先元素的前提下,根据不同的事件绑定方式,有不同的解决方法:

// 移除用"on"加事件名所绑定的事件
function removeEvent(el, event) {
    let parent;
    event = "on" + event.toLowerCase();
    while (parent = el.parentNode) {
        if (parent[event]) parent[event] = null;
    }
}
removeEvent(document.querySelector("div"), "selectStart");

如果祖先元素是用addEventListener方法绑定事件的话,则需要一点小技巧来解决:

// 重写原生事件绑定方法,将已绑定事件缓存起来,方便获取所有事件以解除绑定
const eventMap = new Map;
const elementProto = Element.prototype;
const addEventListener = elementProto.addEventListener;
const removeEventListener = elementProto.removeEventListener;
elementProto.addEventListener = function (event, callback, useCapture) {
    if (typeof callback !== "function") return;
    event = event.toLowerCase();
    let listeners, type = event + (useCapture ? "Capture" : "");
    if (!(listeners = eventMap.get(this))) {
        listeners = { [type]: new Set([callback]) };
        eventMap.set(this, listeners);
    } else if (!listeners[type]) {
        listeners[type] = new Set([callback]);
    } else {
        listeners[type].add(callback);
    }
    addEventListener.call(this, event, callback, useCapture);
};
elementProto.removeEventListener = function (event, callback, useCapture) {
    if (typeof callback !== "function") return;
    event = event.toLowerCase();
    let listeners, type = event + (useCapture ? "Capture" : "");
    if (
        (listeners = eventMap.get(this)) &&
        listeners[type] && listeners[type].delete(callback)
    ) {
        removeEventListener.call(this, event, callback, useCapture);
    }
};
// 移除指定元素的所有祖先元素所绑定的某个事件
function removeAllEventListeners(el, event, useCapture) {
    event = event.toLowerCase();
    const type = event + (useCapture ? "Capture" : "");
    eventMap.forEach((listeners, parent) => {
        if (parent.contains(el) && listeners[type]) {
            listeners[type].forEach(callback => {
                parent.removeEventListener(event, callback, useCapture);
            });
        }
    });
}
removeAllEventListeners(document.querySelector("div"), "selectStart");
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题