请教一种网页内容更新但是没检测到ajax 之类命令的情况

抱歉 因为不了解这种东西不知道该起题目。

以下面这个网站的情况为例:
图片描述

坐标是正常页面,右边是火狐的firebug工具。
在点击页面上的Sold Rent 或者All时候,<div class="property-history__content">下面的内容会被自动改变。
原先以为是ajax之类更新页面,查看firebug的网络界面,发现除了登陆的时候一条请求外,不存在其他任何内容请求。
第一次遇到这种情况,觉得很有意思,就下载了页面源码,这段的源码也只有。

<div class="alternative-bg__item">
    <div data-nav-id="history" class="property-history-container">
        <h2>Property history for 1 New Ballina Road</h2>
        <div id="propertyHistoryComponent"></div>
        <div id="soldEventsCopyright"></div>
    </div>
</div>

请教下,这种页面更新是用什么方法实现的?

网站补充:https://www.realestate.com.au...

阅读 3.8k
5 个回答

这的确就是个 tab 切换,略有点特别。
这个页面是 react 写的。每次切换的时候, 状态改变, react 会重新渲染下面的节点。也可以说下面的内容是写在 JS 里的。
clipboard.png

有点特别的是, 每次点击切换都会发送一次 get 请求,应该不是通过 XMLHttpRequest 对象发送的, 所以在 XHR 面板看不到。看 Content-Type 应该是用 img 标签发送的。
但这个请求好像并没有返回什么内容,而这个请求带了一大堆参数, 所以我猜这个请求是用来记录用户操作的。
clipboard.png

这不是个常见的标签页吗,没有ajax请求是因为不需要从服务器拉取数据,可能数据在一开始载入页面的时候就加载好了,也可能数据本身就是写在js,或者其他可能。
总之页面有没有变化和请求没关系,删除、添加、修改、隐藏、显示DOM都会产生页面更新。

数据是一早就加载进去的,内容请看

https://www.realestate.com.au...

{"propertyHistory":[

{
"date":{"display":"Apr 1992","value":"1992-04-10"},
"price":{"display":"$172,500","value":172500},
"type":"sold"}

]}

已经加载了全部内容。(通过chrome的devtools可以看到只有一个XHR请求将完成了所有操作)

而在三个tab里面都是用这段数据进行判断的。

当点击Sold的时候显示Type为sold的数据

通过这段代码可以很明显看到数据的处理逻辑

 return o(t, e),
            u(t, [{
                key: "setExpanded",
                value: function(e) {
                    this.setState({
                        expanded: e
                    })
                }
            }, {
                key: "selectTab",
                value: function(e) {
                    this.state.tab !== e && (this.setState({
                        tab: e
                    }),
                    this.props.onSwitch(e))
                }
            }, {
                key: "filterItem",
                value: function(e) {
                   // 这里进行数据过滤
                    return this.state.tab === g["default"].TAB.ALL || (this.state.tab === g["default"].TAB.SOLD ? "sold" === e.type : "rentalCampaign" === e.type)
                    
                    
                }
            }, {
                key: "filteredItems",
                value: function() {
                    return this.props.historyItems.filter(this.filterItem)
                }
            }, {
                key: "visibleItems",
                value: function(e) {
                    var t = this.state.expanded ? e.length : this.props.defaultVisibleItems;
                    return e.slice(0, t)
                }
            }, {
                key: "buildTypeMessage",
                value: function() {
                    var e = "sales or rental";
                    return this.state.tab === g["default"].TAB.SOLD ? e = "sales" : this.state.tab === g["default"].TAB.RENT && (e = "rental"),
                    e
                }
            }, {
                key: "render",
                value: function() {
                    var e = void 0
                      , t = this.filteredItems()
                      , n = this.visibleItems(t)
                      , r = t.length > this.props.defaultVisibleItems;
                    return e = 0 === n.length ? f["default"].createElement(c["default"], {
                        typeMessage: this.buildTypeMessage()
                    }) : f["default"].createElement(p["default"], {
                        historyItems: n
                    }),
                    f["default"].createElement("div", {
                        className: "property-history"
                    }, f["default"].createElement(g["default"], {
                        currentTab: this.state.tab,
                        selectTab: this.selectTab
                    }), f["default"].createElement("div", {
                        className: "property-history__content"
                    }, e), r && f["default"].createElement(v["default"], {
                        expanded: this.state.expanded,
                        onToggle: this.setExpanded
                    }))
                }
            }]),

这里用一次加载全部数据是因为数据量太少了。至于说多次加载全部数据还是单次加载全部,要根据返回的数据量来做判断。

现在许多的SPA不都是这样嘛,一上来就把所有的模块在一个js中加载好了(先不提异步加载的模块),vue、react等等,就算是这个没有用MVVM之类的框架,也可以使用类似js模板的工具在html中初始化好,在渲染的时候直接调用了。

我想到了页面路由……………………

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题