If you use js to dynamically add several lines after domready, the buttons in the newly added lines will be useless, we will share with you the following four solutions: js event listening is different from css. css only needs to set the style, whether it is existing or newly added. But event listening is not. You must bind an event to each element.
A common example is processing a table. There is a delete button at the end of each row. Click this button to delete this row.
The Code is as follows:
This line already exists |
Delete |
This line already exists |
Delete |
Normally, I will bind this
The Code is as follows:
JQuery (function ($ ){
// The existing deletion button initializes the binding deletion event.
$ (". Del"). click (function (){
$ (This). parents ("tr"). remove ();
});
});
The delete button that existed before domready is perfect. However, if you use js to dynamically add several lines after domready, the buttons in the newly added lines will be useless.
How can this problem be solved? Four solutions are available below:
Solution No. 0-onclick Method
In general, I will do this without considering the principles of structure and behavior separation.
Note: At this time, the deltr function must be a global function. You must put it outside jQuery (function ($) {}) and put it inside as a local function, the onclick in html cannot be called!
The Code is as follows:
Delete
JQuery (function ($ ){
// Add rows
$ ("# Add2"). click (function (){
$ ("# Table2> tbody"). append ('Add row Delete')
});
});
// Delete the row function, which must be placed out of the domready Function
Function deltr (delbtn ){
$ (Delbtn). parents ("tr"). remove ();
};
Solution 1-repeated binding
That is, when domready is used, an event handler is bound to an existing element,
Then, bind the new element again.
The Code is as follows:
Delete
JQuery (function ($ ){
// Define deletion button event binding
// Write it inside to prevent global namespace contamination
Function deltr (){
$ (This). parents ("tr"). remove ();
};
// The existing deletion button initializes the binding deletion event.
$ ("# Table3. del"). click (deltr );
// Add rows
$ ("# Add3"). click (function (){
$ ('Add row Delete')
// Here, bind the event to the delete button again.
. Find (". del"). click (deltr). end ()
. AppendTo ($ ("# table3> tbody "));
});
});
Solution 2-event Bubble Method
Based on the event bubbling principle, we bind the event processing function to the ancestor element of this button.
After all, we can determine whether the event is triggered by the event.tar get object.
Generally, you can use a few domnames, such as event.target.classname=event.tar get. tagName, to determine whether to use them.
The Code is as follows:
Delete
JQuery (function ($ ){
// Bind the delete button event of the fourth table
$ ("# Table4"). click (function (e ){
If (e.tar get. className = "del "){
Parameters (e.tar get). parents ("tr"). remove ();
};
});
// Add button event binding for the fourth table
$ ("# Add4"). click (function (){
$ ("# Table4> tbody"). append ('Add row Delete')
});
});
Solution 3-copy event Method
The above solutions can be said that even if you do not use the jQuery library, you can implement it relatively easily. However, this method is more dependent on jQuery. JQuery 1.2 or later is required. Plug-ins are required for earlier jQuery versions.
The above two solutions are a lot of brains for deleting functions, and they have changed the trigger and binding methods. This scheme is different. It can be bound to domready like static elements. But when we add a new line, we don't want to splice the string above to add a new line. This time we try to copy DOM elements. In addition, when copying, it copies together with the Bound event, and then modifies the internal elements such as find after copying.
In addition, in this example, if you delete all elements, the template is required. If you do not delete the elements, you may not need to use the template. To prevent accidental deletion, the template is hidden here.
I used the unique clone (true) in jQuery)
The Code is as follows:
. Template {display: none ;}
Here is the Template
Delete
This line already exists
Delete
This line already exists
Delete
JQuery (function ($ ){
// Delete button event binding for the fifth table
$ ("# Table5. del"). click (function (){
$ (This). parents ("tr"). remove ();
});
// Add button event binding for the fifth table
$ ("# Add5"). click (function (){
$ ("# Table5> tbody> tr: eq (0 )")
// Copy together with the event
. Clone (true)
// Remove the template tag
. RemoveClass ("template ")
// Modify the internal element
. Find ("td: eq (0 )")
. Text ("add row ")
. End ()
// Insert table
. AppendTo ($ ("# table5> tbody "))
});
});
General evaluation:
The above four solutions have their own advantages and disadvantages.
Solution No. 0, with no separation of structure and behavior, and contaminated the global namespace. Not recommended. So I don't think of it as a solution. But for beginners of js, it can be used for project emergency.
The No. 1 solution is well-regulated, and it's okay
Solution 2, which gives full play to the advantages of js event bubbling. And the efficiency is the highest. However, because this scheme ignores jQuery's powerful selector, it will be troublesome if too many element attributes are required. You will be stuck in the non-relation of many if conditions. Later, we can use the condition (event.tar get). is (selector) in jqueryas the condition. This can greatly improve the development efficiency, but slightly reduce the execution efficiency.
Solution 3: This is a solution that I think best reflects the idea of separation of structure and behavior. But the disadvantages are also obvious. jQuery is too highly dependent, or you have to write a function that copies together with the event, but this is obviously very difficult for beginners. However, from the perspective of future trends, we recommend this solution.
There is no specific number of options. It depends on your project and the degree to which your js has the idea of separation of structure and behavior. The most suitable is the best.
Additional:
Transform solution 3 into a perfect structure behavior separation style.
First, the template element is included. It is the source of all replication, so it is invisible to prevent accidental deletion. If the light is not deleted, the template element is optional. Because you can copy any existing element for loop.
Next, add a repeat to each repeated element to facilitate the deletion button to find this level of element. This is optional and sometimes not required.
The last step is to add a class to each element to be modified, which is easy to find using find. For example, I have a home content class here. The new value can be modified.
This is a perfect case of separation of structure and behavior.
The Code is as follows:
Here is the Template
Delete
This line already exists
Delete
This line already exists
Delete
Add
JQuery (function ($ ){
// Delete button event binding for the sixth table
$ ("# Tbody6. del"). click (function (){
$ (This). parents (". repeat"). remove ();
});
// Add button event binding for table 6
$ ("# Add6"). click (function (){
$ ("# Tbody6>. template ")
// Copy together with the event
. Clone (true)
// Remove the template tag
. RemoveClass ("template ")
// Modify the internal element
. Find (". content ")
. Text ("add row ")
. End ()
// Insert table
. AppendTo ($ ("# tbody6 "))
});
});
Similarly, this section of js applies to the following html structure:
The Code is as follows:
Here is the Template
Delete
This line already exists
Delete
This line already exists
Delete