简体   繁体   English

DOM /页面未更新,但console.log显示更新后的值

[英]DOM/Page not updating but console.log shows updated value

I'm doing an SPA from scratch and so far I've gotten everything working except the active state off the navigation links will not update according to where user is navigating to. 我正在从头开始制作SPA,到目前为止,除了导航链接的active状态不会根据用户导航到的位置而更新之外,其他所有功能都可以正常工作。

The funny thing is that when I open up the Developer Tools in Chrome, under "Elements" the DOM is still showing the active class on the original nav element, but under "Console", when I console.log the element, it shows that the class has been removed. 有趣的是,当我在Chrome中打开开发人员工具时,在“元素”下,DOM仍在原始nav元素上显示active类,但是在“控制台”下,当我console.log元素时,它显示出该班级已被删除。

I've tried event.stopPropagation() in a few places and the jQuery.off() function but nothing seems to fix this problem. 我已经在几个地方和jQuery.off()函数中尝试过event.stopPropagation() ,但是似乎没有任何方法可以解决此问题。

Problem: The class list of the active and the former active link doesn't update when clicking on a navigation link, but the console.log function does show an updated classlist off the former active link 问题:单击导航链接时,活动和前一个活动链接的类列表不会更新,但是console.log函数的确显示了前一个活动链接的更新后的类列表

Desired Behaviour: That the former active link losses its active class and that the currently active link gets an active class after its navigation link has been clicked and the page renders the new content(the supposedly new page). 期望的行为:以前的活动链接会丢失其active类,并且当前的活动链接会在其导航链接被单击并且页面呈现新内容(假定为新页面)之后变为active类。

UPDATE 1: Updated the code according to suggestions and it got the first part of my problem working. 更新1:根据建议更新了代码,它使我的问题的第一部分开始工作。 Removing active class from all li elements now works, but making the page render the updated links with active class on currently active link after navigation does not work. 现在,可以从所有li元素中删除active类,但是在导航后,使页面在当前活动链接上呈现具有active类的更新链接是无效的。 See in app.js under generateView() function. 请参阅app.js中的generateView()函数。

UPDATE 2: Got it working. 更新2:工作正常。 See on the bottom of this Question. 请参阅此问题的底部。 Thank you! 谢谢!

My app.js 我的app.js

(function ($, hbs){

'use strict';

// declare some usefull variables to use throughout the app
var
    doc = document,
    oldPath = '',
    newPath = '',
    navParentEl = '';


// 1: Manually trigger a hashchange to start the app.
window.onload = function (e) {
    $(window).trigger('hashchange');
};

// 2: Catch clicks on the root-level element for anchor tag clicks.
doc.body.addEventListener('click', function (e) {
    //e.stopPropagation();
    var tag = e.target;

    // check element clicket
    if (tag.tagName === 'A' && tag.href && e.button === 0) {
        // it's a left-click on an anchor. Lets navigate!
        if (tag.origin === window.location.origin) {
            // prevent the page from navigating

            e.preventDefault();

            // it's a link within the site, HURRAY!
            oldPath = window.location;
            newPath = tag.href,
            navParentEl = tag.parentElement;

            console.log(navParentEl);

            // Update the URL bar! IMPORTANT!
            // @TODO: MOVE INTO A FUNCTION OR OBJECT
            window.history.pushState(null, '', newPath);
            render(window.location.hash, data, e);
        }
    }
});

// register Handlebars partials
hbs.registerPartial({
    'header': hbs.templates.header,
    'footer': hbs.templates.footer
});

$(window).on('hashchange', function (e) {
    // On every hash change the render function is called with the new hash.
    render(window.location.hash, data, e);
});

function render(url, data, evt) {
    var temp = url.split('/')[0];

    // Hide current page
    $('.pages').addClass('hidden');

    // remove anchors .active class
    //$('.nav-parent').removeClass('active');

    var map = {
        '': function (data) {
            renderPage('home', data);
        },
        '#home': function (data) {
            renderPage('home', data);
        },
        '#gallery': function (data) {
            renderPage('gallery', data);
        },
        '#about': function (data) {
            renderPage('about', data);
        }
    };

    if (map[temp]) {
        map[temp](data);
    } else {
        renderErrorPage(data);
    }
}

function renderPage(page, data) {
    var tpl = hbs.templates[page](data);
    generateView(tpl, page);
}

function renderErrorPage(data) {
    renderPage('error', data);
}

function generateView(tpl, page) {
    var pageId = '#' + page;

    $(pageId).removeClass('hidden');
    $('.container').html(tpl);

    // this works for removing the active class from all li elements
    $('.nav-parent').removeClass('active');

    // add .active class to the new active anchor element
    // does not work
    $(navParentEl).addClass('active');

}

})(jQuery, Handlebars);

My navigation HTML: 我的导航HTML:

<div class="header clearfix">
    <nav>
        <ul class="nav nav-pills pull-right">
            <li role="presentation" class="nav-parent active"><a href="#home" class="links">Home</a></li>
            <li role="presentation" class="nav-parent"><a href="#gallery" class="links">Gallery</a></li>
            <li role="presentation" class="nav-parent"><a href="#about" class="links">About</a></li>
            <li role="presentation" class="nav-parent"><a href="#contact" class="links">Contact</a></li>
        </ul>
    </nav>
    <h3 class="text-muted">{{ projectName }}</h3>
</div>

UPDATE 2: Got it working after some tips. 更新2:经过一些提示后,它开始工作了。 I needed to re-think my generateView() function. 我需要重新考虑我的generateView()函数。 Here's the final code for that function: 这是该函数的最终代码:

function generateView(tpl, page) {
    var pageId = '#' + page;

    // remove hidden class from content to be shown
    $(pageId).removeClass('hidden');
    // add the template to the html
    $('.container').html(tpl);
    // move the active class from the former active link
    $('.nav-parent').removeClass('active');

    // get the current hash of the location
    var newHash = window.location.hash,
        // get all links
        _links = document.querySelectorAll('.links'),
        currentActiveLink = '';

    // iterate over the _links object and find the link with href === newHash
    for ( var i = 0; i < _links.length; i++ ) {
        if ( _links[i].getAttribute('href') === newHash ) {
            // store the link with href == newHash 
            // inside the currentActiveLink variable
            currentActiveLink = _links[i];
        }
    }

    // add active class to current active link
    currentActiveLink.parentElement.classList.add('active');
}

Thank you! 谢谢!

isnt it possible that you redraw your navigation? 您是否可能重新绘制导航? didnt really go through your code but it took me a looong time to discover that in my SPI. 并没有真正检查您的代码,但是花了我很长的时间才能在我的SPI中发现它。 I changed some params, but I also ajax-loaded those elements wit default serverside properties... EDIT: yea I can see that happening in your app 我更改了一些参数,但是我也用默认服务器端属性将这些元素ajax加载...编辑:是的,我可以看到这种情况发生在您的应用程序中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM