<div class="container text-center">
  <div class="section section-title">
    <h2>二分查找算法</h2>
  </div>
  <div class="section input-section">
    <div class="col-md-4 col-md-offset-2 col-sm-6 col-sm-offset-3 col-xs-8 col-xs-offset-2">
      <div class="input-group generate">
        <input type="text" class="form-control input-lg" placeholder="10 - 100" id="generateInput">
        <div class="input-group-btn">
          <button class="btn btn-default btn-lg" id="generateButton">
        生成数组
      </button>
        </div>
      </div>

    </div>
    <div class="col-md-4 col-md-offset-1 col-sm-6 col-sm-offset-3 col-xs-8 col-xs-offset-2">
      <div class="input-group find">
        <input type="text" class="form-control input-lg" placeholder="1 - n" id="findInput" disabled>
        <div class="input-group-btn">
          <button class="btn btn-default btn-lg" type="submit" id="findButton" disabled>
        查找数字
      </button>
        </div>
      </div>
    </div>
  </div>

  <div class="col-xs-12 section array-section">
    <div class="number">1</div>
    <div class="number">2</div>
    <div class="number">3</div>
    <div class="number">...</div>
    <div class="number">n</div>
  </div>
</div>

<div id="repeatButton" class="repeatButton">
 <span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>
</div>
@mixin center {
  display: flex;
  justify-content: center;
  align-items: center;
}

html,
body {
  margin: 0 auto;
  box-sizing: border-box;
  background: #fcfcfc;
  font-family: 'Roboto', sans-serif;
}

.section {
  margin-top: 40px;
  margin-bottom: 40px;
}

.array-section {
  @include center;
  flex-wrap: wrap;
}

.input-group {
  margin: 5px;
}

.number {
  @include center;
  width: 40px;
  height: 40px;
  text-align: center;
  margin: 5px;
  padding: 5px;
  border: 1px solid gray;
  border-radius: 3px;
  background-color: transparent;
  transition: all 0.8s;
}

.error {
  background: rgb(202, 60, 60);
  color: white;
  border: 1px solid rgb(202, 60, 60);
  transition: 0.5s;
}

.success {
  background: rgb(28, 184, 65);
  color: white;
  border: 1px solid rgb(28, 184, 65);
  transition: 0.5s;
}

.repeatButton {
  display: none;
  width: 50px;
  height: 50px;
  position: fixed;
  top: 25px;
  right: 30%;
  border-radius: 25px;  
  color: #428bca;
  background-color: transparent;
  border: 2px solid #357ebd;
  text-align: center;
  transition: all 1s ease;
  z-index: 10;
  cursor: pointer;
    span {
      top: 0;
      line-height: 50px;
      font-size: 20px;
    }
}

.repeatButtonToggle {
  color: #fff;
  background-color: #428bca;
}
View Compiled
$(document).ready(function() {

  //buttons click handler functions
  $('#generateButton').on("click", generateArray);
  $('#findButton').on("click", findNumber);
  $('#repeatButton').on("click", repeat);
  
  //enable calling functions by 'enter' key
  $('#generateInput').keypress(function(e) {
    if (e.which == 13) {
      generateArray();
    }
  });
  $('#findInput').keypress(function(e) {
    if (e.which == 13) {
      findNumber();
    }
  });

  //functions
  // --- generateArray ---
  function generateArray() {
    //variables
    var $generateGroup = $('.generate');
    var $generateInput = $('#generateInput');
    var $generateInputVal = $generateInput.val();
    var $generateButton = $('#generateButton');
    var $findInput = $('#findInput');
    var $findButton = $('#findButton');
    var $arraySection = $('.array-section');
    //validation
    if ($.isNumeric($generateInputVal) && $generateInputVal >= 10 && $generateInputVal <= 100) {
      //set styling if success
      $generateGroup.removeClass('has-error');
      $generateButton.removeClass('error');
      $generateGroup.addClass('has-success');
      $generateButton.addClass('success');
      //remove styling after 2s
      setTimeout(function() {
        $generateGroup.removeClass('has-success');
        $generateButton.removeClass('success');
      }, 2000);      
      //disable generate input group
      $generateInput.prop('disabled', true);
      $generateButton.prop('disabled', true);
      //enable find input group
      $findInput.prop('disabled', false);
      $findButton.prop('disabled', false);
      //clear array section
      $arraySection.empty();
      //generate array = create divs and append them to array section
      for (var i = 0; i < $generateInputVal; i++) {
        var $number = $('<div>', {
          'class': 'number'
        });
        $arraySection.append($number.text(i + 1));
      }
    } else {
      // set styling if error
      $generateGroup.removeClass('has-success');
      $generateButton.removeClass('success');
      $generateGroup.addClass('has-error');
      $generateButton.addClass('error');
    }
  }  
  
// --- findNumber ---  
async function findNumber() {
    //variables
    var animationSpeed = 1000;
    var $generateInput = $('#generateInput');
    var $generateInputVal = $generateInput.val();
    var $findInput = $('#findInput');
    var $findInputVal = $findInput.val();
    var $findGroup = $('.find');
    var $findButton = $('#findButton');
    var min = 1;
    var max = parseInt($generateInputVal);
    var guess;     //console.log(min,max,parseInt($guessNumber.text()));
   console.log($generateInputVal, $findInputVal);
    //validation
    if ($.isNumeric($findInputVal) && $findInputVal >= 1 && $findInputVal <= max) {
      //set styling if success
      $findGroup.removeClass('has-error');
      $findButton.removeClass('error');
      $findGroup.addClass('has-success');
      $findButton.addClass('success');
      //remove styling after 2s
      setTimeout(function() {
        $findGroup.removeClass('has-success');
        $findButton.removeClass('success');
      }, 2000);    
    //disable find input group
      $findInput.prop('disabled', true);
      $findButton.prop('disabled', true);
    // --- binary search loop ---
    while (max >= min) {
      //compute guess as the average of max and min
      guess = Math.floor((min + max) / 2);
      var $guessNumber = $('.number:nth-child(' + guess + ')');
      //guessed number animation
      await sleep(animationSpeed);
 $guessNumber.css({'background-color': '#000', 'color':'#fff', 'font-weight':'bold'});
      await sleep(animationSpeed);
      //if guessed number equals find number then stop
      if (parseInt($guessNumber.text()) === parseInt($findInputVal)) {
        //found number animation
       $guessNumber.css({'color':'#fff', 'background-color':'#5cb85c','border': '3px solid #4cae4c', 'width':'42px','height':'42px'});
        //fade out all divs except guessed
        $('.number').not($guessNumber).css({'opacity':'0.4'});
        await sleep(animationSpeed*2);
        showRepeatButton();
        break;
        } 
        //if guessed number is to low, set new min value
      else if (parseInt($guessNumber.text()) < parseInt($findInputVal)) {
        //wrong number animation
        $guessNumber.css({'color':'#d43f3a', 'background-color':'#fcfcfc','border': '3px solid #d43f3a'});
        await sleep(animationSpeed);
        //fade out all divs <= guess        
$('.number').slice(min-1,parseInt($guessNumber.text())).css({'opacity':'0.4'});
        min = guess + 1; 
      }
        //if guessed number is to high, set new max value
      else { 
//wrong number animation
        $guessNumber.css({'color':'#d43f3a', 'background-color':'#fcfcfc','border': '3px solid #d43f3a'});
        await sleep(animationSpeed);
        //fade out all divs >= guess
$('.number').slice(parseInt($guessNumber.text())-1,max).css({'opacity':'0.4'});
        max = guess - 1;
      }
    }
      }
    else {
      // set styling if error
      $findGroup.removeClass('has-success');
      $findButton.removeClass('success');
      $findGroup.addClass('has-error');
      $findButton.addClass('error');
    }
  } 

  function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function showRepeatButton() {
  var $repeatButton = $('.repeatButton');
  $repeatButton.fadeIn('slow');
$repeatButton.toggleClass('repeatButtonToggle');
  setInterval(function(){  $repeatButton.toggleClass('repeatButtonToggle');
  }, 1000);
}

// --- repeat function ---
  function repeat() {
    //variables
    var $generateInput = $('#generateInput');
    var $generateButton = $('#generateButton');
    var $findInput = $('#findInput');
    var $arraySection = $('.array-section');
    var $repeatButton = $('.repeatButton');
    //enable find input group
    $generateInput.prop('disabled', false);
    $generateButton.prop('disabled', false);
    //clear array section
    $arraySection.empty();
    //hide repeat button
    $repeatButton.fadeOut('slow');
    //clear inputs
    $generateInput.val('');
    $findInput.val('');
  }
  
});
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js