简体   繁体   English

涉及“white-space:nowrap”的高度转换:可能用更少的Javascript?

[英]Transition of height with “white-space: nowrap” involved: possible with fewer Javascript?

Subject 学科

I have a text-box that hides overflowing text with ellipsis. 我有一个文本框,用省略号隐藏溢出的文本。 Only one line is visible. 只能看到一行。

I accomplished this using text-overflow and white-space: nowrap . 我使用text-overflowwhite-space: nowrap完成了这个white-space: nowrap The element has a fixed height value. 该元素具有固定的height值。

When tapped/clicked the box should smoothly expand (it's height) to show the rest of the text. 点击/单击时,框应平滑地展开(它的高度)以显示文本的其余部分。

I accomplished this using CSS transitions and Javascript. 我使用CSS过渡和Javascript完成了这个。 A hidden "shadow" description container contains the same text without white-space and overflow handling. 隐藏的“阴影”描述容器包含相同的文本,没有空格和溢出处理。 It has the full height. 它有全高。 When toggeling the actual box I set the height value read from the "shadow" element and add a class that will remove the white-space and overflow stuff. 当设置实际的盒子时,我设置从“阴影”元素读取的height值,并添加一个类,它将删除空白和溢出的东西。 The transition: height option makes this change smooth. transition: height选项使此更改顺利进行。

Question

I'd like to do this without extra Javascript logic and without the shadow element. 我想在没有额外的Javascript逻辑和没有阴影元素的情况下这样做。
I'd like to do this without 我想没有这样做

  • using setTimeout() to wait for the transition 使用setTimeout()等待转换
  • the shadow element 阴影元素

Only removing white-space and text-overflow does not work because they're not transitionable. 仅删除white-spacetext-overflow不起作用,因为它们不可转换。

I'm curious if there's another trick that does this. 我很好奇是否有另一种技巧可以做到这一点。

Working code 工作代码

Fiddle: http://jsfiddle.net/ywQTd/ (Make the window small enough to trigger text-overflow: hidden ) 小提琴: http//jsfiddle.net/ywQTd/ (使窗口小到足以触发text-overflow: hidden

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

Click Handler (in jQuery on-load Fn): 单击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: 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>

Update 更新

The initial title was 最初的头衔是

Transition of height with "white-space: nowrap" involved: is there a JS-less way? 涉及“white-space:nowrap”的高度转换:是否有一种JS-less方式?

I've changed it because it was not clear enough. 我改变了它,因为它不够清楚。 Of course it's not possible without Javascript since there has to be a click handler that will do "something". 当然,没有Javascript是不可能的,因为必须有一个点击处理程序才能做“某事”。 But I'd like to archive the goal with fewer Javascript logic and without timing in Javascript. 但我想用更少的Javascript 逻辑归档目标,而没有Javascript中的时间。 ;) ;)

Further I've clarified the first paragraph in the Question section . 此外,我已经澄清了问题部分的第一段


Addendum 附录

@jme11 kindly pointed out that my solution has some accessibility and SEO related issues. @ jme11善意地指出我的解决方案有一些可访问性和SEO相关的问题。 Yes, that's right, this example has these issues. 是的,没错,这个例子有这些问题。 But I've only extracted the relevant part of my code. 但我只提取了代码的相关部分。 Within the application both do not really matter: the page is rendered on the backend so that it works without Javascript, the shadow element is not present there. 在应用程序中,两者都不重要:页面在后端呈现,以便它在没有Javascript的情况下工作,阴影元素不存在。 It then "progressively enhances" and completely re-renders. 然后它“逐步增强”并完全重新渲染。 The "shadow element" might then still be a problem for clever search engines but I guess there's an attribute that would mark this as SEO-unrelated. 对于聪明的搜索引擎来说,“影子元素”可能仍然是一个问题,但我想有一个属性会将此标记为与SEO无关。 The accessibility issue is a good point but I'm sure there is some ARIA attribute that mutes this element. 可访问性问题是一个好点,但我确信有一些ARIA属性可以使这个元素静音。

But since I'd like to get rid of the shadow element anyway all this is not that interesting, is it? 但是,既然我想摆脱阴影元素,那么这一切都不是那么有趣,是吗?

I see the challenge with what you're trying to accomplish, but there are clearly issues (as I'm sure you know) with your current solution. 我看到了你想要完成的挑战,但是你现在的解决方案显然存在问题(我相信你知道)。 Namely, accessibility problems (because the "shadow element" is hidden visually but not aurally), SEO issues (because you're duplicating content you can get blacklisted), as well as readability/maintainably issues with your code and the content itself. 即,可访问性问题(因为“影子元素”在视觉上隐藏但不是听觉上),SEO问题(因为您复制的内容可以被列入黑名单),以及您的代码和内容本身的可读性/可维护性问题。

I recommend the following solution. 我推荐以下解决方案。 The trick here is that you actually remove the description class, get the height of the element and then add the description class back. 这里的技巧是你实际删除描述类,获取元素的高度,然后再添加描述类。 This all happens so quickly, there's no chance for the browser to repaint, and therefore, the user sees nothing (unless they happen to be watching that element in the developer tools). 这一切都发生得如此之快,浏览器没有机会重新绘制,因此,用户什么也看不见(除非他们碰巧在开发人员工具中看到这个元素)。

I found that, much like you've done initially, this requires a couple of milliseconds in a timeout before passing the height into the element after adding the description class back. 我发现,就像你最初做的那样,在将描述类添加回来之前将高度传递给元素之前,这需要几毫秒的超时。 Nonetheless, it feels very responsive and it works well. 尽管如此,它感觉非常敏感,而且效果很好。

Here's a fiddle . 这是一个小提琴 (note that I added the inline width to your control just for testing so I didn't have to keep making the window small). (请注意,我将内联宽度添加到您的控件中仅用于测试,因此我不必继续使窗口变小)。

HTML: 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: NOTE: I moved the line-height: 25px into the containing element so that when the description class is removed the height is still calculated based on the line-height. 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: 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);
        }
    });
});

I realize this isn't really answering your question: is there a JS-less way . 我意识到这并没有真正回答你的问题: 是否有一种没有JS的方式 The answer is really no, not that I can think of with your implementation or to produce the exact results you want. 答案是否定的,不是我能想到你的实现或产生你想要的确切结果。 Plus, AFAIK, you'd have to have a click handler no matter what, so in that regard, you have to have JS involved. 另外,AFAIK,你必须有一个点击处理程序,所以在这方面,你必须有JS参与。 Nonetheless, this is a cleaner, easier to read/maintain approach that solves some of the issue with your current implementation. 尽管如此,这是一种更清晰,更易于阅读/维护的方法,可以解决当前实现中的一些问题。

The problem is that you cannot do a transition to height:auto; 问题是你无法转换到height:auto; Try the following (uses the least amount of JS possible, to my opinion): http://jsfiddle.net/ywQTd/2/ 尝试以下(根据我的意见使用最少量的JS): http//jsfiddle.net/ywQTd/2/

My approach at first reads the height of the element in expanded state and then immediately puts it back to shrinked state. 我的方法首先读取处于展开状态的元素的高度,然后立即将其恢复到收缩状态。 Then on each click at first the class "expand" is toggled, which controls the values for word-wrap and so on. 然后在每次单击时,首先切换“expand”类,它控制word-wrap的值,依此类推。 And then the height is animated by setting a value with $().css() . 然后通过使用$().css()设置值来设置高度。
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 Code: 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);
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM