在AngularJS中创建阅读更多链接

时间:2021-12-08 01:28:32

I want to create a link with read more text. if there are more than 3 lines in a paragraph this link should be visible and clicking on this it show display all the lines.

我想创建一个阅读更多文本的链接。如果段落中有超过3行,则此链接应该是可见的,单击此链接会显示所有行。

4 个解决方案

#1


11  

I wanted to do the same thing, so I created a directive. Have a look here: https://gist.github.com/doukasd/0744566c5494ebc8643f

我想做同样的事情,所以我创建了一个指令。看看这里:https://gist.github.com/doukasd/0744566c5494ebc8643f

Usage is pretty simple:

用法非常简单:

<p data-dd-collapse-text="100">{{veryLongText}}</p>

Where 100 is the character limit you want to specify.

其中100是您要指定的字符限制。

UPDATE: dd-text-collapse

更新:dd-text-collapse

#2


9  

For read more , you can use angular limitTo filter for limiting your paragraph to character's length instead of limiting paragraph to line numbers .

有关详细信息,您可以使用angular limitTo过滤器将段落限制为字符长度,而不是将段落限制为行号。

You can use something like this :

你可以使用这样的东西:

in html

在HTML中

<p> {{myString | limitTo:numLimit}} </p>
<button type='button' ng-click="readMore()">read more</button>

in controller

在控制器中

$scope.numLimit=200;
$scope.readMore=function(){
$scope.numLimit=10000;
};

#3


7  

Based on some of the information here I've put together a nice show more/less implementation

基于这里的一些信息,我已经把一个很好的节目组合在一起

Directive Definition showMore.js

指令定义showMore.js

.directive('showMore', 
function(){
    return {
        templateUrl: 'showMore.html',
        restrict: 'A',
        transclude: true,
        scope:{
            'showMoreHeight': '@'
        },
        controller: ['$scope', '$element', '$interval', function($scope, $element, $interval) {

            $scope.expanded = false;

            $interval(function(){
                renderStyles();
            }, 300);

            $scope.expandable = false;
            function renderStyles(){
                if($element.height() >= $scope.showMoreHeight && $scope.expanded === false){
                    $scope.expandable = true;
                }
            }

            $scope.showLessStyle = {
                'max-height': $scope.showMoreHeight + 'px',
                'overflow': 'hidden'
            };

        }]
    };
});

showMore.html

showMore.html

<span>
    <div ng-style='showLessStyle' ng-hide='expanded' ng-transclude>
    </div>
    <div ng-show='expanded' ng-transclude>
    </div>
    <a style='float:right;' ng-hide='expanded || !expandable' ng-click='expanded = !expanded' localize>show more</a>
    <a style='float:right;' ng-show='expanded && expandable' ng-click='expanded = !expanded'>show less</a>
</span>

The usage is fairly simple just transclude what ever you want to show more/less of

用法非常简单,只需转换您想要显示更多/更少的内容

USEAGE:

用途:

<div show-more show-more-height='150'>
    <div class='showMoreContent'></div>
</div>

I hope this is somewhat helpful!

我希望这有点帮助!

#4


5  

There can be some workaround.

可以有一些解决方法。

basic idea is like this

基本的想法是这样的

 1. at first, use javascript to calculate the original height
 2. if higher than 3 lines , set the overflow to hidden and show a button. The button is used to toggle state
 3.  if not,  do nothing

About the button.

关于按钮。

If the button is out of text area, it's no problem for you I think. If you need the button inline within the element, there are 2 possibilitis.

如果按钮超出文本区域,我认为对你来说没问题。如果您需要元素内嵌的按钮,则有2种可能性。

  1. if you want it position fixed at right-bottom, create a gradient background for the button, fade-out effect. It looks nice and very simple.

    如果你想将它固定在右下角,为按钮创建一个渐变背景,淡出效果。它看起来很好很简单。

    here is jsfiddle: http://jsfiddle.net/sunderls/HYHZ6/ . Everytime toggling the state, you actually change the class of the element.

    这里是jsfiddle:http://jsfiddle.net/sunderls/HYHZ6/。每次切换状态时,实际上都会更改元素的类。

  2. if you want it right after the end of text? it's a little tricky, since even if text height is 3 lines, you cannot be sure whether it remains 3 lines height , after appending a button next to it.

    如果你想在文本结束后立即使用它?它有点棘手,因为即使文本高度为3行,在添加旁边的按钮后,也无法确定它是否保持3行高度。

    I think one way is to use Range API, to calculate the paragraph dimensions, (I've used the api in my collamark.com, it's powerful but different browsers have different behaviors). Actually you can get the dimensions of every lines dynamically. And by some backwards loops, you can get the appropriate substring of the text, to show in collapsed mode, which is just right for 3 lines height with a button. (the api doc is here: https://developer.mozilla.org/en-US/docs/Web/API/range)

    我认为一种方法是使用Range API来计算段落尺寸,(我在我的collamark.com中使用了api,它功能强大,但不同的浏览器有不同的行为)。实际上,您可以动态获取每一行的尺寸。通过一些向后循环,您可以获得文本的相应子字符串,以折叠模式显示,这恰好适用于带有按钮的3行高度。 (api doc在这里:https://developer.mozilla.org/en-US/docs/Web/API/range)

    So now every time you toggle the state, you actually is change the text. not the class.

    所以现在每次切换状态时,实际上都是改变文本。不是班级。

Here begins the Code when do it in Angular

template

first, this kind of feature is a standalone module which you can reuse everywhere, so in your template, we create a new directive autoFolded, sth like this:

首先,这种功能是一个独立的模块,您可以在任何地方重复使用,因此在您的模板中,我们创建一个新的指令autoFolded,如下所示:

<auto-folded>
    <p>Some text here, maybe long maybe short</p>
</auto-folded>

directive.coffee

then we handle all the logic in directive definition( sorry for writing in coffee though)

然后我们处理指令定义中的所有逻辑(抱歉在咖啡中写作)

directive('autoFolded',[
 '$window'
($window) ->
    return {
        restrict: 'E'
        transclude: true
        template: '<div class="auto-folded"><div ng-transclude></div><a href ng-click="toggleFoldedState()" class="auto-folded--more"></a></div>'
        link: (scope, element, attrs)->
            $$window = $ $window
            content = $(element).find('.auto-folded')

            toggleFoldedState = ->
                if content.hasClass 'auto-folded--folded'
                    content.removeClass('auto-folded--folded').addClass('auto-folded--unfolded')
                else if content.hasClass 'auto-folded--unfolded'
                    content.removeClass('auto-folded--unfolded').addClass('auto-folded--folded')

                return

            scope.toggleFoldedState = toggleFoldedState


            init = ()->
                contentHeight = content.outerHeight()
                if contentHeight > 48
                    content.addClass 'auto-folded--folded'
                content.show()

            $$window.on 'ngcontentloaded',init

    }
])

here is the explaination

for this directive contains text it doesn't know, so it's a translucent direcitve. Like a modal popup, it contains the Text and a toggle button.

因为这个指令包含它不知道的文本,所以它是一个半透明的指令。像模态弹出窗口一样,它包含文本和切换按钮。

restrict: 'E'
transclude: true
template: '<div class="auto-folded"><div ng-transclude></div><a href ng-click="toggleFoldedState()" class="auto-folded--more"></a></div>'

when clicking the button, it actually do the toggling. If unfolded, then fold it; If foled, then unfolded. We accomplish this by toggling the classNames, the cold is straightforward

单击按钮时,它实际上进行切换。如果展开,则将其折叠;如果褪色,那么展开。我们通过切换classNames来实现这一目标,冷却是直截了当的

            toggleFoldedState = ->
                content.css 'color','red'

                if content.hasClass 'auto-folded--folded'
                    content.removeClass('auto-folded--folded').addClass('auto-folded--unfolded')
                else if content.hasClass 'auto-folded--unfolded'
                    content.removeClass('auto-folded--unfolded').addClass('auto-folded--folded')

                return

and we use ng-click="toggleFoldedState()" to bind this action to the toggling button

我们使用ng-click =“toggleFoldedState()”将此操作绑定到切换按钮

We have to do some initial work to fold the text if it's tall enough at page loaded. However, link function of directive is to create the actual Dom, before dom rendering.So in link, we cannot know the height, that's why we register the init() to ngcontentloaded event:

如果文本在页面加载时足够高,我们必须做一些初始工作来折叠文本。但是,指令的链接功能是在dom渲染之前创建实际的Dom。所以在链接中,我们无法知道高度,这就是我们将init()注册到ngcontentloaded事件的原因:

            init = ()->
                contentHeight = content.outerHeight()
                if contentHeight > 48
                    content.addClass 'auto-folded--folded'
                content.show()

            $$window.on 'ngcontentloaded',init

here I use 48px as 3-line-height, you can define your own, or calculate dynamically from the dom, like content.css('lineHeight').

这里我用48px作为3行高,你可以定义自己的,或者从dom动态计算,比如content.css('lineHeight')。

since this is done after dom rendering, so the text is already displayed before init(). There will be a ugly slideUp effect. That's why we first hide the dom using css(as following), and content.show() in init

因为这是在dom渲染之后完成的,所以文本已经在init()之前显示。会有一个丑陋的slideUp效果。这就是我们首先使用css(如下所示)和init中的content.show()隐藏dom的原因

So we are done with directive, the folded/unfoled state are controlled by className. here we go.

所以我们完成了指令,折叠/未折叠状态由className控制。开始了。

css.sass

(sorry I wrote it in sass)

(对不起,我是用sass写的)

.auto-folded
    display: none  //only display after init()
    position: relative

    .auto-folded--more //the button is placed at right-bottom, and default to hidden
        display: none
        position: absolute
        right: 0
        bottom: 0

    &.auto-folded--folded //when folded, set maxHeight, and overflow to hidden
        max-height: 48px
        overflow: hidden
        .auto-folded--more // toggling button is displayed,
            display: block
            &:before // and it's text is "more"
                content: "more"

    &.auto-folded--unfolded //when unfoled, s
        .auto-folded--more  // toggling button is displayed
            display: block
            &:before // and it's text is "hide"
                content: "hide" 

So the text of toggling button and visibility of it , are all controlled by the class of its parent.

因此,切换按钮的文本和它的可见性都由其父级的类控制。

for the parent 1. if text is not 3-line height, it will only have 'auto-folded' as css class, so the button is hidden

对于父级1.如果文本不是3行高,它将只有'自动折叠'作为css类,所以按钮被隐藏

  1. if text is over 3-line height, in init() process, it's classNames will be 'auto-folded auto-folded--folded'.
    then the button is shown. clicking it will toggle parent's classNames between 'auto-folded--folded' and 'auto-folded--unfolded'
  2. 如果文本超过3行高,在init()过程中,它的classNames将“自动折叠自动折叠 - 折叠”。然后显示按钮。点击它将在'自动折叠 - 折叠'和'自动折叠 - 展开'之间切换父级的classNames

#1


11  

I wanted to do the same thing, so I created a directive. Have a look here: https://gist.github.com/doukasd/0744566c5494ebc8643f

我想做同样的事情,所以我创建了一个指令。看看这里:https://gist.github.com/doukasd/0744566c5494ebc8643f

Usage is pretty simple:

用法非常简单:

<p data-dd-collapse-text="100">{{veryLongText}}</p>

Where 100 is the character limit you want to specify.

其中100是您要指定的字符限制。

UPDATE: dd-text-collapse

更新:dd-text-collapse

#2


9  

For read more , you can use angular limitTo filter for limiting your paragraph to character's length instead of limiting paragraph to line numbers .

有关详细信息,您可以使用angular limitTo过滤器将段落限制为字符长度,而不是将段落限制为行号。

You can use something like this :

你可以使用这样的东西:

in html

在HTML中

<p> {{myString | limitTo:numLimit}} </p>
<button type='button' ng-click="readMore()">read more</button>

in controller

在控制器中

$scope.numLimit=200;
$scope.readMore=function(){
$scope.numLimit=10000;
};

#3


7  

Based on some of the information here I've put together a nice show more/less implementation

基于这里的一些信息,我已经把一个很好的节目组合在一起

Directive Definition showMore.js

指令定义showMore.js

.directive('showMore', 
function(){
    return {
        templateUrl: 'showMore.html',
        restrict: 'A',
        transclude: true,
        scope:{
            'showMoreHeight': '@'
        },
        controller: ['$scope', '$element', '$interval', function($scope, $element, $interval) {

            $scope.expanded = false;

            $interval(function(){
                renderStyles();
            }, 300);

            $scope.expandable = false;
            function renderStyles(){
                if($element.height() >= $scope.showMoreHeight && $scope.expanded === false){
                    $scope.expandable = true;
                }
            }

            $scope.showLessStyle = {
                'max-height': $scope.showMoreHeight + 'px',
                'overflow': 'hidden'
            };

        }]
    };
});

showMore.html

showMore.html

<span>
    <div ng-style='showLessStyle' ng-hide='expanded' ng-transclude>
    </div>
    <div ng-show='expanded' ng-transclude>
    </div>
    <a style='float:right;' ng-hide='expanded || !expandable' ng-click='expanded = !expanded' localize>show more</a>
    <a style='float:right;' ng-show='expanded && expandable' ng-click='expanded = !expanded'>show less</a>
</span>

The usage is fairly simple just transclude what ever you want to show more/less of

用法非常简单,只需转换您想要显示更多/更少的内容

USEAGE:

用途:

<div show-more show-more-height='150'>
    <div class='showMoreContent'></div>
</div>

I hope this is somewhat helpful!

我希望这有点帮助!

#4


5  

There can be some workaround.

可以有一些解决方法。

basic idea is like this

基本的想法是这样的

 1. at first, use javascript to calculate the original height
 2. if higher than 3 lines , set the overflow to hidden and show a button. The button is used to toggle state
 3.  if not,  do nothing

About the button.

关于按钮。

If the button is out of text area, it's no problem for you I think. If you need the button inline within the element, there are 2 possibilitis.

如果按钮超出文本区域,我认为对你来说没问题。如果您需要元素内嵌的按钮,则有2种可能性。

  1. if you want it position fixed at right-bottom, create a gradient background for the button, fade-out effect. It looks nice and very simple.

    如果你想将它固定在右下角,为按钮创建一个渐变背景,淡出效果。它看起来很好很简单。

    here is jsfiddle: http://jsfiddle.net/sunderls/HYHZ6/ . Everytime toggling the state, you actually change the class of the element.

    这里是jsfiddle:http://jsfiddle.net/sunderls/HYHZ6/。每次切换状态时,实际上都会更改元素的类。

  2. if you want it right after the end of text? it's a little tricky, since even if text height is 3 lines, you cannot be sure whether it remains 3 lines height , after appending a button next to it.

    如果你想在文本结束后立即使用它?它有点棘手,因为即使文本高度为3行,在添加旁边的按钮后,也无法确定它是否保持3行高度。

    I think one way is to use Range API, to calculate the paragraph dimensions, (I've used the api in my collamark.com, it's powerful but different browsers have different behaviors). Actually you can get the dimensions of every lines dynamically. And by some backwards loops, you can get the appropriate substring of the text, to show in collapsed mode, which is just right for 3 lines height with a button. (the api doc is here: https://developer.mozilla.org/en-US/docs/Web/API/range)

    我认为一种方法是使用Range API来计算段落尺寸,(我在我的collamark.com中使用了api,它功能强大,但不同的浏览器有不同的行为)。实际上,您可以动态获取每一行的尺寸。通过一些向后循环,您可以获得文本的相应子字符串,以折叠模式显示,这恰好适用于带有按钮的3行高度。 (api doc在这里:https://developer.mozilla.org/en-US/docs/Web/API/range)

    So now every time you toggle the state, you actually is change the text. not the class.

    所以现在每次切换状态时,实际上都是改变文本。不是班级。

Here begins the Code when do it in Angular

template

first, this kind of feature is a standalone module which you can reuse everywhere, so in your template, we create a new directive autoFolded, sth like this:

首先,这种功能是一个独立的模块,您可以在任何地方重复使用,因此在您的模板中,我们创建一个新的指令autoFolded,如下所示:

<auto-folded>
    <p>Some text here, maybe long maybe short</p>
</auto-folded>

directive.coffee

then we handle all the logic in directive definition( sorry for writing in coffee though)

然后我们处理指令定义中的所有逻辑(抱歉在咖啡中写作)

directive('autoFolded',[
 '$window'
($window) ->
    return {
        restrict: 'E'
        transclude: true
        template: '<div class="auto-folded"><div ng-transclude></div><a href ng-click="toggleFoldedState()" class="auto-folded--more"></a></div>'
        link: (scope, element, attrs)->
            $$window = $ $window
            content = $(element).find('.auto-folded')

            toggleFoldedState = ->
                if content.hasClass 'auto-folded--folded'
                    content.removeClass('auto-folded--folded').addClass('auto-folded--unfolded')
                else if content.hasClass 'auto-folded--unfolded'
                    content.removeClass('auto-folded--unfolded').addClass('auto-folded--folded')

                return

            scope.toggleFoldedState = toggleFoldedState


            init = ()->
                contentHeight = content.outerHeight()
                if contentHeight > 48
                    content.addClass 'auto-folded--folded'
                content.show()

            $$window.on 'ngcontentloaded',init

    }
])

here is the explaination

for this directive contains text it doesn't know, so it's a translucent direcitve. Like a modal popup, it contains the Text and a toggle button.

因为这个指令包含它不知道的文本,所以它是一个半透明的指令。像模态弹出窗口一样,它包含文本和切换按钮。

restrict: 'E'
transclude: true
template: '<div class="auto-folded"><div ng-transclude></div><a href ng-click="toggleFoldedState()" class="auto-folded--more"></a></div>'

when clicking the button, it actually do the toggling. If unfolded, then fold it; If foled, then unfolded. We accomplish this by toggling the classNames, the cold is straightforward

单击按钮时,它实际上进行切换。如果展开,则将其折叠;如果褪色,那么展开。我们通过切换classNames来实现这一目标,冷却是直截了当的

            toggleFoldedState = ->
                content.css 'color','red'

                if content.hasClass 'auto-folded--folded'
                    content.removeClass('auto-folded--folded').addClass('auto-folded--unfolded')
                else if content.hasClass 'auto-folded--unfolded'
                    content.removeClass('auto-folded--unfolded').addClass('auto-folded--folded')

                return

and we use ng-click="toggleFoldedState()" to bind this action to the toggling button

我们使用ng-click =“toggleFoldedState()”将此操作绑定到切换按钮

We have to do some initial work to fold the text if it's tall enough at page loaded. However, link function of directive is to create the actual Dom, before dom rendering.So in link, we cannot know the height, that's why we register the init() to ngcontentloaded event:

如果文本在页面加载时足够高,我们必须做一些初始工作来折叠文本。但是,指令的链接功能是在dom渲染之前创建实际的Dom。所以在链接中,我们无法知道高度,这就是我们将init()注册到ngcontentloaded事件的原因:

            init = ()->
                contentHeight = content.outerHeight()
                if contentHeight > 48
                    content.addClass 'auto-folded--folded'
                content.show()

            $$window.on 'ngcontentloaded',init

here I use 48px as 3-line-height, you can define your own, or calculate dynamically from the dom, like content.css('lineHeight').

这里我用48px作为3行高,你可以定义自己的,或者从dom动态计算,比如content.css('lineHeight')。

since this is done after dom rendering, so the text is already displayed before init(). There will be a ugly slideUp effect. That's why we first hide the dom using css(as following), and content.show() in init

因为这是在dom渲染之后完成的,所以文本已经在init()之前显示。会有一个丑陋的slideUp效果。这就是我们首先使用css(如下所示)和init中的content.show()隐藏dom的原因

So we are done with directive, the folded/unfoled state are controlled by className. here we go.

所以我们完成了指令,折叠/未折叠状态由className控制。开始了。

css.sass

(sorry I wrote it in sass)

(对不起,我是用sass写的)

.auto-folded
    display: none  //only display after init()
    position: relative

    .auto-folded--more //the button is placed at right-bottom, and default to hidden
        display: none
        position: absolute
        right: 0
        bottom: 0

    &.auto-folded--folded //when folded, set maxHeight, and overflow to hidden
        max-height: 48px
        overflow: hidden
        .auto-folded--more // toggling button is displayed,
            display: block
            &:before // and it's text is "more"
                content: "more"

    &.auto-folded--unfolded //when unfoled, s
        .auto-folded--more  // toggling button is displayed
            display: block
            &:before // and it's text is "hide"
                content: "hide" 

So the text of toggling button and visibility of it , are all controlled by the class of its parent.

因此,切换按钮的文本和它的可见性都由其父级的类控制。

for the parent 1. if text is not 3-line height, it will only have 'auto-folded' as css class, so the button is hidden

对于父级1.如果文本不是3行高,它将只有'自动折叠'作为css类,所以按钮被隐藏

  1. if text is over 3-line height, in init() process, it's classNames will be 'auto-folded auto-folded--folded'.
    then the button is shown. clicking it will toggle parent's classNames between 'auto-folded--folded' and 'auto-folded--unfolded'
  2. 如果文本超过3行高,在init()过程中,它的classNames将“自动折叠自动折叠 - 折叠”。然后显示按钮。点击它将在'自动折叠 - 折叠'和'自动折叠 - 展开'之间切换父级的classNames