1

我想在默认情况下仅显示一个指定高度的内容框(比如一个 div)。底部会有一个“更多/更少”之类的链接,单击该链接时,我想显示内容框的全部内容。然后链接的“更多”名称将更改为“更少”。请给点提示。如果独立 JS,是否可以在 YUI 或更好的情况下做?

4

3 回答 3

5

好的,在答案被接受之前没有太多时间,但这是在普通的 ol'javascript 中执行更多/更少的一般原则,没有库。

CSS

p.more {
    margin: 5px;
}
p.less {
    height: 1em;
    overflow: hidden;
}
div.block {
    width: 500px;
    border-style: solid;
    border-width: 1px;
    border-radius: 3px;
    background-color: OldLace;
    box-shadow: 2px 3px 5px DimGray;
    margin: 10px;
}
p.continued {
    font-size: 10px;
    margin: -5px 0px 0px 5px;
}
p.continued:after {
    content: "[...]";
}
p.continuedHide {
    display: none;
}
div.control {
    text-align: center;
    width: 3em;
    height: 1em;
    border-radius: 10px;
    border: 1px solid ;
    margin: 5px;
    padding: 0px 0px 5px 0px;
    background-color: LightGray;
    box-shadow: 2px 3px 5px DimGray;
}
div.control:after {
    content: "more";
}
div.controlLess:after {
    content: "less";
}
div.control:hover {
    cursor: pointer;
}

HTML

<p class="more">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.</p>
<p class="more">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.</p>
<p class="more">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.</p>

Javascript

Array.prototype.forEach.call(document.getElementsByClassName("more"), function (more) {
    more.classList.toggle("less");

    var element = document.createElement("div");

    element.className = "block";
    more.parentNode.insertBefore(element, more).appendChild(more);

    element = document.createElement("p");
    element.className = "continued";
    more.parentNode.appendChild(element);

    element = document.createElement("div");
    element.className = "control";
    element.addEventListener("click", function () {
        this.classList.toggle("controlLess");
        more.classList.toggle("less");
        this.previousSibling.classList.toggle("continuedHide");
    }, false);

    more.parentNode.appendChild(element);
});

jsfiddle

您可以随意设置样式,只需使用 css,在最大化时设置高度并添加滚动以溢出。更改颜色,添加 CSS3 动画等

这是限制最大高度和自动添加滚动条的示例。

p.more {
    margin: 5px;
    height: 10em;
    overflow: auto;
}

jsfiddle

这是它工作所需的最低 CSS

p.less {
    height: 1em;
    overflow: hidden;
}
p.continued:after {
    content: "[...]";
}
p.continuedHide {
    display: none;
}
div.control:after {
    content: "more";
}
div.controlLess:after {
    content: "less";
}
div.control:hover {
    cursor: pointer;
}

jsfiddle

好的,所以我想我有点疯了,把它做成了一个库,我可能会稍后将它上传到 git-hub 或 google-code。它应该是跨浏览器的,至少我能够测试。它不使用任何额外的外部库,但我已经演示了它也可以与 jquery 一起使用。我发布的 CSS 不是最小的,而是我在演示中使用的。您还应该能够使用为jQuery More/Less Text

所需的基本标记结构是

<div class="more-less">
    <div class="more-block">
        <p>The Content</p>
    </div>
</div>

还有这个 CSS 和 Javascript

CSS

/* More Or Less CSS v1.1
 *
 * Add functionality that only displays the first few lines of a block of content
 * with a 'More/Less' link at the bottom, which when clicked, will expand or
 * contract the content. Written with cross-browser compatibility in mind and
 * does not require any external libraries.>
 *
 * Copyright (C) 2013  Graham Fairweather (a.k.a: Xotic750)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

div.more-less {
    width: 500px;
    height: auto;
    border-style: solid;
    border-width: 1px;
    border-radius: 3px;
    background-color: OldLace;
    box-shadow: 2px 3px 5px DimGray;
    margin: 10px;
}
div.more-block {
    margin: 5px;
}
div.more-block-less {
    height: 3em;
    overflow: hidden;
}
div.more-less-continued {
    position: relative;
    text-align: right;
    width: 1em;
    height: 1em;
    bottom: 1em;
    font-size: 0.8em;
    margin: 1em;
    float: right;
    line-height: 1em;
}
div.more-less-continued-hide {
    display: none;
}
div.more-less-control {
    text-align: center;
    width: 3em;
    height: 1em;
    border-radius: 10px;
    border: 1px solid;
    margin: 5px;
    background-color: LightGray;
    box-shadow: 2px 3px 5px DimGray;
    cursor: pointer;
    line-height: 1em;
}
div.more-block > * {
    width: 100%;
    height: auto;
    margin: auto;
}

Javascript

/*jslint maxerr: 50, indent: 4, browser: true, bitwise: true */
/*global tokenList */

/* More Or Less v1.4
 *
 * home: http://code.google.com/p/more-or-less/
 *
 * Add functionality that only displays the first few lines of a block of content
 * with a 'More/Less' link at the bottom, which when clicked, will expand or
 * contract the content. Written with cross-browser compatibility in mind and
 * now uses the DOMTokenList project for dealing with classList.
 *
 * http://code.google.com/p/domtokenlist/
 *
 * Copyright (C) 2013  Graham Fairweather (a.k.a: Xotic750)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var moreLess = (function (tokenList) {
    "use strict";

    var toStringFN = {}.toString,
        moreLessClassListProperty = "classList",
        classNameProperty = "className",
        texts = {
            "continued": "[...]",
            "more": "more",
            "less": "less"
        };

    function addEvent(node, type, func) {
        var handler;

        if (node.addEventListener) {
            node.addEventListener(type, func, false);
        } else if (node.attachEvent) {
            node["e" + type + func] = func;
            node[type + func] = function () {
                node["e" + type + func](window.event);
            };

            node.attachEvent("on" + type, node[type + func]);
        } else {
            handler = node["on" + type];
            if (typeof handler === "function") {
                node["on" + type] = function (evt) {
                    handler(evt);
                    func(evt);
                };
            } else {
                node["on" + type] = func;
            }
        }
    }

    function addTokenList(element) {
        if (!element[moreLessClassListProperty]) {
            tokenList.addTokenList(element, classNameProperty, moreLessClassListProperty);
        }
    }

    function getElementsByClassName(node, className) {
        var elements = node.getElementsByTagName("*"),
            length = elements.length,
            array = [],
            i = 0,
            element;

        while (i < length) {
            element = elements[i];
            addTokenList(element);
            if (element[moreLessClassListProperty].contains(className)) {
                array.push(element);
            }

            i += 1;
        }

        return array;
    }

    function createElement(content) {
        var moreLess = document.createElement("div"),
            element = document.createElement("div");

        addTokenList(element);
        element[moreLessClassListProperty].add("more-block", "more-block-less");
        if (typeof content === "string") {
            element.innerHTML = content;
        } else {
            element.appendChild(content);
        }

        addTokenList(moreLess);
        moreLess[moreLessClassListProperty].add("more-less", "more-less-added");
        moreLess.appendChild(element);

        element = document.createElement("div");
        addTokenList(element);
        element[moreLessClassListProperty].add("more-less-continued");
        element.appendChild(document.createTextNode(texts.continued));
        moreLess.appendChild(element);

        element = document.createElement("div");
        addTokenList(element);
        element[moreLessClassListProperty].add("more-less-control");
        element.appendChild(document.createTextNode(texts.more));
        moreLess.appendChild(element);

        return moreLess;
    }

    function addMarkup() {
        var moreLesses = getElementsByClassName(document, "more-less"),
            length = moreLesses.length,
            i = 0,
            node,
            child,
            element;

        while (i < length) {
            node = moreLesses[i];
            addTokenList(node);
            if (!node[moreLessClassListProperty].contains("more-less-added")) {
                node[moreLessClassListProperty].add("more-less-added");
                child = node.children[0];
                addTokenList(child);
                child[moreLessClassListProperty].add("more-block-less");

                element = document.createElement("div");
                addTokenList(element);
                element[moreLessClassListProperty].add("more-less-continued");
                element.appendChild(document.createTextNode(texts.continued));
                node.appendChild(element);

                element = document.createElement("div");
                addTokenList(element);
                element[moreLessClassListProperty].add("more-less-control");
                element.appendChild(document.createTextNode(texts.more));
                node.appendChild(element);
            }

            i += 1;
        }
    }

    function bind() {
        addEvent(document, "click", function onClicked(evt) {
            var target = evt.target,
                parent = target.parentNode,
                moreBlock = parent.children[0],
                continueds = getElementsByClassName(parent, "more-less-continued"),
                length,
                continued,
                item;

            if (moreBlock.nodeName === "DIV" && moreBlock[moreLessClassListProperty].contains("more-block")) {
                length = continueds.length;
                item = 0;
                while (item < length) {
                    continued = continueds[item];
                    if (continued[moreLessClassListProperty].contains("more-less-continued-hide")) {
                        continued[moreLessClassListProperty].remove("more-less-continued-hide");
                        if (item === 0) {
                            moreBlock[moreLessClassListProperty].add("more-block-less");
                            target.firstChild.nodeValue = texts.more;
                        }
                    } else {
                        continued[moreLessClassListProperty].add("more-less-continued-hide");
                        if (item === 0) {
                            moreBlock[moreLessClassListProperty].remove("more-block-less");
                            target.firstChild.nodeValue = texts.less;
                        }
                    }

                    item += 1;
                }
            }
        });
    }

    function setTexts(object) {
        if (toStringFN.call(object) === "[object Object]") {
            var i;

            for (i in object) {
                if (object.hasOwnProperty(i)) {
                    if (texts[i] && typeof object[i] === "string") {
                        texts[i] = object[i];
                    }
                }
            }
        }
    }

    return {
        "setTexts": setTexts,
        "bind": bind,
        "addMarkup": addMarkup,
        "createElement": createElement
    };
}(tokenList));

然后是演示Javascript

// These are the default texts, but using this method you can change them to what you want
moreLess.setTexts({
    "continued": "[...]",
    "more": "more",
    "less": "less"
});

// This method adds the required click listener to the document
moreLess.bind();
// This method causes a search of the document, and any matching markup will have
// the additional markup added
moreLess.addMarkup();

// Now for some dynamic examples

// Some text we will use
var text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.";

// Demonstartions

// Using dynamically created node with the `moreLess.createElement` method
var element = document.createElement("p");

element.appendChild(document.createTextNode(text));
document.body.appendChild(moreLess.createElement(element));

// Using dynamically created html text with the `moreLess.createElement` method
document.body.appendChild(moreLess.createElement("<p>" + text + "<p>"));

// Using dynamically created jquery node and jquery html text with the
// `moreLess.createElement` method
$(document.body).append(moreLess.createElement($("<p>").text(text).get(0)));
$(document.body).append(moreLess.createElement($("<p>").text(text).html()));

// Using html text with the jquery `append` method, then executing `moreLess.addMarkup`
// method upon a button click to add the additional markup.
var html = '<div class="more-less"> <div class="more-block" style="overflow: hidden;"> <img alt="Car 1" src="http://img130.imageshack.us/img130/4296/v2gr0wd.jpg"> <h2>Lorem ipsum dolor</h2> <p>' + text + '</p> </div> </div>'

$(document.body).append(html);
$(document.body).append($("<button>").text("Add Markup").click(moreLess.addMarkup));

无论如何,你可以看到演示jsfiddle

我现在要停止玩了,不过我会尝试添加一些评论;)一旦我把它上传到某个地方,我就会在这里发布一个链接。

这里是More Or Less项目。

更新:现在已经合并了我的其他项目DOMTokenList并更新了演示。


(来源:ohloh.net(来源:ohloh.net


于 2013-05-13T05:47:27.293 回答
3

YUI 中的 Anim 模块提供了你需要的东西。如果您在此处查看倒车 动画示例,它会显示如何做到这一点。这里是来源。

<div id="demo" class="yui3-module">
<div class="yui3-hd">
    <h3>Reversing an Animation</h3>
</div>
<div class="yui3-bd">
    <p>Click the icon in the header to toggle the element's height.</p>
</div>
</div>
<p>This is placeholder text used to demonstrate how the above animation affects subsequent content.</p> 


<script type="text/javascript">type="text/javascript">
YUI().use('anim', function(Y) {
var module = Y.one('#demo');

// add fx plugin to module body
var content = module.one('.yui3-bd').plug(Y.Plugin.NodeFX, {
    from: { height: 0 },
    to: {
        height: function(node) { // dynamic in case of change
            return node.get('scrollHeight'); // get expanded height (offsetHeight may be zero)
        }
    },

    easing: Y.Easing.easeOut,
    duration: 0.5
});

var onClick = function(e) {
    e.preventDefault();
    module.toggleClass('yui3-closed');
    content.fx.set('reverse', !content.fx.get('reverse')); // toggle reverse 
    content.fx.run();
};

// use dynamic control for dynamic behavior
var control = Y.Node.create(
    '<a title="collapse/expand element" class="yui3-toggle">' +
        '<em>toggle</em>' +
    '</a>'
);

// append dynamic control to header section
module.one('.yui3-hd').appendChild(control);
control.on('click', onClick);

});
</script>
于 2013-05-13T04:46:18.347 回答
0

你可以使用jQuery More/Less插件。它是一个漂亮的插件

看这里

于 2013-05-13T04:31:25.897 回答