如果之前没有使用jQuery设置过,如何绑定事件监听器?

时间:2019-01-08 18:53:28

标签: javascript jquery

在我的代码中的某处执行此命令:

function hook(el) {
    console.log("hooked")
}

$('a[href!="#"]').click(hook)

我想防止意外重置该钩子,因为如果再次执行该操作:

$('a[href!="#"]').click(hook)

哇,我会得到两次hooked。有没有办法查看hook是否已经与onclick事件相关?

其背后的内容如下:

function hook(e) {
    let uri = e.currentTarget.pathname

    e.preventDefault();

    if (uri == window.location.pathname)
        return;

    $.get(uri, function (data) {
        data = $(data)

        let main = data.find('#main').html()

        if (!main) {
            window.location.href = uri
            return
        }

        $('#main').html(main)

        install() // Reinstall the hook for the new code

        if (history.pushState) {
            history.pushState({'main': main }, null, uri);
        }
    }).fail(function () {
        window.location.href = uri
    });

    return false;
}

function install() {
    $('a[href!="#"]').click(hook);
}

当然,在这种情况下,我将仅通过重新安装新代码的钩子来解决该问题,例如installOn($('#main'))

2 个答案:

答案 0 :(得分:1)

function hook(e) {
    let uri = e.currentTarget.pathname

    e.preventDefault();

    if (uri == window.location.pathname)
        return;

    $.get(uri, function (data) {
        data = $(data)

        let main = data.find('#main').html()

        if (!main) {
            window.location.href = uri
            return
        }

        $('#main').html(main)

        // pass in the main context so it only binds on those
        install('#main') // Reinstall the hook for the new code

        if (history.pushState) {
            history.pushState({'main': main }, null, uri);
        }
    }).fail(function () {
        window.location.href = uri
    });

    return false;
}

function install(parentSelector) {
                   // find the elements in the context, or the document
    $('a[href!="#"]', parentSelector || document).click(hook);
}

//this will bind on all the links that match any where in the document
install();

通过搜索所需的上下文,使用此解决方案可以避免重复的绑定。

install()将以所有匹配的元素为目标,因为没有传入上下文,因此install方法默认为在文档中查找所有元素。

在ajax中,$('#main').html(main)用新元素替换main的内容。保证这些元素没有任何绑定,因为main是一个字符串,因此这些元素是全新创建的。

然后,install('#main') 定位到主体内部未绑定的元素,并在其上放置绑定。

因此避免重复绑定。

答案 1 :(得分:0)

jQuery允许使用event namespaces.

$('a[href!="#"]').on("click.hook", hook)

然后,当您想要重新创建并再次添加事件时,只需手动进行:

$('a[href!="#"]').off("click.hook");
$('a[href!="#"]').on("click.hook", hook);