Javascript 计算剔除渲染组件的宽度

Javascript 计算剔除渲染组件的宽度,javascript,jquery,html,css,knockout.js,Javascript,Jquery,Html,Css,Knockout.js,我使用knockout来呈现一个可单击元素列表,这些元素可以作为单选按钮。但是,由于这是一个水平列出元素的列表,因此当放入太多元素时(有时可能是这样),它可能会从页面右侧运行。现在,我只需要将它拆分成多行,但这对于我想要的设计来说并不理想 问题是,我插入的组件的宽度是可变的,这取决于每个组件中列出的人员的姓名。我想做的是能够告诉我可以为给定的浏览器宽度放置多少组件,然后将其余的隐藏在不同的可观察数组中,我可以以不同的方式渲染(使用下拉列表)。我不相信有任何简单的方法可以使用CSS来实现这一点,因

我使用knockout来呈现一个可单击元素列表,这些元素可以作为单选按钮。但是,由于这是一个水平列出元素的列表,因此当放入太多元素时(有时可能是这样),它可能会从页面右侧运行。现在,我只需要将它拆分成多行,但这对于我想要的设计来说并不理想

问题是,我插入的组件的宽度是可变的,这取决于每个组件中列出的人员的姓名。我想做的是能够告诉我可以为给定的浏览器宽度放置多少组件,然后将其余的隐藏在不同的可观察数组中,我可以以不同的方式渲染(使用下拉列表)。我不相信有任何简单的方法可以使用CSS来实现这一点,因为它必须在一个完全不同的元素中呈现

my ViewModel中的代码如下所示:

self.personList = ko.observableArray(params.personList);

self.visiblePersons = ko.pureComputed(function () {
    var viewPortWidth = $("#personListContainer").width();
    var personArray = [];
    $.each(personList(), function(person) {
        var widthOfPersonElement = getPersonWidth(person); //not sure how to get the person width after render?
        viewPortWidth -= widthOfPersonElement;
        if (viewPortWidth >= 0) {
            personArray.push(person);
        }
    });
    return personArray;
});

self.overflowPersons = ko.pureComputed(function () {
    //get all persons in the person list that AREN'T in the visible list
    //this is the easy part
});
var getRenderedPersonWidth = function(person) {
    var displayString = person.FullName + person.ID;
    var element = document.createElement('span');
    $(element).text(displayString);
    $(element).addClass(""); //class names of the element I'm rendering
    $('#elementtorenderunder').append(element);
    var width = $(element).width();
    $(element).remove();
    return width;
}
var getRenderedPersonWidth = function(person) {
    var displayString = person.FullName + person.ID;
    var element = document.createElement('span');
    $(element).text(displayString);
    $(element).addClass(""); //class names of the element I'm rendering
    $('#elementtorenderunder').append(element);
    var width = $(element).width();
    $(element).remove();
    return width;
}
我想我的问题是,这是否现实可行?我希望避免渲染它,然后获得每个元素的宽度,然后重新渲染或类似的混乱/闪烁。我知道,为了使它在调整窗口大小时动态更新,我必须为元素添加一个触发器,但我甚至不知道如何执行第一步


编辑:所以,我四处摸索了一下,最后决定我必须使用dom。我的解决方案如下所示:

self.personList = ko.observableArray(params.personList);

self.visiblePersons = ko.pureComputed(function () {
    var viewPortWidth = $("#personListContainer").width();
    var personArray = [];
    $.each(personList(), function(person) {
        var widthOfPersonElement = getPersonWidth(person); //not sure how to get the person width after render?
        viewPortWidth -= widthOfPersonElement;
        if (viewPortWidth >= 0) {
            personArray.push(person);
        }
    });
    return personArray;
});

self.overflowPersons = ko.pureComputed(function () {
    //get all persons in the person list that AREN'T in the visible list
    //this is the easy part
});
var getRenderedPersonWidth = function(person) {
    var displayString = person.FullName + person.ID;
    var element = document.createElement('span');
    $(element).text(displayString);
    $(element).addClass(""); //class names of the element I'm rendering
    $('#elementtorenderunder').append(element);
    var width = $(element).width();
    $(element).remove();
    return width;
}
var getRenderedPersonWidth = function(person) {
    var displayString = person.FullName + person.ID;
    var element = document.createElement('span');
    $(element).text(displayString);
    $(element).addClass(""); //class names of the element I'm rendering
    $('#elementtorenderunder').append(element);
    var width = $(element).width();
    $(element).remove();
    return width;
}

它实际上工作得很好,尽管您必须使类与正在呈现的html保持同步。不太好看,但这是我目前拥有的最好的了。

使用模型无法做到这一点,因为您的问题依赖于DOM,而viewmodel不知道它与DOM的关系。可以在多个位置渲染相同的数据


当您想要控制数据的呈现方式时,需要一个。实际上这是可能的,但这是一个复杂的问题。

编辑:因此,我稍微摸索了一下,最终决定必须使用dom。我的解决方案如下所示:

self.personList = ko.observableArray(params.personList);

self.visiblePersons = ko.pureComputed(function () {
    var viewPortWidth = $("#personListContainer").width();
    var personArray = [];
    $.each(personList(), function(person) {
        var widthOfPersonElement = getPersonWidth(person); //not sure how to get the person width after render?
        viewPortWidth -= widthOfPersonElement;
        if (viewPortWidth >= 0) {
            personArray.push(person);
        }
    });
    return personArray;
});

self.overflowPersons = ko.pureComputed(function () {
    //get all persons in the person list that AREN'T in the visible list
    //this is the easy part
});
var getRenderedPersonWidth = function(person) {
    var displayString = person.FullName + person.ID;
    var element = document.createElement('span');
    $(element).text(displayString);
    $(element).addClass(""); //class names of the element I'm rendering
    $('#elementtorenderunder').append(element);
    var width = $(element).width();
    $(element).remove();
    return width;
}
var getRenderedPersonWidth = function(person) {
    var displayString = person.FullName + person.ID;
    var element = document.createElement('span');
    $(element).text(displayString);
    $(element).addClass(""); //class names of the element I'm rendering
    $('#elementtorenderunder').append(element);
    var width = $(element).width();
    $(element).remove();
    return width;
}

它实际上工作得很好,尽管您必须使类与正在呈现的html保持同步。不太好看,但这是我目前拥有的最好的了。

谢谢,我实际上是临时使用dom来解决这个问题的。我明白你的观点,它是不可知论的。