Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Варианты заполнения поля и идея реализации этой системы

#javascript #html #css


Здравствуйте. 

Постараюсь объяснить ситуацию на пальцах: есть страница, на которой можно посмотреть
список всех заказов (и провести поиск среди них). У каждого заказа имеется несколько
характеристик, в том числе и идентификтора заказчика. 

Для облегчения поиска по заказчикам, под полем ввода имени появляется ниспадающий
список со всеми заказчиками. Чтобы сделать систему максимально быстрой, список отдается
пользователю при загрузке страницы в виде JS объекта. Далее (при вводе данных) осуществляется
перебор всех юзеров и формирование таблицы. 

Проблема в том, что таблица, из которой берется список, довольно большая (8-10 тыс.
записей) и загрузка ее на страницу идет с зависанием (как и поиск в ней). 

Сам вопрос: как лучше организовать эту систему? (код не нужен, нужна лишь идея/структура
и т.д. для быстрого и эффективного поиска)

Пример системы (это не оригинальный код, а лишь копия некоторых функций и обработчиков
событий):



$(document).ready(function() {
  /*
         Получение списка, для упрощения сделал готовый объект
         для примера
    */
  lastElement = null;
  userList = [{
    ID: 1,
    Name: 'Иванов Иван Иванович',
    Phone: 123
  }, {
    ID: 2,
    Name: 'Петров Петр Петрович',
    Phone: 1243
  }, {
    ID: 3,
    Name: 'Максимов Максим Максимович',
    Phone: 1253
  }, {
    ID: 4,
    Name: 'Петров Иван Иванович',
    Phone: 1723
  }, {
    ID: 5,
    Name: 'Иванов Петр Иванович',
    Phone: 1236
  }, {
    ID: 6,
    Name: 'Иванов Иван Петрович',
    Phone: 1253
  }, {
    ID: 7,
    Name: 'Максимов Иван Иванович',
    Phone: 1323
  }, {
    ID: 8,
    Name: 'Иванов Максим Иванович',
    Phone: 1213
  }, {
    ID: 9,
    Name: 'Иванов Иван Максимович',
    Phone: 123
  }, {
    ID: 10,
    Name: 'Даниилов Данил Данилович',
    Phone: 1623
  }, {
    ID: 11,
    Name: 'Примеров Пример Примерович',
    Phone: 123
  }, {
    ID: 12,
    Name: 'Антонов Антон Антонович',
    Phone: 14223
  }, {
    ID: 13,
    Name: 'Кириллов Кирилл Кириллович',
    Phone: 12123
  }, {
    ID: 14,
    Name: 'Иоанов Иоан Иоанович',
    Phone: 12123
  }, {
    ID: 15,
    Name: 'Николаев Николай Николаевич',
    Phone: 123
  }, {
    ID: 16,
    Name: 'Анатольев Анатолий Анатольевич',
    Phone: 12683
  }, {
    ID: 17,
    Name: 'Анатольев Иван Иванович',
    Phone: 122343
  }, {
    ID: 18,
    Name: 'Иванов Анатолий Иванович',
    Phone: 123
  }, {
    ID: 19,
    Name: 'Иванов Иван Анатольевич',
    Phone: 122453
  }, {
    ID: 20,
    Name: 'Иоанов Иван Иванович',
    Phone: 12363
  }, {
    ID: 21,
    Name: 'Иванов Иоан Максимович',
    Phone: 120533
  }, {
    ID: 22,
    Name: 'Максимов Иван Максимович',
    Phone: 12123
  }, {
    ID: 23,
    Name: 'Примеров Иван Максимович',
    Phone: 12633
  }];
  $("body").append("
"); var controlElement = $("#searchPanel"); var table = $("#searchTable"); function OnSearch(l) { var search = $(l).val(); var idx = 0; var j = userList.length; var len = j; var i = 0; var dataHTML = ""; var toSetString = ""; while (--j) { i = len - j; elem = userList[i]; toSetString = elem.Name.concat(" (", elem.Phone, ")"); if (search.length > 0) { idx = elem.Name.indexOf(search); if (idx !== -1) { dataHTML = dataHTML.concat("", toSetString.substr(0, idx).concat("", search, "", toSetString.substr(idx + search.length))); } } else dataHTML = dataHTML.concat("", toSetString, ""); } table.html(dataHTML); } function ShowHelp(l) { lastElement = $(l); var pos = $(l).offset(), h = $(l).height(), topPos = pos.top + h + 5; h = 300; controlElement.css({ top: topPos, left: pos.left, height: h }); controlElement.fadeIn(100); table.empty().append("Загрузка списка... Пожалуйста, подождите"); OnSearch(l); } function HideHelp() { $("#searchPanel").fadeOut(100); } function OnSelect(l) { var value = userList[parseInt($(l).attr("k"))].Name; lastElement.val(value); } $("input[name=myinput]").on("click", function(e) { ShowHelp(e.currentTarget); }); $("input[name=myinput]").on("input", function(e) { ShowHelp(e.currentTarget); }); $("input[name=myinput]").on("blur", function(e) { HideHelp(); }); $("#searchTable").on("mousedown", "tr", function(e) { OnSelect(e.currentTarget) }); }); body { font-family: Sans-Serif; } #searchPanel { background-color: white; z-index: 1000; position: fixed; width: 500px; overflow: auto; display: none; text-align: left } .hightlightTR { width: 100%; } .hightlightTR tr:hover { background-color: #479EC4; border: 1px blue outset; cursor: pointer; } .parametres td, .parametres th { padding: 5px; border: 1px solid black; } Sasha Omelchenko Общая схема примерно такая: ввод нескольких букв в поле → отправка данных на сервер аяксом→ поиск введенных данных на сервере по таблице → возврат данных на страницу. Так работала первая версия этой системы. На событие INPUT вешался обработчик, который каждый раз отправлял данные на сервер. Но из-за ввода данных в поле "залпом" сервер был завален большим количеством запросов. Потом была добавлена задержка на ожидание ввода (в 400 мс) перед отправкой данных. Так как таблица довольно большая, на формирование ответа уходит порядка 1-2 секунд (если под условие поиска подходит 1+ тыс. строк), что, согласитесь, довольно неприятно. Именно после этого было решено хранить заранее сформированный список в базе данных и обновлять его только при регистрации пользователей или обновлении их данных.


Ответы

Ответ 1



Добавлять на страницу такое количество данных и осуществлять по ним поиск при помощи js это действительно плохая идея с низкой производительностью. Выводите на страницу только результаты поиска. Общая схема примерно такая: ввод нескольких букв в поле → отправка данных на сервер аяксом→ поиск введенных данных на сервере по таблице → возврат данных на страницу.

Комментариев нет:

Отправить комментарий