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>