展开/折叠div元素?

时间:2013-05-13 04:29:32

标签: javascript html yui

我希望默认情况下只显示指定高度的内容框(例如div)。底部会有一个“更多/更少”的链接,点击后,我想显示内容框的完整内容。然后链接的“更多”名称将更改为“更少”。请给出一些提示。 是否有可能在YUI或更好的情况下做独立的JS?

3 个答案:

答案 0 :(得分:5)

好的,在答案被接受之前没有多少时间,但是这里的一般原则是在普通的'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 并更新了演示。

答案 1 :(得分:3)

YUI中的Anim模块提供您所需的功能。如果你看一下倒车animation example,它会说明如何做到这一点。这是来源。

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

答案 2 :(得分:0)

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

SEE HERE