在JQuery Ajax调用期间错误地更新了变量存储主体classList

时间:2019-03-18 14:54:48

标签: javascript jquery ajax

我目前正在使用JQuery的Ajax请求功能创建一个脚本来处理Ajax页面转换。在Ajax函数的success回调内部,我需要能够访问当前页面的body classListclassList中的body回调的返回data。当此脚本在我的(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(单个案例研究页面),但它仍应打印主页的{ {1}} body,因为在两次classList调用之间变量没有进行任何更改。

所以...

如何存储用户正离开的页面的console.info body,并防止在Ajax调用期间随时对其进行更新/更改?

我认为这与以下事实有关:我正在创建新的classList元素并在第三个html之前更新其body classList,但是我仍然不明白为什么这会更改console.info变量的值,因为它仅在函数执行过程中(在ajax调用之前)设置在某个点上

1 个答案:

答案 0 :(得分:1)

问题是变量cameFromBodyClasses指向classList,它是数组的形式。如果数组的 contents 发生更改,则cameFromBodyClasses也会反映这些更改,因为它仅指向该数组,而不是原始指向的唯一数组。

请考虑以下内容...

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都指向内存中的同一数组。但是,最后一次推送未反映在y中。这是因为执行的slice()导致y指向一个完全不同的数组。因此,推到x不会影响y。