Event fires only second, after sequence of user actions

5

I have a form where there is a table. At the bottom of this, there are buttons to manipulate the rows of the table, and only the selected ones will be affected.

StepstoReproduceProblem

jsfiddle to check the problem

result of fiddle to test in IE 8

  • click any box so that it is orange
  • click one of the command buttons
  • click the box again to deselect the line

    It will not work!

  • click again to deselect the line

    Now it works!

  • This fiddle already has a very well isolated javascript code, it does not even have a scroll in the fiddle (in the script part, which is where I think the problem is) ... but I still could not solve the problem. p>

    Question

    How to make the box deselect on the first click?

    Please, if you know the solution, explain to me ... do not just put code ... I would very much like to know why this is not working.

    Browsers that I tested have the problem: Chrome 34, Firefox 28, IE 8

    To tell you the truth, I worry a lot about solving for chrome, a little less for FF, and not for IE 8 at all ... I just mentioned IE 8 to show that the problem is consistent between browsers .

    Notes:

    I noticed that by removing the lines below, it works the way I want it ... almost ... There are two lines equal to this:

    .bind("blur mouseout", restore)
    

    However, this way I lose the mouse-out, which serves to clear the icon that is placed inside the orange box indicating which lines are affected, as not always a selected line can be affected by a command.

        
    asked by anonymous 17.05.2014 / 01:31

    2 answers

    4

    Most likely your problem is in blur . Follow these steps:

  • click any box so that it is orange
  • click one of the command buttons

    2.1. (click on another window, use Tab several times, etc.)

  • click the box again to deselect the line

    Now it works!

  • Explanation

    When you do shifts the focus, the following things happen:

  • When you click, focus is still on the command button;
  • The first thing to happen, therefore, is the blur event on this button;
  • This event causes a restore , which changes the html of the element being clicked
  • As this element has just changed, it probably is not yet subject to live ;
  • The click happens in fact; as the element is not yet subject to live it does not register the click.
  • Proposed solution (imperfect):

    If the event that caused the restore is not a blur , force it:

    var restore = function(e) {
        if ( e.type != "blur" )
            $(this).blur();
        $("#columns .selected .selector").get(0).innerHTML
            = "<i>&nbsp;</i>";
    };
    

    Example in jsFiddle . This is not the ideal solution (eg if the user has moved the focus to the button, passed the mouse over inadvertently, then pressed "space" it will be surprised that the button has lost the focus), but serves as the basis for a solution. Another scenario that may surprise the user is if he used the keyboard to trigger the command button (ie he has the focus, and never received a mouseout ) and the mouse to try to de-select the line (ie blur of the command button will be activated) - in this case, the bug will remain.

    I can not think of a better solution, so it would be ideal to not change the html of the element being clicked, to avoid this glitch . I'm afraid I have nothing to suggest about it, but if I can think of something better I'll post again here.

    Update

    I set up an example without touching markup or CSS, which works correctly except for a small visual detail. It is based on the above proposed - not to tamper with html during a blur :

    var showIcon = function() {
        // Esconde o elemento presente
        $("#columns .selected .selector i").hide();
    
        // Obtém o ícone; se ele não existe, cria-o
        var icone = $("#columns .selected .selector .icone");
        if ( icone.length == 0 )
            icone = $('<span class="icone"></span>').appendTo($("#columns .selected .selector"));
    
        // Atualiza-o para ficar igual ao botão de comando
        icone.html($(this).html()).show();
    }
    
    var restore = function() {
        // Mostra de novo o elemento vazio e esconde o ícone
        $("#columns .selected .selector i").show();
        $("#columns .selected .selector .icone").hide();
    };
    

    Example in jsFiddle . Since we are not changing the html of the element (which I confirmed to be enough pro click fails - either using live or jQuery 1.7+ using on ) the glitch does not occur. I just needed to position the element with CSS so it stays inside the square.

        
    17.05.2014 / 02:12
    2

    When you click on button it also fires a focus event ( link ).

    An option, similar to the @mgibsonbr idea would trigger a blur at the time of the click. This solves the problem for me in Chrome: link

    var clic = function () {
       $(this).blur();
    }
    
    //...
    
    // UP
    $("#move-column-up")
        .bind("click", clic)
        .bind("focus mouseover", showIcon)
        .bind("blur mouseout", restore)
    
    // DOWN
    $("#move-column-down")
        .bind("click", clic)
        .bind("focus mouseover", showIcon)
        .bind("blur mouseout", restore)
    

    Now, and without being sure that you have e.preventDefault() , putting type="button" on the button stops you from submitting form each time you click.

        
    17.05.2014 / 06:00