高度转换为"白色空间:nowrap"涉及:可能用更少的Javascript?

时间:2014-06-15 16:06:53

标签: javascript jquery css css-transitions word-wrap

主题

我有一个文本框,用省略号隐藏溢出的文本。只能看到一行。

我使用text-overflowwhite-space: nowrap完成了此操作。该元素具有固定的height值。

点击/点击时,框应平滑地展开(它的高度),以显示文本的其余部分。

我使用CSS过渡和Javascript完成了这个。一个隐藏的"阴影" description容器包含相同的文本,没有空格和溢出处理。它有全高。在设置实际的盒子时,我设置从" shadow"中读取的height值。元素并添加一个类,将删除空白和溢出的东西。 transition: height选项使此更改顺利进行。

问题

我想在没有额外的Javascript逻辑且没有阴影元素的情况下这样做。
我想在没有

的情况下这样做
  • 使用setTimeout()等待转换
  • 阴影元素

仅删除white-spacetext-overflow不起作用,因为它们无法转换。

我很好奇是否还有其他技巧可以做到这一点。

工作代码

小提琴:http://jsfiddle.net/ywQTd/(使窗口足够小以触发text-overflow: hidden

CSS:

#control {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;

    background-color: rgba(0,0,0, 0.05);
}

.description {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background-color: rgba(0,0,0, 0.2);
    color: rgb(255,255,255);
    padding: 0 10px;

    line-height: 25px;
    transition: height 0.5s ease;

    text-align: center;
}

#description {
    height: 25px;
}

#description.expand {
    overflow: hidden;
    text-overflow: initial;
    white-space: normal;
}

#shadow-description {
    position: absolute;
    top: -10000px;

    text-overflow: initial;
    overflow: visible;
    white-space: normal;
}

单击Handler(在jQuery中加载Fn):

$("...").on("click", function(){
    var h = $("#shadow-description").height(),
        $el = $("#description");

    if ($el.hasClass("expand")) {
        $el.css({height: ""});

        setTimeout(function(){
            $el.removeClass("expand");
        }, 200);
    } else {
        $el.css({height: h + "px"}).addClass("expand");

    }

});

HTML:

<div id="control">
    <div id="description" class="description">lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum dolor sit amet</div>
    <div id="shadow-description" class="description">lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum dolor sit amet</div>
</div>

更新

最初的标题是

  

高度转换为&#34;白色空间:nowrap&#34;涉及:有没有JS的方式?

我已经改变了它,因为它不够清楚。当然,如果没有Javascript,它是不可能的,因为必须有一个点击处理程序,它将执行&#34;某些事情&#34;。但是我希望使用更少的Javascript 逻辑来存档目标,而无需在Javascript中进行计时。 ;)

此外,我已经澄清了问题部分中的第一段。


附录

@ jme11善意地指出我的解决方案有一些可访问性和SEO相关的问题。是的,没错,这个例子有这些问题。但我只提取了代码的相关部分。在应用程序中,两者都不重要:页面在后端呈现,以便它在没有Javascript的情况下工作,阴影元素不存在。然后它逐步增强&#34;并完全重新渲染。 &#34;阴影元素&#34;对于聪明的搜索引擎来说可能仍然是一个问题,但我想有一个属性会将此标记为与SEO无关。可访问性问题是一个好点,但我确定有一些 ARIA 属性可以使此元素静音。

但是,既然我想摆脱阴影元素,那么这一切都不是那么有趣,是吗?

2 个答案:

答案 0 :(得分:1)

我看到了你想要完成的挑战,但是你现在的解决方案显然存在问题(我相信你知道)。即,可访问性问题(因为“影子元素”在视觉上隐藏但不是听觉上),SEO问题(因为您复制的内容可以被列入黑名单),以及您的代码和内容本身的可读性/可维护性问题。

我推荐以下解决方案。这里的技巧是你实际删除描述类,获取元素的高度,然后再添加描述类。这一切都发生得如此之快,浏览器没有机会重新绘制,因此,用户什么也看不到(除非他们碰巧在开发人员工具中看到这个元素)。

我发现,就像你最初做的那样,在将描述类添加回来之前将高度传递给元素之前,这需要几毫秒的超时。尽管如此,它感觉非常敏感,而且效果很好。

这是一个fiddle。 (请注意,我将内联宽度添加到您的控件中仅用于测试,因此我不必继续使窗口变小)。

<强> HTML:

<a href="javascript: void(0);">open</a>
<div id="control">
    <div id="description" class="description">lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum dolor sit amet</div>
</div>

CSS: 注意:我将line-height:25px移动到包含元素中,这样当删除描述类时,仍然会根据行高计算高度。 / em>的

#control {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    line-height: 25px;
    background-color: rgba(0,0,0, 0.05);
}

.description {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background-color: rgba(0,0,0, 0.2);
    color: rgb(255,255,255);
    padding: 0 10px;
    height: 25px;
    transition: height .5s ease;
    text-align: center;
}

.description.expand {
    overflow: hidden;
    text-overflow: initial;
    white-space: normal;
}

<强> JS:

$(function(){
    $("a").on("click", function(){
        $el = $("#description");      
        if ($el.hasClass("expand")) {
            $el.css({height: ""});

            setTimeout(function(){
                $el.removeClass("expand");
            }, 200);
        } else {

            $el.removeClass("description");
            var h = $el.css("height");
            $el.addClass("description");
            setTimeout(function(){
                $el.addClass("expand").css("height", h);
            }, 200);
        }
    });
});

我意识到这并没有真正回答你的问题:是否有一种没有JS的方式。答案是否定的,不是我能想到你的实现或产生你想要的确切结果。另外,AFAIK,你必须有一个点击处理程序,所以在这方面,你必须有JS参与。尽管如此,这是一种更清晰,更易于阅读/维护的方法,可以解决当前实施中的一些问题。

答案 1 :(得分:1)

问题在于您无法转换到height:auto; 尝试以下(根据我的意见,使用最少量的JS): http://jsfiddle.net/ywQTd/2/

我的方法首先读取处于展开状态的元素的高度,然后立即将其恢复到收缩状态。然后在每次点击时首先切换“扩展”类,它控制word-wrap的值,依此类推。然后通过使用$().css()设置值来设置高度。
CSS:

  #control {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;

        background-color: rgba(0,0,0, 0.05);
    }

    .description {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        background-color: rgba(0,0,0, 0.2);
        color: rgb(255,255,255);
        padding: 0 10px;

        line-height: 25px;

        text-align: center;
    }

    #description {
        transition: height 0.5s ease;
    }

    #description.expand {
        overflow: hidden;
        text-overflow: initial;
        white-space: normal;            
    }


JQuery代码:

$(document).ready(function(){
    var $el = $('#description'), 
        height = $el.outerHeight() + 'px', //get height in expanded state
        i=0, //initialize toggle variable
        initheight = 25 + 'px'; //sets the initial height
    $el.removeClass('expand').css('height', initheight);
    $("a").on("click", function(){
        //toggles the expand class, then sets height to either the height in
        //expanded state or 25 px (i++%2) acts as a toggle expresssion
        //(returns 25 at first click, height at second, 25 at third and so on)
        $el.toggleClass('expand').css('height', (i++%2) ? initheight : height);
    });
});