Ajax请求成功,但无论如何都会继续到目标url

Ajax request succeeds but continues on to the target url regardless

本文关键字:继续 目标 url 无论如何 请求 成功 Ajax      更新时间:2023-09-26

我正在开发一个页面,该页面在div中包含各种Youtube视频缩略图,每个<img>都有链接,容器上有Masonry来控制类切换以调整所选视频的大小。

其想法是点击div,这会触发砖石结构来更改CSS,还会触发对django的.ajax()请求,django会返回所选视频的模板。(当您再次选择它以返回缩略图模板并使用Masonry重置为正常时,将执行相反的操作(。

目前,我有两个javascript函数,一个触发div上的砖石,另一个触发视频链接上的ajax请求;

<script>
(function($) {
    $(document).ready(function() {
        var container = $('.masonry'), masonry;
        //masonry = new Masonry(container[0]);
        container.masonry('stamp', container.find('.stamp'));
        container.unbind('click').on('click', '.item', function() {
            var $this = $(this),
                this_link = $this.find('a'),
                $this_link = $(this_link),
                this_href = $this_link.attr('href'),
                video_id = $this.attr('data-video-id'),
                gigante = $this.hasClass('gigante'),
                selector = 'div#panel-area.video_grid div.masonry div.item.' + video_id;
            $.ajax({
                type: "GET",
                async: false,
                url: this_href,
                timeout: 5000,
                data: {'g': gigante},
                dataType: 'html',
                success : function(data) {
                    $(selector).html(data);
                    container.find('.item').removeClass('gigante');
                    $(this).toggleClass('gigante', !gigante);
                    container.masonry();
                    console.log('Selector: ' + selector + ''nSuccess');
                }
            })
            .done(function(msg){
                console.log('Done: ' + msg);
            })
            .fail(function(jqXHR, textStatus){
                console.log('Failed: ' + textStatus);
            });
        });
    });
})(jQuery);    </script>

以及HTML;

<div class="masonry js-masonry" data-masonry-options='{ "stamp": ".stamp", "isOriginLeft": false }'>
    <div class="mpus stamp">            
    </div>
    <div class="item video {{ object.id }}" data-video-id="{{ object.id }}">
        <a class="GetYoutubeVideo" href="{% url 'show_video' video_id=object.id %}">
            <i class="icon-play-circled play"></i>
            <span class="title">
                {{ object.get_title|slice:":20" }}...<br/>
                {{ object.date_created|date:"d/m/Y" }}
            </span>
            {{ object.get_img_tag }}
        </a>
    </div>
</div>

我本质上是一个javascript新手,所以我相信这是一个非常基本的问题。当我在禁用async的情况下通过chrome dev工具运行此操作时,我看到ajax请求返回了预期的内容,但最终出现在目标页面上,而不是像预期的那样将内容加载到$(selector)中。当我启用async时,它会立即失败。我已经看了很长时间的文档,但我觉得我没有任何进展。如有任何帮助,我们将不胜感激。

要避免默认的点击操作,请按如下方式修改您的点击处理程序:

.on('click', '.item', function(e) {
    var ...
    e.preventDefault();
    $.ajax({
        ...
    )}
    ...
})

e添加到单击处理程序函数中意味着在函数中可以获得事件详细信息——在e对象上,您运行preventDefault()方法来防止默认操作发生——例如,超链接将不再导航到其目标。

事件通常以以下方式发生,尽管这不是一个深入的总结:

a元素上会发生单击事件。

单击事件开始搜索事件处理程序。如果在导致该事件的元素上找不到,则该事件将在DOM树上"冒泡",一次一级,直到它到达根DOM元素而无法继续,或者找到单击处理程序。

在任何时候,如果找到一个点击处理程序,那么点击处理程序中的代码就会被执行。如果单击处理程序在事件对象上设置preventDefault(),或返回false,则不采取进一步的操作。

如果单击处理程序既不返回false也不设置preventDefault(),那么除了您自己的事件处理程序外,还会执行原始浏览器默认操作。

修改后的完整代码:

<script>
(function($) {
    $(document).ready(function() {
        var container = $('.masonry'), masonry;
        //masonry = new Masonry(container[0]);
        container.masonry('stamp', container.find('.stamp'));
        container.unbind('click').on('click', '.item', function(e) {
            var $this = $(this),
                this_link = $this.find('a'),
                $this_link = $(this_link),
                this_href = $this_link.attr('href'),
                video_id = $this.attr('data-video-id'),
                gigante = $this.hasClass('gigante'),
                selector = 'div#panel-area.video_grid div.masonry div.item.' + video_id;
            e.preventDefault();
            $.ajax({
                type: "GET",
                async: false,
                url: this_href,
                timeout: 5000,
                data: {'g': gigante},
                dataType: 'html',
                success : function(data) {
                    $(selector).html(data);
                    container.find('.item').removeClass('gigante');
                    $(this).toggleClass('gigante', !gigante);
                    container.masonry();
                    console.log('Selector: ' + selector + ''nSuccess');
                }
            })
            .done(function(msg){
                console.log('Done: ' + msg);
            })
            .fail(function(jqXHR, textStatus){
                console.log('Failed: ' + textStatus);
            });
        });
    });
})(jQuery);
</script>

如果您不想让<a>元素直接指向该URL,那么在它上设置一个有效的href属性有意义吗?

不是想变得聪明,只是问是否有具体的原因。

因为问题是<a>元素仍在执行其"正常"职责,即更改页面。我可以看到您在稍后阶段通过jQuery检索该URL,但这并不重要。

将您使用的属性更改为非href:

<a class="GetYoutubeVideo" href="#" data-custom-url="{% url 'show_video' video_id=object.id %}">

当您需要检索值时,只需使用新的属性名称:

this_href = $this_link.attr('data-custom-url')

请注意,我不能100%确定您是否需要砌体的href属性。从您的代码示例中可以看出,这并不重要,只要您能够从属性中检索值即可(不是特别的href(。

通过不使用href属性,可以确保<a>元素在单击时没有实际的URL可供参考。

这是一个可接受的解决方案/解决方法吗?

您可以简单地在点击事件回调中返回false:

container.unbind('click').on('click', '.item', function() {
    ...
    #ajax
    ...
    return false;
});

我相信这是一种更实用的方法,可以停止默认操作并防止事件冒泡。