javascript preventDefault()被忽略

时间:2013-01-28 11:36:53

标签: javascript django preventdefault django-autocomplete-light

所以我试图找到解决我的问题的方法,但是我在SO和Google上看到的其他preventDefault()问题似乎是独一无二的。它也可能有点过于狭窄,但如果有人有任何调试技巧,那些也会受到赞赏。

我有一个网站向用户显示不同的视频“书签”,用户可以点击它们并更改视频/搜索时间在页面上的div中播放。用户可以执行此操作的3个位置。左边是显示“最近观看的前10个视频”的菜单,右边是基于D3.js的拓扑树,顶部是一个由django-autocomplete-light构建的搜索框。这三种方法都使用相同的javascript函数(playvid)来更改视频并更新网页上的元数据信息。例如,用户单击一个链接,然后转到视频1的第4分钟,然后单击另一个链接,并转到视频45的第9分钟。

当我在我的开发机器上实现它时,所有三种方法都适用于FF 18和Safari 6(Django 1.4.3,Python 2.7.3,运行Django的Web服务器)。然后我把它放到生产服务器上(Django 1.4.3,Python 2.6.6,Apache / mod_wsgi)。现在使用django-autocomplete-light的搜索框的方法不起作用,但另外两个,做!我假设不同的Python版本不应该是罪魁祸首......?自动完成代码与我的开发代码相同,但现在看起来像preventDefault()的某种javascript问题?经过几个小时的调试,我无法弄清楚在哪里以及为什么,因为代码似乎只是忽略了我的e.preventDefault(); call ...这是我的/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>

在FF和Safari中弹出alert(),使用Firebug,我可以看到浏览器尝试加载playvid()但是后面跟着链接 - e.preventDefault();完全被忽略了。正如你所看到的,我也试图阻止冒泡(变得绝望),但没有运气。

有没有人知道为什么我的preventDefault()代码可能在这个特定的方法中被忽略,但它在我的其他调用中工作正常(特别是当它在开发中适用于所有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 个答案:

答案 0 :(得分:0)

模糊实现

您的代码会阻止selectChoice 的默认,但不会阻止点击!

当通过鼠标或键盘选择选项时,自动完成对象会触发input元素上的selectChoice。它不会弄乱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中最喜欢的功能。

无论如何修复模糊实现

如果你真的需要不可点击的<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>