在将数据插入页面之前触发的事件(在AJAX调用之后)

时间:2017-04-02 12:40:39

标签: javascript jquery ajax

此站点(http://nelation.net/)使用AJAX和pushState加载页面。 AJAX检索section#body的内容和新CSS的路径。

以下代码发送AJAX请求,检索部分#body(页面内容)的新内容和新的CSS路径。然后将它们插入到页面中,然后调用" pageLoad"事件 - 我认为这件事太早发生了。

function loadPage(url) {
    var target = document.getElementById("body");
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    xhr.onreadystatechange = function() {
        if (xhr.readyState < 4) {
            target.innerHTML = "";
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            // Function to decode the new page
            var decodeEntities = (function() {
                // this prevents any overhead from creating the object each time
                var element = document.createElement('div');
                function decodeHTMLEntities (str) {
                    if(str && typeof str === 'string') {
                        // strip script/html tags
                        str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
                        str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
                        element.innerHTML = str;
                        str = element.textContent;
                        element.textContent = '';
                    }
                    return str;
                }
                return decodeHTMLEntities;
            })();

            var resultJSON = JSON.parse(xhr.responseText);
            var page = decodeEntities(resultJSON.page);
            // Remove existing CSS and insert new one
            $(".page-css").remove();
            if (resultJSON.css != "none") {
                $("<link/>", {
                    "class": "page-css",
                    rel: "stylesheet",
                    type: "text/css",
                    href: resultJSON.css
                }).appendTo("head");
            }
            // Insert page contents, then trigger the pageLoad event
            $(target).html(page);
            $("body").trigger("pageLoad");
        }
    };
    xhr.send();
}
// Detect link clicks, and make AJAX calls out of them + pushState.
$("body").on("click", '[data-ajax="true"]', function(event) {
    event.preventDefault();
    // detect which page has been selected
    var newPage = $(this).attr("href");
    if (newPage != window.location) {
        window.history.pushState({path: newPage}, "", newPage);
    }
    loadPage(newPage);
});

&#34; pageLoad&#34;在此脚本中找到事件处理程序。如果您在主页中,它会重新执行大部分脚本,最明显的是centerPlayButton_Featured()函数。当您将图像悬停在主页上时,该功能会调整您看到的叠加层的大小;当你正常加载页面时它工作正常,但是当你通过AJAX到达页面时它不会。该函数仍然执行(Logs to console),但我怀疑它是在内容正确加载到页面之前执行的。

// DOES NOT RE-EXECUTE ON AJAX
function centerPlayButton_Featured() {
    console.log("centerPlayButton_Featured() just executed");
    var coverWidth = $("section.home-latest-release img.cover").width();
    var coverHeight = $("section.home-latest-release img.cover").height();
    $("section.home-latest-release div.cover-overlay").css({
        "height": coverWidth + "px",
        "width": coverHeight + "px"
    });
}

$("body").click(function(e) {
    if ($(e.target).hasClass("dropdown-text")) {
        if ($(e.target).siblings(".menu").hasClass("open")) {
            $(e.target).siblings(".menu").removeClass("open");
            $(e.target).removeClass("open");
        } else {
            $(".dropdown .menu, .dropdown .dropdown-text").removeClass("open");
            $(e.target).siblings(".menu").addClass("open");
            $(e.target).addClass("open");
        }
    } else {
        $(".dropdown .menu, .dropdown .dropdown-text").removeClass("open");
    }
});
// RE-EXECUTES ON AJAX
$("body").on("pageLoad", function() {
    $(function() {
        // HOME PAGE
        if ($("#body").children().hasClass("home-latest-release")) {

            centerPlayButton_Featured();
            $(window).on('resize', function() {
                centerPlayButton_Featured();
            });

        }
        // MUSIC PAGE
        if ($("#body").children().hasClass("music-tracks")) {

            //...

        }
        // CONTACT PAGE
        $(function() {
            if ($("#body").children().hasClass("contact")) {

                $("textarea").bind("input", function() {
                    var offset = this.offsetHeight - this.clientHeight;
                    $(this).css("height", "auto").css("height", this.scrollHeight + offset);
                });

            }
        });
    });
});
$("body").trigger("pageLoad");

感谢任何帮助/反馈。转到链接以查看更多代码,并告诉我您是否需要查看后端。如果代码混乱且注释缺乏,我道歉。非常感谢您的帮助。

我遇到的另一个问题是,当您进入音乐页面时,您可能会看到所有下拉菜单逐渐淡出。不像主要问题那么重要,但是将不胜感激:)

1 个答案:

答案 0 :(得分:1)

  1. pageLoad事件未触发,因为它绑定到窗口load事件:

        $(window).bind("load", function() {
            $("body").trigger("pageLoad");
        });
    

    load在窗口的生命周期中只发生一次,并且当ajax请求甚至可以启动时,该时间早已过去。直接触发pageLoad

  2. 当DOM完成加载时,
  3. $(function () {...})执行一次。实际上,您将使用仅发生一次的相同事件load包装要执行两次的代码。直接在pageLoad事件处理程序中执行设置代码。我这样写:

    function pageSetup () {
        // HOME/MUSIC/CONTACT PAGE setup code
    }
    
    $("body").on("pageLoad", pageSetup);
    pageSetup();