Remove an item from datalist

2019-08-26 12:07发布

问题:

I have a working Ajax call and function that populates a datalist. The datalist is used to select from a finite list an addition to an UL element on the page. Once I add one from the datalist to the actual list, I want to remove that option from the datalist. The brute force method I'm using is to clear the datalist and repopulate it.

function populate_datalist_from_array(list_id, list_str)
{
    clearChildren( list_id );
    var arr = eval ( list_str );
    for (var i = 0; i < arr.length; i++) {
        var opt = document.createElement('option');
        opt.innerHTML = arr[i];
        opt.value = arr[i];
        document.getElementById(list_id).appendChild(opt);
    }
}

function clearChildren( parent_id ) {
    var childArray = document.getElementById( parent_id ).children;
    if ( childArray.length > 0 ) {
        document.getElementById( parent_id ).removeChild( childArray[ 0 ] );
        clearChildren( parent_id );
    }
}

I've verified that the list_str object is correct. i.e., it contains only the options not already in the current list. But after calling populate_datalist_from_array with that new list, the datalist in the dropdown doesn't change. Is this because the browser has essentially compiled all of the values that were there (like it were a normal, browser-based autocomplete) and doesn't 'forget' the values that I want removed?

回答1:

If list_str really is OK, your code works. You can check it in action at jsFiddle.

The most general reason for a behaviour you've described, is that your code refreshes the page. If you remove type="button" from the "Change options" button in the linked fiddle, you'll get an error (due to the fiddle itself). In your page you probably have something similar invoking populate_datalist_from_array(). Notice, that also hitting Enter on an active text input will do submit/refresh.



回答2:

Teemu's JsFiddle works fine. However, it's normally better to avoid recursion, and multiple DOM queries when not required.

Here is an edit that only requires a single DOM query, and is iterative. (Note decrement before index because this is a zero based list)

    clearChildren = function (parent_id) {
        var parent = document.getElementById(parent_id);
        var childArray = parent.children;
        var cL = childArray.length;
        while(cL > 0) {
            cL--;
            parent.removeChild(childArray[cL]);
        }
    };

(In JSFiddle on MacBookPro I saved 10 ms - from 15 ms total - on a list of 500 elements, but could be more dramatic with larger DOM's on mobile).