2017-02-01 4 views
1

Я хочу отложить триггер поиска до тех пор, пока пользователь не закончит ввод. Я использую функцию, созданную с помощью mark.js (https://markjs.io). Он выполняет поиск по типу пользователя и переходит к первому результату при его поиске. Проблема в том, что он ищет каждую комбинацию букв по мере ввода. I.E: поиск «help» Ищет «h», «he», «hel», «help». Учитывая размер документа, это смехотворно медленно. Есть ли что-то, что я могу сделать с этой функцией, чтобы заставить ее ждать, пока пользователь не сделает ввод?JQuery - поиск задержки до завершения ввода

Вот функция поиска Я использую:

$(function() { 

    // the input field 
    var $input = $("input[type='search']"), 
    // clear button 
    $clearBtn = $("button[data-search='clear']"), 
    // prev button 
    $prevBtn = $("button[data-search='prev']"), 
    // next button 
    $nextBtn = $("button[data-search='next']"), 
    // the context where to search 
    $content = $(".container"), 
    // jQuery object to save <mark> elements 
    $results, 
    // the class that will be appended to the current 
    // focused element 
    currentClass = "current", 
    // top offset for the jump (the search bar) 
    offsetTop = 150, 
    // the current index of the focused element 
    currentIndex = 0; 

    /** 
    * Jumps to the element matching the currentIndex 
    */ 
    function jumpTo() { 
    if ($results.length) { 
     var position, 
     $current = $results.eq(currentIndex); 
     $results.removeClass(currentClass); 
     if ($current.length) { 
     $current.addClass(currentClass); 
     position = $current.offset().top - offsetTop; 
     window.scrollTo(0, position); 
     } 
    } 
    } 

    /** 
    * Searches for the entered keyword in the 
    * specified context on input 
    */ 
    $input.on("input", function() { 
    var searchVal = this.value; 
    $content.unmark({ 
     done: function() { 
     $content.mark(searchVal, { 
      accuracy: "exactly", 
      separateWordSearch: false, 
      done: function() { 
//Filter Results//$context.not(":has(mark)").hide(); 
      $results = $content.find("mark"); 
      currentIndex = 0; 
      jumpTo(); 
      } 
     }); 
     } 
    }); 
    }); 

    /** 
    * Clears the search 
    */ 
    $clearBtn.on("click", function() { 
    $content.unmark(); 
    $input.val("").focus(); 
    }); 

    /** 
    * Next and previous search jump to 
    */ 
    $nextBtn.add($prevBtn).on("click", function() { 
    if ($results.length) { 
     currentIndex += $(this).is($prevBtn) ? -1 : 1; 
     if (currentIndex < 0) { 
     currentIndex = $results.length - 1; 
     } 
     if (currentIndex > $results.length - 1) { 
     currentIndex = 0; 
     } 
     jumpTo(); 
    } 
    }); 
}); 

Вот некоторые HTML:

<input type="search" placeholder="Search" class="text-input" style="height: 28px; border-style: solid; border-color: black; border-width: 1px; margin-bottom: 3px;"> 
     <br/> 
     <button data-search="next">Next</button> 
     <button data-search="prev">Previous</button> 
     <button data-search="clear">✖</button><br/> 
<div class="container"> 
    <div> 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum non arcu id tristique. Cras fringilla nisi erat, non ultricies leo varius eu. Duis venenatis enim sed tristique gravida. Nulla dolor augue, tempor non nisl eget, consequat consequat magna. Nulla quis elit nisl. Integer at tortor molestie, dignissim odio id, pharetra nunc. Maecenas scelerisque porta erat bibendum aliquet. Proin est felis, pretium sit amet consequat eu, aliquet ac erat. Donec tempus, libero sit amet rutrum posuere, leo ipsum gravida odio, quis sodales magna nisl ut lectus. 
    </div> 
</div> 
+2

Вы можете установить setInterval или начать поиск после того как длина строки длиннее 3 символов (например). –

+0

Какую версию mark.js вы используете? Есть недавний релиз, который обеспечивает оптимизацию производительности. – dude

ответ

1

Вы можете душить в iniitialization функции поиска с помощью таймера, а также проверить если минимальное количество символов существует

Что-то вроде:

var searchTimer = null, 
    minLength = 3, 
    searchDelay = 300; 

$input.on("input", function() { 
    // clear previous timer 
    clearTimeout(searchTimer); 

    var searchVal = this.value; 

    // don't do anything if not enough characters 
    if (searchVal.length < minLength) { 
    return; 
    } 

    // start new timer 
    searchTimer = setTimeout(function() { 
    $content.unmark({ 
     done: function() { 
     $content.mark(searchVal, { 
      accuracy: "exactly", 
      separateWordSearch: false, 
      done: function() { 
      //Filter Results//$context.not(":has(mark)").hide(); 
      $results = $content.find("mark"); 
      currentIndex = 0; 
      jumpTo(); 
      } 
     }); 
     } 
    }); 
    }, searchDelay); 
}); 
+0

Спасибо! Кажется, это трюк. Возможно, мне нужно будет немного подкорректировать, чтобы замедлить работу там, где я хочу. Я ценю помощь. – bwoodruff1

0

Вам нужен таймер с задержкой. В принципе, когда пользователь нажимает клавишу, запустите таймер вместо прямого вызова функции поиска. Если пользователь снова нажмет клавишу, запустите таймер. Если таймер заканчивается, выполните поиск.

var searchHandler; 
var searchDelay = 300; 
$('input[type="search"]').on('keydown', function(e) { 
    if (searchHandler) 
    clearTimeout(searchHandler); 
}) 
$('input[type="search"]').on('keyup', function(e) { 
    $('#status').html('Waiting...'); 
    searchHandler = setTimeout(doSearch, searchDelay) 
}) 

doSearch = function() { 
    $('#status').html('Doing the search!'); 
} 

Рабочий пример: https://jsfiddle.net/mspinks/13uxa86p/2/

1

Вы можете вызвать функцию поиска по словам, как после нажатия Enter ключа и чем функция поиска вызовов.

Для примера:

$input.on("input", function(e) { 

    if (e.which == 13) { 
     var searchVal = this.value; 
     $content.unmark({ 
      done: function() { 
       $content.mark(searchVal, { 
        accuracy: "exactly", 
        separateWordSearch: false, 
        done: function() { 
         $results = $content.find("mark"); 
         currentIndex = 0; 
         jumpTo(); 
        } 
       }); 
      } 
     }); 
    } 
} 
0

Я просто написал небольшую функцию для вас:

function simpleDelayTimer() { 
 
    var delay = 2000; 
 
    var timer = null; 
 
    return { 
 
    start: 
 
    function() { 
 
     this.timer = setTimeout(function() { 
 
     alert('Put Code here'); 
 
     }, delay); 
 
     return timer; 
 
    }, 
 
    reset: function() { 
 
     clearTimeout(this.timer); 
 
    } 
 
    } 
 
} 
 
    
 
    var timer = simpleDelayTimer(); 
 
    
 
    
 
    function startTimer(){ 
 
    if (document.getElementById('timertest').value.trim() == "") 
 
     return; 
 
    
 
    timer.reset(); 
 
    timer.start(); 
 
    } 
 
    
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<label for="timertest">Type here </label> 
 
<input type="text" id="timertest" placeholder="2000ms timer" onkeyup="startTimer()" />

Вы можете поместить functin или код в функции тела «SetTimeout "

Смежные вопросы