显示/隐藏具有多种条件的元素的最有效方式

时间:2014-08-01 04:54:10

标签: jquery performance

我正在尝试优化现有产品的加载时间。根据用户选择的条件,我有一大堆要显示/隐藏的产品。简单来说,我只选择3个条件,即产品名称,尺寸和颜色。

例如,根据用户的下拉条件显示产品。参考下面的HTML,如果产品名称是A,则显示列pa,pa1和pa2。如果附加条件大小为2,则显示列pa2和列pa2r。如果包含颜色,则仅显示列pa2r。所有其他产品都是隐藏的。

HTML就像这样

<table>
<tr>
<td>Products</td>
<td class="pa">Product A</td>
<td class="pa1">Product A1</td>
<td class="pa2">Product A2</td>
<td class="pa2r">Product A2r</td>
<td class="pb">Product B</td>
<td class="pc">Product C</td>
<td class="pc1">Product C1</td>
</tr>
</table>

目前我的java脚本有一个很大的开关过滤产品名称,以及多个if else条件来检查颜色和大小。某些条件可能会覆盖产品名称的现有开关,这会导致列首先隐藏,然后在切换(产品名称)语句期间显示,并再次隐藏在内部IF ELSE语句中。将引入更多条件并使代码复杂化,我在IE7上测试由于隐藏/显示和切换而非常慢。

我在网上找到的一些可以减少负载的解决方案,包括用css({'display':'none'})替换show / hide或css({'display':'block'}),基本上是优化我认为不够好的选择器。

有没有其他好的解决方案来处理jQuery中的多个条件?

1 个答案:

答案 0 :(得分:1)

我会通过将操作DOM的次数减少到最小来优化这一点。我还会优化更快的元素查找。

常规资料

我注意到你的班级名字是独一无二的。更改它们,以便每个元素都有一个ID,并且有办法通过类获取所有产品。与通过类名查找相比,ID可以超级​​快速查找。这是一个示例DOM:

<table>
    <tr>
    <td>Products</td>
        <td id="p-a" class="product">Product A</td>
        <td id="p-a1" class="product">Product A1</td>
        <td id="p-a2" class="product">Product A2</td>
        <td id="p-a2r" class="product">Product A2r</td>
        <td id="p-b" class="product">Product B</td>
        <td id="p-c" class="product">Product C</td>
        <td id="p-c1" class="product">Product C1</td>
    </tr>
</table>

我的例子在这里没有使用ID查找速度快的事实,但无论如何都要记住它。

现在,您的jQuery需要获得所有产品:var elements = $(".product");

接下来,您需要循环遍历元素,可以显示或隐藏元素的决定。这个循环可以像这样完成:

elements.each(function (e) {
    if (<showcondition>) {
        $(e).show(); //you can also do this in plain javascript to avoid creating a new jQuery
    }
    else {
        $(e).hide();
    }

    //alternately: $(e).toggle(<showcondition>) would work as well and is smaller.
});

现在,您的<showcondition>是一个值,表示是否应根据选择显示元素,并按每个元素计算。

基于您暗示但可能不属实的具体想法:

同样,这并没有使用ID查找速度快的事实。

如果他们必须在选择数字之前选择产品,并且必须在选择颜色之前选择尺寸,您可以进行非常快速的比较,如下所示:

var selectedProduct = functionToGetSelectedProductLetter() || null; //we want this null if not there
var selectedSize = functionToGetSelectedProductSize() || null;
var selectedColor = functionToGetSelectedProductColor() || null;

//your class names seem to have a certain format...let's take advantage of that:
var startsWith = 'p-'; //this could be anything...even a blank string...so long as your products' ids all start with it.
if (selectedProduct) {
    startsWith += selectedProduct;
    if (selectedSize) {
        startsWith += selectedSize;
        if (selectedColor) {
            startsWith += selectedColor;
        }
    }
}

elements.each(function (e) {
    $(e).toggle(e.id.indexOf(startsWith) === 0); //if the ID starts with our search string, we show the element. Otherwise it is hidden.
});

如果他们只选择一个尺寸或只是一种颜色,这显然不会起作用,但希望它可以让你了解我的意思&#34;减少你修改DOM的次数&#34 ;。上面的示例迭代将每个元素的可见性设置为一次,而不是一遍又一遍地进行。整个想法是使用一些中间变量来缓冲&#34;显示/隐藏元素直到最后一刻。与数千个项目的DOM更改相比,数学和比较操作相对便宜,因为每次更改都会触发重新绘制..