Vincular correctamente los controladores de eventos jquery

I am trying to neatly package up some functionality that adds editing controls to a table cell. Below is an example of what I am trying to achieve.

What I want to know is if this is the correct way to do this. I end up having to re-bind the event handlers when I empty the cell. I think jquery removes them but I am not certain. I expected them to remain since I have saved the dom elements within the ScoreManager object.

<div id="main">
 <table id="points-table">
    <thead>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Points</th>
    </thead>
    <tr>
        <td>Joe</td>
        <td>Bloggs</td>
        <td class="points">
            <span>100</span>
            <button>edit</button>
        </td>
    </tr>
    <tr>
        <td>Jiminy</td>
        <td>Cricket</td>
        <td class="points">
            <span>77</span>
            <button>edit</button>
        </td>
    </tr>
 </table>
 </div>

 <script type="text/javascript" src="js/jquery.js"></script>
 <script type="text/javascript">
window.onload = init;

var ScoreManagers = [];

function init() {
    $('#points-table .points').each(function(){
        ScoreManagers.push( new ScoreManager(this) );
    });
}

var ScoreManager = function(cell) {
    this.cell = $(cell);
    this.edit = $('button', this.cell);
    this.points = $('span', this.cell);
    this.scoreInput = $('<input>');
    this.submit = $('<button>Submit</button>');
    this.cancel = $('<button>Cancel</button>');

    this.init();
};

ScoreManager.prototype.init = function() {
    this.edit.bind('click', $.proxy(this.showEditControls, this));
};

ScoreManager.prototype.showEditControls = function(e) {
    this.cell.empty();
    this.cell.append(this.scoreInput, this.submit, this.cancel);
    this.submit.bind('click', $.proxy(this.savePoints, this));
    this.cancel.bind('click', $.proxy(this.cancelEdit, this));
};

ScoreManager.prototype.cancelEdit = function() {
    this.cell.empty();
    this.cell.append(this.points, this.edit);
    this.edit.bind('click', $.proxy(this.showEditControls, this));
}

ScoreManager.prototype.savePoints = function() {
    this.cell.empty();
    this.points.text(this.scoreInput.val());
    this.cell.append(this.points, this.edit);
    this.edit.bind('click', $.proxy(this.showEditControls, this));
}

 </script>

preguntado el 26 de agosto de 12 a las 23:08

2 Respuestas

You should take a look at event delegation and event bubbling in browsers, the PPK blog es un buen lugar.

Entonces mira jQuery en method which implements delegation in an elegent way.

Now bind events to the top element under consideration that doesnt get removed added to DOM, it can be body also, and delegate to the element you want.

$('#points-table').on('click', '.points', function(){
  //what should be done when you click a point element
  });

Respondido 27 ago 12, 00:08

bind will not work after element is removed. It will attach an event to all already available elements, but if you remove that element - binidng will be lost. Newly added elements will have no binding too. You may find usefull jQuery.live which allows to bind an event to elements with specified selector no matter if it already exists or will be added later. But if you are using latest jQuery, you may need to use alternatives as it is depricated. Also you may find usefull to use .detach() en lugar de .empty() because detach keeps event handler bindings. But you will need to modify your code as this.cell.detach(); will remove whole cell) instead of its children only.

Respondido 26 ago 12, 23:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.