Javascript предотвращает дефолт () игнорируется

Поэтому я попытался найти решение своей проблемы, но оно кажется уникальным для других вопросов о protectDefault(), которые я видел в SO и Google. Это также может быть слишком узким, но если у кого-то есть какие-либо советы по отладке, они также будут оценены.

У меня есть сайт, который показывает разные "закладки" видео для пользователей, которые могут кликать по ним и изменять время воспроизведения / видео во время воспроизведения в div на странице. Есть 3 места, где пользователь может сделать это. Слева находится меню, отображающее "10 самых последних просмотренных видео", справа - дерево топологии на основе D3.js, а вверху - окно поиска, построенное из django-autocomplete-light. Все три метода используют одну и ту же функцию javascript (playvid) для изменения видео и обновления информации метаданных на веб-странице. Например, пользователь щелкает ссылку и переходит к минуте 4 видео 1, затем нажимает другую ссылку и переходит к минуте 9 видео 45.

Когда я реализовал это на своей машине для разработки, все три метода работали с FF 18 и Safari 6 (Django 1.4.3, Python 2.7.3, работающий с веб-сервером Django). Затем я помещаю его на рабочий сервер (Django 1.4.3, Python 2.6.6, Apache / mod_wsgi). Теперь метод с окном поиска django-autocomplete-light не работает, а два других - работают! Я предполагаю, что разные версии Python не должны быть виновником...? Код автозаполнения был таким же, как и мой код разработки, но теперь кажется, что это какая-то проблема с javascript с функцией protectDefault()? Однако после нескольких часов отладки я не могу понять, где и почему, поскольку код, похоже, просто игнорирует мой e.preventDefault(); вызовите... вот мой /navigation_autocomplete/script.html код, который фиксирует то, что пользователь нажимает в окне поиска автозаполнения (хотя я чувствую, что проблема заключается в javascript, а не именно в этом модуле Django):

{% load url from future %}

<script type="text/javascript">
$(document).ready(function() {
    $('#navigation_autocomplete').yourlabsAutocomplete({
        url: '{% url 'navigation_autocomplete' %}',
        choiceSelector: 'a',
    }).input.bind('selectChoice', function(e, choice, autocomplete) {
        e.preventDefault();
        e.stopImmediatePropagation();
        var URL = choice.attr('href');
        alert('this should not follow the link!!');
        playvid(URL);
        return false;
    });
});
</script>

Alert() появляется в FF и Safari, и, используя Firebug, я вижу, что браузер пытается загрузить playvid(), но затем переходит по ссылке -e.preventDefault(); полностью игнорируется. Как видите, я тоже пытался прекратить пузыриться (отчаянно), но безуспешно.

У кого-нибудь есть идеи о том, почему мой код protectDefault() может быть проигнорирован в этом одном конкретном методе, но он отлично работает в других моих вызовах (особенно, когда он работал нормально при разработке для всех 3 методов)? Или советы по отладке, как отследить это?

Спасибо!

===========

Обновить

Я попробовал решение jpic, но оно не работает... вот новый блок кода (может быть, я что-то жирный нажал...):

<script type="text/javascript">
$(document).ready(function() {
    $('#navigation_autocomplete a').on('click', function(e) {e.preventDefault(); });
    $('#navigation_autocomplete').yourlabsAutocomplete({
        url: '/video_search/navigation/',
        choiceSelector: 'a',
    }).input.bind('selectChoice', function(e, choice, autocomplete) {
        var URL = choice.attr('href');
        alert('this should not follow the link!!');
        playvid(URL);
        return false;
    });
});
</script>

1 ответ

Решение

Нечеткая реализация

Ваш код запрещает использование по умолчанию для selectChoice, но не для клика!

Автозаполнение объектов вызывает selectChoice на input элемент, когда выбор выбирается с помощью мыши или клавиатуры. Это не портит click событие. Если вы не хотите браузер по умолчанию click событие, то зачем использовать <a>?

Альтернативное предложение по реализации

Вы можете сделать шаблон автозаполнения следующим образом:

{% for video in video_qs %}
<span class="div choice" data-href="{{ video.get_absolute_url }}">{{ video }}</span>
{% endfor %}

С такими js:

<script type="text/javascript">
$(document).ready(function() {
    $('#navigation_autocomplete')
        .yourlabsAutocomplete({
            url: '{% url 'navigation_autocomplete' %}',
            choiceSelector: '.choice',
        }).input.bind('selectChoice', function(e, choice, autocomplete) {
            playvid(choice.data('href'));
        });
});
</script>

Эта простота по дизайну - моя любимая функция в django-autocomplete-light.

Исправление нечеткой реализации в любом случае

Если вы действительно нуждаетесь в unclickable <a> теги, то вы можете использовать jQuery on()т.е.

$('#navigation_autocomplete').on('click', 'a', function(e) { e.preventDefault(); });

Пример:

<script type="text/javascript">
$(document).ready(function() {
    $('#navigation_autocomplete')
        .on('click', 'a', function(e) { e.preventDefault(); })
        .yourlabsAutocomplete({
            url: '{% url 'navigation_autocomplete' %}',
            choiceSelector: 'a',
        }).input.bind('selectChoice', function(e, choice, autocomplete) {
            var URL = choice.attr('href');
            playvid(URL);
        });
});
</script>
Другие вопросы по тегам