Как я могу перечислить тысячи / большой список эмодзи в веб-браузере, не замораживая браузер? - PullRequest
2 голосов
/ 20 июня 2019

Я посмотрел на несколько вопросов, но, похоже, ни один из них не решил мою проблему.Проект должен открыть список смайликов внутри div (модальный).Поэтому, когда пользователи нажимают кнопку смайликов, появляется модал с смайликами.Если мы перечислим сотни смайликов, то это почти мгновенно будет сделано.Если мы поместим тысячи смайликов, то для загрузки модала потребуется несколько секунд.

Я предоставил фрагмент демонстрационного массива смайликов.Пробовал классический подход, а также createDocumentFragment (вдохновленный здесь ), оба они имеют одинаковый эффект.

Ищите решение, которое может воспроизводить эмодзи по одному, как в очереди,Я знаю, что могу поместить элемент DOM в очередь, и когда он будет загружен, я смогу перейти к следующему элементу.Единственное, что я не знаю, когда отображается content.appendChild(button) или fragment.appendChild(button).Я читал, что вы можете использовать функцию setTimeout, но я не знаю, какое время устанавливать или рекомендуется ли в этом случае.

Спасибо!

function showEmojis() {
  let symbols = [
    "☺", "☻", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?" , "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "☹", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "☠", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?",  "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "☕", "?", "?", "?", "?", "?", "?", "?", "?"]

    // Just to a have big array with emojis
    for (var i = 0; i < 6; i++) {
        symbols = symbols.concat(symbols)
    }

    let content = document.getElementById("content")

    // Simple for
    /*
    for(var i=0; i < symbols.length; i++) {
        let unicode = symbols[i]
        
        let button = document.createElement("button")
        button.classList.add("emoji-button")
        button.innerHTML = unicode
        
        button.onclick = function() {
            console.log("selected")
        }
        
        content.appendChild(button)
    }*/

    // Document fragment
    var fragment = document.createDocumentFragment()

    for (var i = 0; i < symbols.length; i++) {
        let unicode = symbols[i]

        let button = document.createElement("button")
        button.classList.add("emoji-button")
        button.innerHTML = unicode

        button.onclick = function() {
            console.log("selected")
        }

        fragment.appendChild(button)
    }

    content.appendChild(fragment)
}
.emoji-show-button {
    font-size: 15px;
}

.emoji-button {
    width: 28px;
    height: 28px;
    padding: 0px;
    margin: 5px;
    background: white;
    border-style: none;
    font-size: 20px;
}
<button class="emoji-show-button" onclick="showEmojis()">Show emojis</button>
<div id="content"></div>

Ответы [ 3 ]

1 голос
/ 20 июня 2019

Проблема в том, что вы запускаете и создаете кнопки для события click кнопки «Показать смайлики», при этом каждый раз, когда пользователь нажимает кнопку «Эмоги», выполняется один и тот же код Некоторые способы оптимизировать это были бы

  1. Запустите этот метод в окне. Загрузка
  2. Запустите это в асинхронном методе, чтобы загрузить в фон
  3. Скрыть фрагмент документа и показывать его только тогда, когда пользователь нажимает кнопку

также было бы проще не устанавливать прослушиватель onclick для каждой кнопки, а сделать что-то подобное

<button id='button'> emoji</button>
<button id='button'> emoji2</button>

тогда в вашем js

document.addEventListener('click', (event) => {
if (event.target.id === 'button') {
    console.log(event.target.innerHtml)
}
1 голос
/ 20 июня 2019

Вы можете создать помощника, который берет фрагмент и добавляет его дочерние элементы в контейнер кусками.Оборачивая каждый вызов для добавления фрагмента в setTimeout, другие вещи javascript имеют шанс работать между ними.Например, если пользователь нажимает эмодзи или другую часть вашего пользовательского интерфейса, он будет ждать только 1 блок для записи, прежде чем он ответит.

Возможно, вы захотите изучить издержки, вызванные отдельными записями, и проверить наличиеоптимальный размер куска.Также может иметь смысл сначала создать фрагменты для каждого фрагмента, а затем выполнить только 1 запись в DOM.Я оставлю это на ваше усмотрение или другому ответчику, чтобы узнать:)

function appendInChunks(fragment, container, chunkSize = 5) {
  function writeChunk() {
    for (let c = 0; c < chunkSize && fragment.firstChild; c += 1) {
      container.appendChild(fragment.firstChild);
    }
  }
  
  for (let i = 0; i < fragment.children.length; i += chunkSize) {
    setTimeout(writeChunk);
  }
}

function showEmojis() {
  let symbols = [
    "☺", "☻", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?" , "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "☹", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "☠", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?",  "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", 
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
    "?", "?", "?", "?", "☕", "?", "?", "?", "?", "?", "?", "?", "?"]

    // Just to a have big array with emojis
    for (var i = 0; i < 6; i++) {
        symbols = symbols.concat(symbols)
    }

    let content = document.getElementById("content")

    // Simple for
    /*
    for(var i=0; i < symbols.length; i++) {
        let unicode = symbols[i]
        
        let button = document.createElement("button")
        button.classList.add("emoji-button")
        button.innerHTML = unicode
        
        button.onclick = function() {
            console.log("selected")
        }
        
        content.appendChild(button)
    }*/

    // Document fragment
    var fragment = document.createDocumentFragment()

    for (var i = 0; i < symbols.length; i++) {
        let unicode = symbols[i]

        let button = document.createElement("button")
        button.classList.add("emoji-button")
        button.innerHTML = unicode

        button.onclick = function() {
            console.log("selected")
        }

        fragment.appendChild(button)
    }

    appendInChunks(fragment, content);
}
.emoji-show-button {
    font-size: 15px;
}

.emoji-button {
    width: 28px;
    height: 28px;
    padding: 0px;
    margin: 5px;
    background: white;
    border-style: none;
    font-size: 20px;
}
<button class="emoji-show-button" onclick="showEmojis()">Show emojis</button>
<button onclick="console.log('ping')">press to check browser response</button>
<div id="content"></div>
1 голос
/ 20 июня 2019

Это похоже на проблему с оконным менеджером браузера / ОС, который борется с Emojis (Unicode)

Обходным решением будут фотографии, например, (https://emojipedia.org/emojipedia/)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...