最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cancel event triggering (blur) from another element's event (click) - Stack Overflow

programmeradmin6浏览0评论

I have a few rows with text, which I can "edit" by replacing the row inline with an input, which gets the text from the row as its value attribute.

When the input looses focus, the previous text is restored.

When pressing return (keyCode 13), the new text is saved and will be written in the row.

Now, for the users who don't know to press return for saving the text, I want to add a "Save" button right next to the input field. But when pressing it, the blur event of the input field is getting fired first, discarding the changes.

So is there an easy way, that the .click() event of the button can cancel the .blur() event on the input field? Perhaps an "don't execute other events" or can I perhaps see in the blur event, which events will get called next to cancel it?

Here is a jsfiddle to see what I mean: / (I'm working in Firefox (latest Nightly), where the button click won't work. I just tested the jsfiddle also in chrome, where also the keyup won't work as expected.)

$('#showEdit').click(function() {
    $('#row').data('text',$('#row').text());
    $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
    $('#editInput').val($('#row').data('text')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;

    if (keycode == 13) $('#editSave').click();
}).delegate('#editSave','click',function(e) {
    e.stopPropagation();

    $('#row').text($('#editInput').val());
}).delegate('#editInput','blur',function() {
    $('#row').text($('#row').data('text'));
});

I have a few rows with text, which I can "edit" by replacing the row inline with an input, which gets the text from the row as its value attribute.

When the input looses focus, the previous text is restored.

When pressing return (keyCode 13), the new text is saved and will be written in the row.

Now, for the users who don't know to press return for saving the text, I want to add a "Save" button right next to the input field. But when pressing it, the blur event of the input field is getting fired first, discarding the changes.

So is there an easy way, that the .click() event of the button can cancel the .blur() event on the input field? Perhaps an "don't execute other events" or can I perhaps see in the blur event, which events will get called next to cancel it?

Here is a jsfiddle to see what I mean: http://jsfiddle/ykY5X/ (I'm working in Firefox (latest Nightly), where the button click won't work. I just tested the jsfiddle also in chrome, where also the keyup won't work as expected.)

$('#showEdit').click(function() {
    $('#row').data('text',$('#row').text());
    $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
    $('#editInput').val($('#row').data('text')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;

    if (keycode == 13) $('#editSave').click();
}).delegate('#editSave','click',function(e) {
    e.stopPropagation();

    $('#row').text($('#editInput').val());
}).delegate('#editInput','blur',function() {
    $('#row').text($('#row').data('text'));
});
Share Improve this question edited Jan 1, 2014 at 14:07 BenMorel 36.7k52 gold badges206 silver badges337 bronze badges asked Sep 4, 2011 at 16:49 WulfWulf 3,8982 gold badges24 silver badges36 bronze badges 3
  • 1 cant you just save the value when the user hits edit, then save it again when on onblur, then the save button function pares the two values and if they are different, changes it to the last value saved from on blur? – Psyrus Commented Sep 4, 2011 at 17:04
  • Was a great idea! Unfortunately, the click event won't fire, as soon as the blur event removes the button. It only fires the mousedown event of the button. With a bit of temporary data, it works nice :) Thank you! – Wulf Commented Sep 4, 2011 at 17:46
  • Glad i could offer an approach to which you could work from :) – Psyrus Commented Sep 4, 2011 at 18:24
Add a ment  | 

4 Answers 4

Reset to default 2

My final working solution is this:

$('#showEdit').click(function() {
    $('#row').data('textOriginal',$('#row').text());
    $('#row').data('textSave',$('#row').text());
    $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
    $('#editInput').val($('#row').data('textOriginal')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;
    if (keycode == 13) {
        $('#row').data('textSave',$(this).val());
        $('#editSave').click();
    }
}).delegate('#editSave','mousedown',function() {
    $('#row').data('textSave',$('#editInput').val());
}).delegate('#editSave','click',function(e) {
    e.stopPropagation();

    if ($('#row').data('textOriginal') == $('#row').data('textSave')) {
        $('#row').text($('#row').data('textOriginal'));
        return;
     }

    $('#row').text($('#row').data('textSave'));

}).delegate('#editInput','blur',function() {
    $('#editSave').click();
});

http://jsfiddle/RSUdx/

You can use some delay before the code inside blur event handler gets executed. On Save button click you can cancel the blur timer so that it will not be executed.

Working demo

var blurTimer;
$('#showEdit').click(function() {
        $('#row').data('text',$('#row').text());
        $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
        $('#editInput').val($('#row').data('text')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;
    if (keycode == 13){
       $('#editSave').click();
    }
}).delegate('#editSave','click',function(e) {
    clearTimeout(blurTimer);
    $('#row').text($('#editInput').val());
}).delegate('#editInput','blur',function() {
    blurTimer = setTimeout(function(){
       $('#row').text($('#row').data('text'));
    }, 200);
});

I think u can try this:

$('#showEdit').click(function() {
    $('#row').data('text',$('#row').text());
    $('#row').html('<input type="text" id="editInput" /> <span id="editSave">Save</span>');
    $('#editInput').val($('#row').data('text')).focus();
});

$('#row').delegate('#editInput','keyup',function(e) {
    e.stopPropagation();
    var keycode = e.keyCode || e.which;
    if (keycode == 13) $('#editSave').click();
}).delegate('#editSave','click',function(e) {
    e.stopPropagation();

    $('#row').text($('#editInput').val());

}).delegate('#editInput','blur',function() {
    if($('#editSave').click())
         $('#row').text($('#editInput').val());
    else
    $('#row').text($('#row').data('text'));
});

.unbind allows u to unbind.[docs]

EDIT

Use keydown in place of keyup

发布评论

评论列表(0)

  1. 暂无评论