0

好的,我一直在构建一个 SPA 应用程序,并希望根据网站是在手机还是笔记本电脑上查看不同的布局。

如果使用 Bootstrap,它提供了对 css 类的有条件的隐藏/显示,虽然它可以很好地完成它的工作,但当布局更改超过某个点时它就不能很好地工作。使用这种替代布局,我最终需要将两组 div 放在一个页面上,然后使用一些条件 Javascript 代码来清除目标 div 的内部 html。这可以防止图表被填充到永远不会看到的页面部分。

    var setViewscape = function () {
    var l = $(".positionDetails").length;
    if (l == 0) {
        setTimeout(function() {
            setViewscape();
        }, 10);
    } else {
        if (window.innerWidth <= 899) {
            $(".landscape").html("");
            $(".phonescape").css("visibility", "visible");
        } else {
            $(".phonescape").html("");
            $(".landscape").css("visibility", "visible");
        }
    }
};

到目前为止一切都很好,除了当我使用 Knockout 观察页面上发生的情况时,第二组淘汰标签仍然被绑定到。我尝试添加一个 ko 条件以仅绑定到我打算显示的那些控件:

<div id="content" class="main">
    <div class="row landscape">
        <!--ko if: $(window.innerWidth > 899) -->
        <div class="col-8 col-lg-8">
            <!--ko compose: {view: 'positions/list'} --><!--/ko-->
        </div>
        <div class="col-lg-4 col-4 " > 
            <!--ko compose: {view: 'shared/summaryGraph'} --><!--/ko-->
            <!--ko compose: {view: 'shared/memberSummary'} --><!--/ko-->
            <!--ko compose: {view: 'shared/memberCalendar'} --><!--/ko-->
            <!--ko compose: {view: 'shared/memberTwitter'} --><!--/ko-->
            <div data-bind="visible: advert() != null && advert().length > 0" id="advert"  class="img-rounded container-fluid" style="min-width: 120px; min-height: 680px; height: inherit; margin-bottom: 30px; background-color:whitesmoke ">
                <h4>Advert</h4>
            </div>
        </div>
    <!--/ko-->
    </div>
    <div  class="row phonescape" style="padding-left: 15px; padding-top: 15px;">
    <!--ko if: $(window.innerWidth <= 899) -->
        <div class="col-sm-12">
            <!--ko compose: {view: 'shared/memberSummary'} --><!--/ko-->
            <!--ko compose: {view: 'shared/sagaSummaryGraph'} --><!--/ko-->
            <!--ko compose: {view: 'positions/list'} --><!--/ko--> 
        </div>
    <!--/ko-->
    </div>
</div>

但是当我观察调试信息时,我看到 ["Binding", "views/positions/list", ko.bindingContext] ["Binding", "views/positions/list", ko.bindingContext]

["Binding", "views/shared/memberSummary", ko.bindingContext] ["Binding", "views/shared/memberSummary", ko.bindingContext]

["Binding", "views/shared/summaryGraph", ko.bindingContext] ["Binding", "views/shared/summaryGraph", ko.bindingContext]

我确信这一定是一个性能打击。

我要做的是只绑定到“phonescape”或“landscape”模式,并删除肯定会影响性能的东西。知道怎么做吗?

4

1 回答 1

0

最近,我使用了一个 observable 扩展来做这样的事情,扩展根据媒体查询是否被命中来更新一个 observable。您将定义一个可观察的,例如:

this.large = ko.observable().matchMedia("(min-width: 800px)");

然后,您可以将页面区域与“大”(like if: large)绑定,以防止您不想要的区域被绑定。

该代码有点幼稚,因为它仅支持针对旧浏览器中基于 px 的测量的最小/最大宽度查询。

这是我使用的:

//small extension to update an observable based on a media query
(function() {
    var self = ko.observable.fn.matchMedia = function(query) {
        self["matchMedia" in window ? "syncWithMatchMedia" : "syncWithResize"](this, query);
        return this;
    };

    self.syncWithMatchMedia = function(observable, mediaQuery) {
        var query = window.matchMedia(mediaQuery);

        observable(query.matches);

        query.addListener(function(query) {
            observable(query.matches);
        });
    };

    self.syncWithResize = function(observable, mediaQuery) {
        var pieces = mediaQuery.split(":"),
            isMax = pieces[0].indexOf("max") > -1,
            value = pieces[1].replace(")", "").replace("px",""), //just works with px for now
            currentWidth;

        var matcher = function() {
            var width = document.outerWidth || document.body.clientWidth;

            //see if something changed
            if (width !== currentWidth) {
                currentWidth = width;
                observable(isMax ? value > width : value < width);
            }
        }

        matcher();

        ko.utils.registerEventHandler(window, "resize", matcher);
    };
})();

如果浏览器不支持 API ,它会回退到使用resize事件。matchMedia

这是一个示例:http: //jsfiddle.net/rniemeyer/7s2hZ/

于 2013-08-15T15:24:58.007 回答