如何检测元素失去点击焦点事件

4

基本上,我希望用户点击任何.editable项目,会出现一个输入框并复制其样式,然后如果他们在其他地方单击,我希望输入框消失并保存更改。但是我发现这很困难。我看到了使用 event.stopPropagation 的解决方法,但是我不知道如何将其包含在我代码的结构中:

$(function() {
    var editObj = 0;
    var editing = false;   

    $("html").not(editObj).click(function(){
         if (editing){
                $(editObj).removeAttr("style");
                $("#textEdit").hide();
                alert("save changes");
            }
    });    


    $(".editable").not("video, img, textarea")
        .click(function(event) {

            editObj = this;
            editing = true;

            $("#textEdit")
                .copyCSS(this)
                .offset($(this).offset())
                .css("display", "block")
                .val($(this).text())
                .select();

            $(this).css("color", "transparent");


    });
}

这里复制copyCSS函数。

我需要区分对可编辑对象的点击和对其之外的点击,即使该点击是在不同的可编辑对象上(在这种情况下应调用2个事件)。


我认为捕获文档上的点击事件可能会起作用,但是我对事件冒泡等主题不够熟悉,无法确定应该在何时或如何执行此操作。 - Blazemonger
1
你能在输入框上使用模糊事件吗? - Kevin Bowersox
1
关于添加 http://api.jquery.com/blur 呢? - MRR0GERS
2个回答

2

试试这个:

$('body').click(function(event) {
    var parents = $(event.target).parents().andSelf();
    if (parents.filter(function(i,elem) { return $(elem).is('#textEdit'); }).length == 0) {
        // click was not on #textEdit or any of its childs
    }
});

$(".editable").not("video, img, textarea")
        .click(function(event) {

    // you need to add this, else the event will propagate to the body and close
    e.preventDefault();

http://jsfiddle.net/dDFNM/1/

这个代码的作用是检查点击的元素或其父元素是否为 #textEdit。

可以通过使用 event.stopPropagation 来实现以下解决方案:

// any click event triggered on #textEdit or any of its childs
// will not propagate to the body

$("#textEdit").click(function(event) {
    event.stopPropagation();
});

// any click event that propagates to the body will close the #textEdit

$('body').click(function(event) {
    if (editing) {
        $("#textEdit").hide();
    }
});

http://jsfiddle.net/dDFNM/2/


如果我当时在想这件事,那么这正是我会想到的。 - Blazemonger
由于某些原因,我无法使这两种方法都起作用。第一种方法从未触发过滤器中的内容,而第二种方法总是会触发。我试图将其转换为 jsfiddle,但它出现了问题。 - Damon
1
你需要停止 $(".editable").click() 事件的传播,否则该事件会传播到 body 并立即关闭输入。我稍微更新了第一段代码并添加了可工作的 jsfiddles。 - Arnaud Le Blanc

0
问题在于您没有正确地绑定到editObj。也许如果您将绑定移动到您的.editable点击处理程序内部,甚至更好地使用live()或delegate(),会有所帮助。 $("html").not(editObj)...在文档准备就绪时绑定一次,在那时editObj为false。

很有帮助..我一直在误解绑定(可能仍然如此)。我把它放在里面,但它不起作用。我得看看能想出什么来。 - Damon
我建议查阅 delegate()。另外,你可以在处理程序内部使用简单的 if 语句来取消事件,如果它是 editObj - beefyhalo

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