【问题标题】:Click event executes both click and hover event handler even when the click event handler unbinds all handlers即使单击事件处理程序取消绑定所有处理程序,单击事件也会执行单击和悬停事件处理程序
【发布时间】:2016-03-06 03:35:26
【问题描述】:

我正在编写井字游戏。在用户选择谁开始以及是否使用 X 或 O 后,他可以将鼠标悬停在一个空的网格上,X 或 O 会出现,向用户显示他可以移动到那里。当用户点击他想要继续移动的网格时,X 或 O 将保留在那里并且移动将是永久的。目前我有这个工作,但以一种非常奇怪的方式。代码如下:

$('td').hover(moveHover);
$('td').mouseleave(function(){
    $(this).html('');
});
$('td').click(move);

function move(){
    $(this).unbind();
}   

function moveHover(){
    if (xO === 'X'){
        $(this).append('<i class="fa fa-times fa-5x"></i>');
        $('td i').css('color', '#ccc');
    }
    if (xO === 'O'){
        $(this).append('<i class="fa fa-circle-o fa-5x"></i>');
        $('td i').css('color', '#ccc');
    }       
}

点击事件处理程序仅解除元素与任何点击事件处理程序的绑定。它实际上并没有将 X 或 O 图标附加为子元素。但是,当我单击一个空网格时,它确实会附加一个图标。这是link 的所有代码,如果您想自己尝试一下。我想知道这怎么可能?

【问题讨论】:

    标签: javascript jquery events event-handling


    【解决方案1】:

    您现在所做的是在悬停时追加并在取消悬停时删除:

    $('td').mouseleave(function() {
        $(this).html('');
    });
    

    单击后,您已经将鼠标悬停,因此会附加 X 或 O。 但是你还没有取消悬停(鼠标离开),所以它还没有被移除。当您现在单击并因此取消绑定所有内容时,您也会取消绑定 mouseleave,因此它永远不会再次被删除。

    这实际上是一个非常聪明的解决方案。

    也为图片点赞!

    【讨论】:

    • 感谢老实说​​我偶然发现了它。最初我让 move 函数与 moveHover 函数相同,并且在它的末尾还有$(this).unbind();。但是当我测试它时,点击一个网格会产生 2 个 X 或 O。所以我尝试在函数中只使用$(this).unbind();,这就是我让代码看起来像现在这样的方式。
    【解决方案2】:

    这是一个 CSS 问题,代码使用 BootstrapFont-Awesome CSS 样式,我已在此处将代码附加到 sn-p 中(单击下面的“运行”按钮),看看它是否正常工作。 :)

    $(document).ready(function() {
      var xO = '';
      var xOClass = '';
      var whoStart = '';
      var option1 = $('.option1').html();
      var option2 = $('.option2').html();
      var choice = $('.choice').html();
    
      $('.choose').click(choose);
    
      function choose(e) {
        e.preventDefault();
        if ($('.choice h2').text() === 'Who starts?') {
          whoStart = $(this).children('p').text().substr(0, $(this).children('p').text().indexOf(' '));
          $('.option1 p, .option2 p').empty();
          $('.choice h2').remove();
          $('.choice').prepend('<a href="#" class="restart"><h2>Restart Game</h2></a>');
          $('.restart').hover(function() {
            $('.restart h2').css('color', '#000');
          });
          $('.restart').mouseleave(function() {
            $('.restart h2').css('color', '#777');
          });
          $('.restart').click(restart);
          $('.option1 a').remove();
          $('.option2 a').remove();
          $('.choice').css('height', '100px');
          $('td').hover(moveHover);
          $('td').mouseleave(function() {
            $(this).html('');
          });
          $('td').click(move);
        }
        if ($('.choice h2').text() === 'X or O?') {
          xO = $(this).children('p').text().substr(13);
          $('.choice h2').text('Who starts?');
          $('.option1 i').removeClass('fa-times').addClass('fa-laptop');
          $('.option1 p').text('Computer starts');
          $('.option2 i').removeClass('fa-circle-o').addClass('fa-user');
          $('.option2 p').text('Player starts');
        }
      }
    
      function restart(e) {
        e.preventDefault();
        $('.option1').empty().html(option1);
        $('.option2').empty().html(option2);
        $('.choice').empty().html(choice);
        $('.choose').click(choose);
        $('td').unbind();
        $('td').empty();
      }
    
      function move() {
        $(this).unbind();
      }
    
      function moveHover() {
        console.log(xO, this);
        if (xO === 'X') {
          $(this).append('<i class="fa fa-times fa-5x"></i>');
          $('td i').css('color', '#ccc');
        }
        if (xO === 'O') {
          $(this).append('<i class="fa fa-circle-o fa-5x"></i>');
          $('td i').css('color', '#ccc');
        }
      }
    });
    h1,
    .col-xs-4,
    .col-xs-12 {
      text-align: center;
    }
    
    h1,
    h2 {
      color: #777;
    }
    
    a {
      color: #777;
    }
    
    td {
      width: 150px;
      height: 150px;
    }
    
    table {
      width: 450px;
      margin: 0 auto;
    }
    
    .middle {
      box-shadow: 0 -1px 0 #777, 0 1px 0 #777;
    }
    
    .center {
      box-shadow: -1px 0 0 #777, 1px 0 0 #777;
    }
    
    .middle.center {
      box-shadow: 0 -1px 0 #777, 0 1px 0 #777, -1px 0 0 #777, 1px 0 0 #777;
    }
    
    a:hover,
    a:focus,
    a:active {
      color: #000;
      text-decoration: none;
    }
    
    .container {
      min-width: 500px;
    }
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <div class="container">
      <h1>Tic Tac Toe</h1>
      <div class="row">
        <div class="col-xs-4 option1">
          <a href="#" class="choose">
            <i class="fa fa-times fa-5x"></i>
            <p>I want to be X</p>
          </a>
        </div>
        <div class="col-xs-4 choice">
          <h2>X or O?</h2>
        </div>
        <div class="col-xs-4 option2">
          <a href="#" class="choose">
            <i class="fa fa-circle-o fa-5x"></i>
            <p>I want to be O</p>
          </a>
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <table>
            <tr>
              <td class="top left"></td>
              <td class="top center"></td>
              <td class="top right"></td>
            </tr>
            <tr>
              <td class="middle left" id=></td>
              <td class="middle center"></td>
              <td class="middle right"></td>
            </tr>
            <tr>
              <td class="bottom left"></td>
              <td class="bottom center"></td>
              <td class="bottom right"></td>
            </tr>
          </table>
        </div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 2015-12-22
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 1970-01-01
      • 2015-01-17
      • 2022-01-24
      • 2013-08-06
      • 2020-02-15
      相关资源
      最近更新 更多