Событие jQuery onclick работает некорректно при изменении DOM

0

Мне сложно понять jQuery (v1.11) в отношении событий и как взаимодействие DOM влияет на эти события.

Настройка:

Я создаю сетку встроенных блоков с буквой класса и отслеживаю клики:

$('.letter).on('click',function(){ // do something })

Когда я нажимаю на один, он расширяется до размера его родительского контейнера.

Проблема:

Несмотря на то, что я удаляю букву класса, div все еще реагирует на события кликов. В идеале я хочу расширить div, чтобы показать больше информации, а затем позволить ему сместиться на место, когда пользователь будет выполнен.

Вот мой html, и скрипка внизу.

<!DOCTYPE html>
<html lang="en-US">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Test</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <style type="text/css">
        /* apply a natural box layout model to all elements */
        *, *:before, *:after {
          -moz-box-sizing: border-box; 
          -webkit-box-sizing: border-box; 
          box-sizing: border-box;
        }
        .square { 
            font-size: 20px;
            color: white;
            padding: 5px;
            display: inline-block;
            background-color: #69f;
            height: 50px;
            width: 50px;
            vertical-align: top;
        }
        .grid {
            width: 390px;
            padding: 5px;
            }
        .row { padding-top: 5px; }
        .square.empty { background-color: #87afff; }
        .square-highlight { background-color: #36f; }
    </style>
    </head>
    <body>
    <!-- begin content -->
    <div class="grid">
        <div class="rows">
            <div class="row">
                <div class="square empty"></div>
                <div class="square empty"></div>
                <div class="square empty"></div>
                <div class="square empty"></div>
                <div class="square empty"></div>
                <div class="square empty"></div>
                <div class="square letter">a</div>
            </div>
            <div class="row">
                <div class="square letter">b</div>
                <div class="square letter">c</div>
                <div class="square letter">d</div>
                <div class="square letter">e</div>
                <div class="square letter">f</div>
                <div class="square letter">g</div>
                <div class="square letter">h</div>
            </div>
            <div class="row">
                <div class="square letter">i</div>
                <div class="square letter">j</div>
                <div class="square letter">k</div>
                <div class="square letter">l</div>
                <div class="square letter">m</div>
                <div class="square letter">n</div>
                <div class="square letter">o</div>
            </div>
            <div class="row">
                <div class="square letter">p</div>
                <div class="square letter">q</div>
                <div class="square letter">r</div>
                <div class="square letter">s</div>
                <div class="square letter">t</div>
                <div class="square letter">u</div>
                <div class="square letter">v</div>
            </div>
            <div class="row">
                <div class="square letter">w</div>
                <div class="square letter">x</div>
                <div class="square letter">y</div>
                <div class="square letter">z</div>
                <div class="square empty"></div>
                <div class="square empty"></div>
                <div class="square empty"></div>
            </div>
        </div>
    </div>
</body>
  <script type="text/javascript" charset="utf-8">
    $(document).ready(function(){

        $('.letter').hover(function(){
            $(this).addClass('square-highlight');
        },function(){
            $(this).removeClass('square-highlight');
        });

        $(".letter").not('.large').on('click',function(){
            $(this)
                .addClass('large')
                .css('position','absolute')
                .stop()
                .animate({
                    height: $('.rows').height()-5, 
                    width: $('.rows').width(),
                    top: $('.rows').position().top+5,
                    left: $('.rows').position().left
                },"fast")
                .append('<input type="button" name="Save" value="save" />');
        });
        $(".large").on('click',function(){
            alert('test');
        });
    });
  </script>
</html>

Вот моя скрипка: http://jsfiddle.net/aKpLQ/

Теги:
dom

4 ответа

0

Я обычно использую делегирование событий для такого рода вещей, вот пример, близкий к вашей разметке:

$('.rows').on('click',function(e){

var $tar = $(e.target);
 if($tar.is('.letter')){
    if($tar.is('.large')){
        // Do Stuff
    } else {
        // Do other stuff
    }
});

И это также будет работать, если вы добавите или удалите ".letter" в своем списке, что очень круто.

0

Я обновил ваш jsfiddle http://jsfiddle.net/aKpLQ/1/, чтобы он работал. Я предлагаю вам принять шаблон создания и уничтожения элемента div каждый раз, когда пользователь нажимает на него. Это позволит вам получить большую гибкость, не мешая вам существующим строкам. Но в любом случае это тоже работает, просто может стать голова, если вы пытаетесь сделать больше вещей. Убедитесь, что вы помните event.currentTarget, это очень полезно, когда вы пытаетесь выяснить, какой элемент вызвал событие.

Вот часть кода, если вы слишком ленивы, чтобы нажать на ссылку;)

$(document).ready(function(){

        $('.letter').hover(function(){
            $(this).addClass('square-highlight');
        },function(){
            $(this).removeClass('square-highlight');
        });

        $(".letter").on('click',function(e){
            if(!$(e.currentTarget).hasClass("large")){
            $(e.currentTarget)
                .addClass('large')
                .css('position','absolute')
                .css('z-index','100')
                .stop()
                .animate({
                    height: $('.rows').height()-5, 
                    width: $('.rows').width(),
                    top: $('.rows').position().top+5,
                    left: $('.rows').position().left
                },"fast")
                .append('<input type="button" name="Save" value="save" />');
            }
        });
        $(".large").on('click',function(){
            alert('test');
        });
    });
0

События согласовываются один раз на готовом документе, когда ни один из них не имеет класса большой, поэтому событие с большим селектором не будет работать. Вы можете проверить, имеет ли элемент класс большой onClick http://jsfiddle.net/84gba/1/

    $(".letter").on('click',function(){
        if($(this).hasClass('large'))
        {
         alert("test");   
        }
        else
        {
        $(this)
            .addClass('large')
            .css('position','absolute')
            .css('z-index','100')
            .stop()
            .animate({
                height: $('.rows').height()-5, 
                width: $('.rows').width(),
                top: $('.rows').position().top+5,
                left: $('.rows').position().left
            },"fast")
            .append('<input type="button" name="Save" value="save" />');
        }
    });
0

Событие click привязано к элементу во время $(document).ready используя селектора и состояние элементов в это время. Изменение класса элемента не изменяет события, привязанные к нему.

Чтобы изменить событие, вам нужно отменить событие click и связать его с новым событием. В качестве альтернативы вы можете использовать одну и ту же функцию обработчика событий с условным выражением, которое ведет себя по-разному в зависимости от текущего состояния элемента. Что-то вроде:

$(".letter").on('click',function(){
  if($(this).hasClass('large')){
    alert('test');
    $(this).removeClass('large');
  } else
    $(this)
      .addClass('large')
      .css('position','absolute')
      .stop()
      .animate({
        height: $('.rows').height()-5, 
        width: $('.rows').width(),
        top: $('.rows').position().top+5,
        left: $('.rows').position().left
      },"fast")
      .append('<input type="button" name="Save" value="save" />');
  });

Ещё вопросы

Сообщество Overcoder
Наверх
Меню