高度与“;空白:nowrap”;涉及:可能使用更少的Javascript

Transition of height with "white-space: nowrap" involved: possible with fewer Javascript?

本文关键字:Javascript 涉及 空白 nowrap 高度      更新时间:2023-09-26

主题

我有一个用省略号隐藏溢出文本的文本框。只有一行可见。

我使用text-overflowwhite-space: nowrap实现了这一点。元素具有固定的height值。

点击/单击时,框应平滑展开(其高度(以显示其余文本。

我使用CSS转换和Javascript实现了这一点。隐藏的"阴影"描述容器包含相同的文本,没有空格和溢出处理。它有全高。当切换实际框时,我设置了从"shadow"元素读取的height值,并添加了一个类,该类将删除空白和溢出内容。transition: height选项使此更改变得平滑。

问题

我想在没有额外Javascript逻辑和shadow元素的情况下完成这项工作
我想在没有的情况下完成这项工作

  • 使用setTimeout()等待转换
  • 阴影元素

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

我很好奇是否还有其他的把戏可以做到这一点。

工作代码

Fiddle: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;
}

单击处理程序(在加载Fn的jQuery中(:

$("...").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>

更新

最初的标题是

涉及"空白:nowrap"的高度转换:是否有一种无JS的方式?

我把它改了,因为它不够清晰。当然,没有Javascript是不可能的,因为必须有一个点击处理程序来做"一些事情"。但我想用更少的Javascript逻辑来实现目标,并且在Javascript中不计时。(

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


附录

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

但既然我无论如何都想去掉阴影元素,这一切就没那么有趣了,是吗?

我看到了您试图实现的挑战,但您当前的解决方案显然存在问题(我相信您也知道(。也就是说,可访问性问题(因为"阴影元素"在视觉上隐藏,但在听觉上不隐藏(、SEO问题(因为你在复制内容,你可能会被列入黑名单(,以及代码和内容本身的可读性/可维护性问题。

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

我发现,就像您最初所做的那样,在添加回描述类之后,在将高度传递到元素之前,这需要几毫秒的超时时间。尽管如此,它感觉反应很快,效果也很好。

这是一把小提琴。(注意,我只是为了测试而在控件中添加了内联宽度,这样我就不必一直让窗口变小(。

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:注意:我将行高:25px移动到包含元素中,这样当删除描述类时,高度仍然基于行高计算

#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。尽管如此,这是一种更干净、更易于阅读/维护的方法,可以解决当前实现中的一些问题。

问题是无法转换到height:auto;请尝试以下操作(在我看来,使用尽可能少的JS(:http://jsfiddle.net/ywQTd/2/

我的方法首先读取处于展开状态的元素的高度,然后立即将其放回收缩状态。然后,每次点击时,首先会切换类"expand",它控制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);
    });
});