javascript - 展开/折叠一个 div 元素?

标签 javascript html yui

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

最佳答案

好的,在答案被接受之前没有太多时间,但这是在普通 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)

关于javascript - 展开/折叠一个 div 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16514883/

相关文章:

javascript - 滚动后动画标题导航缩小

javascript - React 防止焦点窃取 onClick

html - 调整窗口大小的最小宽度

jquery - 需要有关可折叠内容部分的帮助

javascript - JS - 检查 http ://In TextField Input

javascript - 视觉 : Selecting an option while setInterval is firing

c# - 在发布之前重新显示所有表单输入

javascript - 在 DataTable 中放置一个 YUI 按钮

javascript - YUI 压缩机的命令行选项

javascript - 为什么 yui DOM-create 方法有一个名为 'yui3-big-dummy' 的类的处理程序?