2016-08-02 4 views
0

Я пытаюсь использовать функцию pushPage() функции OnsenUI 2 (rc15 на данный момент). Наряду с OnsenUI, я использую JQuery 3.Перемещение со страницы на страницу создает ошибки (дубликаты?)

Вот моя функция, которая при нажатии определенных элементов следует нажать на странице:

$(".tile_handler").on("click", ".imalink", function() { 
    var link = $(this).data().href; 
    if(link != null){ 
     document.querySelector("#myNavigator").pushPage(link, { animation: "slide-ios" }); 
    } 
}) 

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

[index.js: 450] Неиспользованный (в обещании) pushPage уже запущен.

Вот еще одна функция, которая должна загружать разделительные страницы:

$(".splitter_item").click(function() { 
    var address = $(this).data('address'); 
    $('#content')[0].load(address).then(menu.close.bind($('#menu')[0])); 
}) 

При переключении между двумя страницами через Splitter он начинает бросать это (и больше каждый раз, когда я переключаться между страницами)

[undefined: 1] Uncaught (в обещании) Сторона сплиттера заблокирована.


Что я предполагаю, что происходит, что я загрузить страницу, оставьте его, и когда я достигаю его снова, снова загружает страницу. Однако это не кажется, что поведение показано в примерах OnsenUI таких as this:

document.addEventListener('init', function(event) { 
    var page = event.target; 

    if (page.id === 'page1') { 
    page.querySelector('#push-button').onclick = function() { 
     document.querySelector('#myNavigator').pushPage('page2.html', {data: {title: 'Page 2'}}); 
    }; 
    } else if (page.id === 'page2') { 
    page.querySelector('ons-toolbar .center').innerHTML = page.data.title; 
    } 
}); 

Существует popPage() функции, которая должна удалить ранее загруженную страницу и будет препятствовать этому. Но ссылки не используют его, поэтому я предполагаю, что я делаю что-то неправильно. Но я не знаю, что.


UPDATE:

мне удалось воспроизвести обе проблемы в CodePen. Here - ошибка Splitter, а here - это pushPage(). Кажется, что pushPage() - проблема с моей функцией, поскольку она добавляет запрос pushPage() каждый раз, когда я нажимаю на него, но не знаю, почему.

Обе ошибки, похоже, происходят только в эмуляторе Ripple (через VS2015). Кажется, я не могу воспроизвести их в Android-эмуляторе (но код $(".tile_handler").on("click", ".imalink", function() { в любом случае срабатывает неоднократно). Я тестирую это дальше.

+0

Вы можете перетаскивать одну и ту же страницу снова и снова без проблем. Я сделал быстрый код: https://codepen.io/anon/pen/NALzWZ, который демонстрирует это. Кнопка «Назад» выполняет popPage(), но, как вы можете видеть, я снова и снова запускаю один и тот же шаблон page2.html в стек навигации. Обычно, когда я получаю эту ошибку или вижу ее, происходит что-то еще. – Munsterlander

+0

Это происходит только на iOS или в браузере? Также, если вы используете анимацию 'fade-ios'? –

+0

Я немного недоукомплектован, поэтому у меня есть только эмуляторы для работы. Это происходит в Ripple Emulator на Android и iOS. Я добавил CodePen, воспроизводя ошибку. – rancor1223

ответ

1

Обе ошибки, о которых вы упоминаете, на самом деле являются надежной мерой от толкания или выполнения какого-либо действия дважды по ошибке, если вы дважды щелкните по кнопке/ссылке, например.

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

Вот демоверсия с вашим точным кодом как для splitter, так и для navigator.

Таким образом, ошибка не исходит из кода, который вы предоставили, где-то в другом месте.

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

Альтернативой, хотя и очень важно, чтобы вы сделали это, прежде чем выполнять свое действие. Это, однако, не решает проблему, а лишь маскирует ее. И, конечно же, со всеми хаками - это может сломаться в будущих версиях.

myNavigator._isRunning = false; 

UPDATE:

Вот два обновленных ручки, которые вы дали в комментариях: https://codepen.io/IliaSky/pen/YWOOkW?editors=1010 https://codepen.io/IliaSky/pen/QEVVGm?editors=1010

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

Добавить вещи, как:

if (e.target.id == 'pagename') ... 

или просто

$(document).on("init", '#dashboard_page', function(){ ... } 
+0

А, это помогает. Кажется, что моя функция продолжает добавлять все больше запросов к 'pushPage()' каждый раз, когда я нажимаю плитку. Однако я понятия не имею, почему. И я не думаю, что это объясняет брэдж Сплиттера, который я вижу, поскольку я использую 'load()' там (я попытаюсь воспроизвести это в CodePen тоже). – rancor1223

+0

Добавлена ​​CodePen для Splitter. – rancor1223

+0

ok Я знаю причину - в ближайшее время я обновлю свой ответ. в основном вы добавляете все больше обработчиков событий, которые добавляются каждой страницей. Таким образом, вы все чаще вызываете 'load' и' pushPage'. :) –

2

В основном каждый раз, когда вы нажимаете на страницу, эта страница Запускает init событие. Однако Onsen все еще сохраняет начальную страницу в dom.

Навигатор пример (та же логика применима и к сплиттер один):

<ons-navigator> 
    <ons-page id="dashboard"> 
    <div class="imalink" data-href="request_list.html"></div> 
    </ons-page> 
</ons-navigator> 

У вас есть событие инициализации для приборной панели. Затем вы нажимаете на плитку и переходите на другую страницу. Затем request_list стреляет собственным init события. Однако наша начальная страница все еще находится в доме.

<ons-navigator> 
    <ons-page id="dashboard" style="display: none"> 
    <div class="imalink" data-href="request_list.html"></div> 
    </ons-page> 
    <ons-page id="request_list"> 
    ... 
    </ons-page> 
</ons-navigator> 

У вас есть что-то вроде этого. Однако следующий вызов называется вторым раз:

$(".tile_handler").on("click", ".imalink", function() { 
    ... 
}) 

Который добавляет слушателей еще раз. $el.on("click") как псевдоним addEventListener, что означает, что вы добавляете все больше и больше слушателей.

Поэтому всякий раз, когда вы перемещаетесь, вы добавляете их, потому что начальная страница никогда не удалялась из dom.

Альтернативные решения:

  1. Используйте только текущей страницы (e.target)

    $('selector') // instead of this 
    $(e.target).find('selector') // use this 
    

    Таким образом, можно ограничить только найти элементы внутри страницы, которую вы только что создали.

  2. Включить обработчики с самого начала. Поскольку вы используете jQuery, на самом деле существует более простой способ делать вещи, не полагаясь на событие init.

    Просто делать это вне любого обработчика INIT:

    $(document).on("click", ".tile_handler .imalink", function() { ... }) 
    

    Это фактически означает, что обработчик прилагается к документу себя и обработчик будет вызываться только тогда, когда цель .tile_handler .imalink - так она работает с любым будущие imalinks, которые вы создаете.

    Возможно, это не самый эффективный подход, но, безусловно, один из самых простых.

+0

Теперь я понимаю. Спасибо! – rancor1223