类似 Facebook 的 "show more" 按钮,用于带有 URL 的字符串

Facebook-like "show more" button for a string with URLs

我正在尝试使用类似于 Facebook show more 行为的功能。 我想要它 trim 字符串 if:

这听起来很简单,我已经有了一个初始函数(仅按长度完成,我还没有实现 /n 次):

function contentShowMore($string, $max_length) {
    if(mb_strlen($string, 'utf-8') <= $max_length) {
        return $string; // return the original string if haven't passed $max_length
    } else {
        $teaser = mb_substr($string, 0, $max_length); // trim to max length
        $dots = '<span class="show-more-dots"> ...</span>'; // add dots
        $show_more_content = mb_substr($string, $max_length); // get the hidden content
        $show_more_wrapper = '<span class="show-more-content">'.$show_more_content.'</span>'; // wrap it

        return $teaser.$dots.$show_more_wrapper; // connect all together for usage on HTML.
    }
}

问题在于该字符串可能包含 URL,因此会破坏它们。我需要找到一种方法来制作功能性 show-more 按钮来检查长度、换行符并且不会剪切 URL。

谢谢!

示例:

输入:contentShowMore("hello there http://google.com/ good day!", 20).

输出:

hello there http://g
<span class="show-more-dots"> ...</span>
<span class="show-more-content">oogle.com/ good day!</span>

我想要的输出:

hello there http://google.com/
<span class="show-more-dots"> ...</span>
<span class="show-more-content"> good day!</span>

找到解决方案!

function contentShowMore($string, $max_length, $max_newlines) {

    $trim_str = trim($string);

    if(mb_strlen($trim_str, 'utf-8') <= $max_length && substr_count($trim_str, "\n") < $max_newlines) { // return the original if short, or less than X newlines
        return $trim_str;
    } else {
        $teaser = mb_substr($trim_str, 0, $max_length); // text to show
        $show_more_content = mb_substr($trim_str, $max_length);

        // the read more might have cut a string (or worse - an URL) in the middle of it.
        // so we will take all the rest of the string before the next whitespace and will add it back to the teaser.
        $content_parts = explode(' ', $show_more_content, 2); // [0] - before first space, [1] - after first space
        $teaser .= $content_parts[0];

        if(isset($content_parts[1])) { // if there are still leftover strings, its on show more! :)
            $show_more_content = $content_parts[1];
        }

        // NOW WERE CHEKING MAX NEWLINES.
        $teaser_parts = explode("\n", $teaser); // break to array.
        $teaser = implode("\n", array_slice($teaser_parts, 0, $max_newlines)); // take the first $max_newlines lines and use them as teaser.
        $show_more_content = implode("\n", array_slice($teaser_parts, $max_newlines)) . ' ' . $show_more_content; // connect the rest to the hidden content.

        if(mb_strlen($show_more_content, "UTF-8") === 0) {
            return $trim_str; // nothing to hide - return original.
        } else {
            $show_more_wrapper = '<span class="show-more-content">'.$show_more_content.'</span>';

            $dots = '<span class="show-more-dots"> ...</span>'; // dots will be visible between the teaser and the hidden.
            $button = ' <span class="show-more">Show more</span>';

            return $teaser.$dots.$button.$show_more_wrapper; // connect ingredients
        }

    }
}