Chrome 停止运行 javascript,控制台显示 [违规]“更改”处理程序耗时 475 毫秒

问题描述 投票:0回答:0

我有下面的代码。当我选中或取消选中复选框时,chrome 会停止执行 Javascript。它给出了控制台消息

[Violation] 'change' handler took 475ms
.

我尽我所能地尝试改进代码,我减少了重复的 jQuery 选择器,使用文档片段来构建 DOM 内容,但它仍然让 Chrome 放弃执行 Javascript。我已经将它从 2000+ms 减少到大约 500ms。

我还能做什么?大约有 250 个国家/地区可能存在问题。在此之后,我将不得不对更多项目做类似的事情,所以这将是一个真正的泡菜。任何建议都将非常受欢迎。谢谢

HTML/PHP/Javascript:

<script>
    var countries = <?=getVar('freelancerCountries')?>;
    var languages = <?=getVar('freelancerLanguages')?>;
    var countryRanks = <?php $r = getVar('countryRanks'); echo ($r?$r:'{}')?>;
    $(document).ready(initFreelancerSettings);
</script>
<div id="countries" class="block small-top">
    <h3>Countries</h3>
    <div class="top">
        <label>Default rank: <input type="number" class="default-rank xxs"/></label>
        <label>Filter: <input type="text" class="filter xs" /></label>
    </div>
    <ul class="bottom list">
    </ul>
    <button class="save">Save</button>
</div>

Javascript:

function updateCountryRankForElement(element)
{
    var code = $(element).closest('[data-code]').data('code')
    if ($(`#countries [data-code=${code}] [type=checkbox]`).prop('checked'))
        countryRanks[code] = $(`#countries [data-code=${code}] [type=number]`).val();
    else
        delete countryRanks[code];
}

function updateCountryList() {
    // Cache DOM elements
    var $list = $('#countries .list');
    var $filter = $('#countries .filter');
    var $defaultRank = $('#countries .default-rank');

    // Create document fragment
    var fragment = document.createDocumentFragment();

    // Get filter value
    var filter = $filter.val().toLowerCase();

    // Filter and sort countries
    var sortedFiltered = Object.keys(countries);
    if (filter) {
        sortedFiltered = sortedFiltered.filter(function(code) {
            var country = countries[code];
            var name = country.name.toLowerCase();
            var lang = languages[country.lang].toLowerCase();
            return name.indexOf(filter) !== -1 || lang.indexOf(filter) !== -1;
        });
    }
    sortedFiltered.sort(function(a, b) {
        var rankA = countryRanks.hasOwnProperty(a) ? countryRanks[a] : $defaultRank.val();
        var rankB = countryRanks.hasOwnProperty(b) ? countryRanks[b] : $defaultRank.val();
        if (rankA !== rankB) {
            return rankA - rankB;
        } else {
            return countries[a].name.localeCompare(countries[b].name);
        }
    });

    // Build list items
    var defaultRank = $defaultRank.val();
    sortedFiltered.forEach(function(code) {
        var country = countries[code];
        var name = country.name;
        var lang = languages[country.lang];
        var rankSpecified = countryRanks.hasOwnProperty(code);
        var rank = rankSpecified ? countryRanks[code] : defaultRank;

        // Create list item
        var li = document.createElement('li');
        li.dataset.code = code;

        // Create list item content
        var content = `
            ${name} (${lang})
            <span class="controls">
                <input type="checkbox" ${rankSpecified ? 'checked' : ''}/>
                <input type="number" class="xxs" ${rankSpecified ? '' : 'disabled'} value="${rank}"/>
            </span>
        `;

        // Append list item to fragment
        li.innerHTML = content;
        fragment.appendChild(li);
    });

    // Replace list content with fragment
    $list.empty();
    $list[0].appendChild(fragment);
}

function initFreelancerSettings()
{
    var _default = countryRanks['_default']?countryRanks['_default']:0;
    $('#countries .default-rank').val(_default);
    updateCountryList();
    $('#countries .filter').on('keyup', function()
    {
        updateCountryList();
    });
    $('#countries .list [type=number]').on('change', function()
    {
        updateCountryRankForElement(this);
        updateCountryList();
    });
    $('#countries [type=checkbox]').on('change', function()
    {
        updateCountryRankForElement(this);
        updateCountryList();
    });
    $('#countries .default-rank').on('change', function()
    {
        updateCountryList();
    });
}
javascript jquery google-chrome dom google-chrome-devtools
© www.soinside.com 2019 - 2024. All rights reserved.