Обработчик сворачивания срабатывает несколько раз для динамически генерируемого мобильного сворачиваемого списка jQuery.

Я пытаюсь динамически заполнять и устанавливать обработчики свертывания/развертывания для складного списка в jQuery Mobile. Обработчик развертывания работает должным образом, но обработчик свертывания срабатывает один раз для каждого элемента в списке при развертывании элемента.

<head>
    <link rel="stylesheet" href="jquery.mobile-1.2.0-alpha.1.css?gfd" />
    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script src="http://jquerymobile.com/demos/1.2.0-alpha.1/js/jquery.mobile-1.2.0-alpha.1.js"></script>
</head>
<script>
    $(document).ready(function () {

        for (var i = 0; i < 4; i++) {

            var element = $("#listElementTemplate").clone();

            element.find('h3').append("list Element: " + i);
            $("#list").append(element);

            element.on('expand', function () {
                alert("expand: "+i);
            });

            element.collapsible();

            element.on('collapse', function () {
                alert("collapse: "+i);
            });
        }
    });
</script>

<body>
    <div id='listElementTemplate' data-role="collapsible" data-collapsed='true'>
            <h3 class='chart-elem-data'>
    </h3>

        <p id=''>Content</p>
    </div>
    <div data-role="page" class="type-interior">
        <div data-content-theme="c" id="list" data-role="collapsible-set"></div>
    </div>
</body>


person Ben Pearce    schedule 11.05.2013    source источник


Ответы (2)


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

Это некрасиво, но, похоже, работает.

 $(document).ready(function () {
   //Create element name variable
   var elementName;
    for (var i = 0; i < 4; i++) {
        (function (i) {
            var element = $("#listElementTemplate").clone();
            //Use index to create unique name attribute
            element.attr("name",count);
            element.find('h3').append("list Element: " + i);
            $("#list").append(element);

            element.on('expand', function () {
                //On expand set element name to name of expanded element
                elementName = $(this).attr("name");
            });

            element.collapsible();

            element.on('collapse', function(){
                      //Use conditional logic only trigger code on the previously expanded element
              if (elementName == $(this).attr("name")){
                      //code to execute
              }else{
                          //Leave empty
                           }
    });
    }
});
person Ben Pearce    schedule 17.05.2013

Такое поведение не является ошибкой.

Подумайте об этом, у вас есть складной набор из 4 складных элементов. Одновременно можно расширить только один. Поэтому, когда один расширяется, другой вызывает событие коллапса. Повторяю, это набор, поэтому они действуют как набор.

Если вы не хотите, чтобы они вели себя так, вам понадобится складной набор для каждого складного элемента. Но в этом случае, если вы израсходуете еще один складной, первый все равно останется сложенным.

Рабочий пример: http://jsfiddle.net/Gajotres/AXhkF/

HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>jQM Complex Demo</title>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>    
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
        <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>      
    </head>
    <body>  
        <div data-content-theme="c" id="list" data-role="collapsible-set">
            <div id='listElementTemplate' data-role="collapsible" data-collapsed='true'>
                <h3 class='chart-elem-data'></h3>
                <p id=''>Content</p>
            </div>
        </div>        
        <div data-role="page" id="type-interior">

        </div>      
    </body>
</html>    

JS:

$(document).on('pagebeforeshow', '#type-interior', function(){       
    for (var i = 0; i < 4; i++) {
        var element = $("#list").clone().attr('id','list'+i);
        element.find('[data-role="collapsible"]').attr('id','element'+i);
        element.find('h3').append("list Element: " + i);
        element.appendTo('[data-role="page"]');

        $(document).on('expand', '#element'+i ,function (e) {
            if(e.handled !== true) // This will prevent event triggering more then once
            {
                console.log('expand = '+  $(this).attr('id'));
                e.handled = true;
            }
        });

        $(document).on('collapse', '#element'+i,function (e) {
            if(e.handled !== true) // This will prevent event triggering more then once
            {            
                console.log('collapse = ' + $(this).attr('id'));
                e.handled = true;
            }
        });

        $('#element'+i).collapsible();        
    }        
});

Опять же, вы можете вручную свернуть все остальные складные элементы во время события расходования, но тогда вы столкнетесь с той же ситуацией, что и в вашем примере.

В общем, тут ничего не поделаешь.

person Gajotres    schedule 11.05.2013