javascript - JQuery Ajax 调用期间变量存储主体 classList 被错误更新

标签 javascript jquery ajax

我目前正在创建一个脚本来使用 JQuery 的 Ajax 请求功能处理 Ajax 页面转换。在 Ajax 函数的 success 回调中,我需要能够访问当前页面的 body classListclassList<回调返回的数据body。由于此脚本在我的 (Wordpress) 站点的页面之间转换,因此我需要在 Ajax success 函数期间更新正文类。

这是我的代码的一个非常简单的版本,可以让您大致了解我正在做的事情:

function loadPageData(event, elem, eventType) {

    let _this = elem;

    // use this to determine where the transition comes from (i.e. to differentiate between home->single-casestudy and single-casestudy->single-casestudy etc...)
    let cameFromBodyClasses = elem.closest('body').classList;

    console.info('console test 1:', cameFromBodyClasses, cameFromBodyClasses.contains('home'));

    // Prevent the default behavior of clicking these links
    event.preventDefault();

    let th = eventType === 'menuLinkClick' ? $(_this) : $('.menu-main-container ul li.current-menu-item');
    let url = eventType === 'menuLinkClick' ? th.attr('href') : window.location.href;

    $.ajax({
        type: 'POST',
        url: url,
        dataType: "html",
        success: function (data) {

            console.info('console test 2:', cameFromBodyClasses, cameFromBodyClasses.contains('home'));

            let htmlObject = document.createElement('html');
            htmlObject.innerHTML = data;

            $(document).find('body').attr('class', $(htmlObject).find('body').attr('class'));

            let newBody = $(htmlObject).find('body');

            // this console.info is now different to the previous two...
            console.info('console test 3:', cameFromBodyClasses, cameFromBodyClasses.contains('home'));

            // the below if statement is being passed because cameFromBodyClasses.contains('home') is false at this point (but it shouldn't be)
            if (cameFromBodyClasses.contains('home') && newBody.hasClass('single-casestudy')) {

                // if coming from 'home' page and going to 'single-casestudy' page

                    // do unique transition animation here

            }
        }
    });
}


$(document).on('click', 'a[data-ajax="true"]', function (e) {

    loadPageData(e, this, 'menuLinkClick');

}

问题

正如您从简化的代码中看到的,我有 3 次使用 console.info cameFromBodyClasses 变量来检查其值。

从主页导航到单个案例研究页面时,第一个和第二个 console.info 调用显示变量 cameFromBodyClasses 包含 classList 的主页 body 标记,因为它应该(因为我们来自主页)。然而,第三个 console.info 调用是不同的,它打印我正在导航到的页面的 body classList (单个案例研究页面) ),但它仍然应该打印主页的 body classList,因为变量在两个 console.info 之间没有以任何方式更改来电。

所以...

如何存储用户正在离开的页面的 body classList 并防止其在 Ajax 调用期间的任何时候被更新/更改?

我认为这与我在第三个之前创建一个新的 html 元素并更新其 body classList 的事实有关console.info,但我仍然不明白为什么这会改变 cameFromBodyClasses 变量的值,因为它仅在函数期间(以及 ajax 之前)的一个点设置调用)

最佳答案

问题在于变量 cameFromBodyClasses 指向 classList,它是一种数组形式。如果数组的内容发生变化,cameFromBodyClasses也会反射(reflect)这些变化,因为它只是指向该数组,而不是它最初指向的唯一数组。

考虑以下...

var x = [ 'a', 'b'];
var y = x;

console.log(x, y);

x.push('c');

console.log(x, y);

y = x.slice(0);

x.push('d');

console.log(x, y);

正如你所看到的,x和y都指向内存中的同一个数组。然而,最后一次推送并没有反射(reflect)在 y 中。这是因为执行了 slice(),导致 y 指向一个完全不同的数组。因此,此时插入 x 不会影响 y。

关于javascript - JQuery Ajax 调用期间变量存储主体 classList 被错误更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55224163/

相关文章:

javascript - AngularJS Angular 种子启动项目添加指令

javascript - 如何修复链接引导模板?

javascript - 如何在元素完成渲染后立即运行函数?

javascript - 遍历每个 div 并获取其 html 内容

javascript - 如何手动从 Bootstrap 中关闭 Web 模式对话框?

javascript - 使用 JQuery 的登录页面

javascript - JQuery Accordion TypeError : this. 幻灯片未定义

javascript - .removeClass 不工作,并阻止 .addClass 工作

javascript - 需要自动保存 TinyMCE

javascript - 如何使日历表 > td 成为可选择的表单元素?