Ответ 1
Я думаю, что лучший способ - напрямую модифицировать плагин readmore.js. Поэтому я добавляю шаг и новую метку:
$('article').readmore({
speed: 500,
collapsedHeight:200,
collapsedMoreHeight: 400, // Always bigger than collapsedHeigh. There isn't any control to that. Be careful.
moreLink: '<a class="white-shadow" href="#">More information</a>',
evenMoreLink: '<a class="white-shadow" href="#">Even More informations</a>', // Add new label
lessLink: '<a href="#">Less information</a>'
});
Самые большие изменения, которые я сделал, таковы:
var $element = $(element),
newHeight = '',
newLink = '',
expanded = false,
collapsedHeight = $element.data('collapsedHeight'),
collapsedMoreHeight = this.options.collapsedMoreHeight; // add an Even More informations
if ($element.data('expandedHeight') <= collapsedMoreHeight){
//This is the normal code if the article height is smaller than my new option
if ($element.height() <= collapsedHeight) {
newHeight = $element.data('expandedHeight') + 'px';
newLink = 'lessLink';
expanded = true;
}
else {
newHeight = collapsedHeight;
newLink = 'moreLink';
}
} else {
//Here it works the new step: 'Even More informations'
if ($element.height() <= collapsedHeight) {
newHeight = collapsedMoreHeight;
newLink = 'evenMoreLink';
expanded = false;
} else if ($element.height() > collapsedHeight && $element.height() <= collapsedMoreHeight){
newHeight = $element.data('expandedHeight') + 'px';
newLink = 'lessLink';
expanded = true;
}
else {
newHeight = collapsedHeight;
newLink = 'moreLink';
}
}
// This is the new Readmore.js file. Save this in external file.
/*!
* @preserve
*
* Readmore.js jQuery plugin
* Author: @jed_foster
* Project home: http://jedfoster.github.io/Readmore.js
* Licensed under the MIT license
*
* Debounce function from http://davidwalsh.name/javascript-debounce-function
*/
/* global jQuery */
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function($) {
'use strict';
var readmore = 'readmore',
defaults = {
speed: 100,
collapsedHeight: 50,
collapsedMoreHeight: 150, // add an Even More informations Height
heightMargin: 16,
moreLink: '<a href="#">More informations</a>',
evenMoreLink: '<a href="#">Even more informations</a>', // add new label
lessLink: '<a href="#">Close</a>',
embedCSS: true,
blockCSS: 'display: block; width: 100%;',
startOpen: false,
// callbacks
blockProcessed: function() {},
beforeToggle: function() {},
afterToggle: function() {}
},
cssEmbedded = {},
uniqueIdCounter = 0;
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (! immediate) {
func.apply(context, args);
}
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
}
function uniqueId(prefix) {
var id = ++uniqueIdCounter;
return String(prefix == null ? 'rmjs-' : prefix) + id;
}
function setBoxHeights(element) {
var el = element.clone().css({
height: 'auto',
width: element.width(),
maxHeight: 'none',
overflow: 'hidden'
}).insertAfter(element),
expandedHeight = el.outerHeight(),
cssMaxHeight = parseInt(el.css({maxHeight: ''}).css('max-height').replace(/[^-\d\.]/g, ''), 10),
defaultHeight = element.data('defaultHeight');
el.remove();
var collapsedHeight = cssMaxHeight || element.data('collapsedHeight') || defaultHeight;
// Store our measurements.
element.data({
expandedHeight: expandedHeight,
maxHeight: cssMaxHeight,
collapsedHeight: collapsedHeight
})
// and disable any 'max-height' property set in CSS
.css({
maxHeight: 'none'
});
}
var resizeBoxes = debounce(function() {
$('[data-readmore]').each(function() {
var current = $(this),
isExpanded = (current.attr('aria-expanded') === 'true');
setBoxHeights(current);
// Resize only if expanded
if(isExpanded){
current.css({
height: current.data('expandedHeight')
});
}
});
}, 100);
function embedCSS(options) {
if (! cssEmbedded[options.selector]) {
var styles = ' ';
if (options.embedCSS && options.blockCSS !== '') {
styles += options.selector + ' + [data-readmore-toggle], ' +
options.selector + '[data-readmore]{' +
options.blockCSS +
'}';
}
// Include the transition CSS even if embedCSS is false
styles += options.selector + '[data-readmore]{' +
'transition: height ' + options.speed + 'ms;' +
'overflow: hidden;' +
'}';
(function(d, u) {
var css = d.createElement('style');
css.type = 'text/css';
if (css.styleSheet) {
css.styleSheet.cssText = u;
}
else {
css.appendChild(d.createTextNode(u));
}
d.getElementsByTagName('head')[0].appendChild(css);
}(document, styles));
cssEmbedded[options.selector] = true;
}
}
function Readmore(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
embedCSS(this.options);
this._defaults = defaults;
this._name = readmore;
this.init();
// IE8 chokes on 'window.addEventListener', so need to test for support.
if (window.addEventListener) {
// Need to resize boxes when the page has fully loaded.
window.addEventListener('load', resizeBoxes);
window.addEventListener('resize', resizeBoxes);
}
else {
window.attachEvent('load', resizeBoxes);
window.attachEvent('resize', resizeBoxes);
}
}
Readmore.prototype = {
init: function() {
var current = $(this.element);
current.data({
defaultHeight: this.options.collapsedHeight,
heightMargin: this.options.heightMargin
});
setBoxHeights(current);
var collapsedHeight = current.data('collapsedHeight'),
heightMargin = current.data('heightMargin');
if (current.outerHeight(true) <= collapsedHeight + heightMargin) {
// The block is shorter than the limit, so there no need to truncate it.
if (this.options.blockProcessed && typeof this.options.blockProcessed === 'function') {
this.options.blockProcessed(current, false);
}
return true;
}
else {
var id = current.attr('id') || uniqueId(),
useLink = this.options.startOpen ? this.options.lessLink : this.options.moreLink;
current.attr({
'data-readmore': '',
'aria-expanded': this.options.startOpen,
'id': id
});
current.after($(useLink)
.on('click', (function(_this) {
return function(event) {
_this.toggle(this, current[0], event);
};
})(this))
.attr({
'data-readmore-toggle': id,
'aria-controls': id
}));
if (! this.options.startOpen) {
current.css({
height: collapsedHeight
});
}
if (this.options.blockProcessed && typeof this.options.blockProcessed === 'function') {
this.options.blockProcessed(current, true);
}
}
},
toggle: function(trigger, element, event) {
if (event) {
event.preventDefault();
}
if (! trigger) {
trigger = $('[aria-controls="' + this.element.id + '"]')[0];
}
if (! element) {
element = this.element;
}
/////////////////////////
// I changed this part //
/////////////////////////
var $element = $(element),
newHeight = '',
newLink = '',
expanded = false,
collapsedHeight = $element.data('collapsedHeight'),
collapsedMoreHeight = this.options.collapsedMoreHeight; // add an Even More informations
if ($element.data('expandedHeight') <= collapsedMoreHeight){
//This is the normal code if the article height is smaller than my new option
if ($element.height() <= collapsedHeight) {
newHeight = $element.data('expandedHeight') + 'px';
newLink = 'lessLink';
expanded = true;
}
else {
newHeight = collapsedHeight;
newLink = 'moreLink';
}
} else {
//Here it works the new step: 'Even More informations'
if ($element.height() <= collapsedHeight) {
newHeight = collapsedMoreHeight;
newLink = 'evenMoreLink';
expanded = false;
} else if ($element.height() > collapsedHeight && $element.height() <= collapsedMoreHeight){
newHeight = $element.data('expandedHeight') + 'px';
newLink = 'lessLink';
expanded = true;
}
else {
newHeight = collapsedHeight;
newLink = 'moreLink';
}
}
////////////////
// End change //
////////////////
// Fire beforeToggle callback
// Since we determined the new "expanded" state above we're now out of sync
// with our true current state, so we need to flip the value of 'expanded'
if (this.options.beforeToggle && typeof this.options.beforeToggle === 'function') {
this.options.beforeToggle(trigger, $element, ! expanded);
}
$element.css({'height': newHeight});
// Fire afterToggle callback
$element.on('transitionend', (function(_this) {
return function() {
if (_this.options.afterToggle && typeof _this.options.afterToggle === 'function') {
_this.options.afterToggle(trigger, $element, expanded);
}
$(this).attr({
'aria-expanded': expanded
}).off('transitionend');
}
})(this));
$(trigger).replaceWith($(this.options[newLink])
.on('click', (function(_this) {
return function(event) {
_this.toggle(this, element, event);
};
})(this))
.attr({
'data-readmore-toggle': $element.attr('id'),
'aria-controls': $element.attr('id')
}));
},
destroy: function() {
$(this.element).each(function() {
var current = $(this);
current.attr({
'data-readmore': null,
'aria-expanded': null
})
.css({
maxHeight: '',
height: ''
})
.next('[data-readmore-toggle]')
.remove();
current.removeData();
});
}
};
$.fn.readmore = function(options) {
var args = arguments,
selector = this.selector;
options = options || {};
if (typeof options === 'object') {
return this.each(function() {
if ($.data(this, 'plugin_' + readmore)) {
var instance = $.data(this, 'plugin_' + readmore);
instance.destroy.apply(instance);
}
options.selector = selector;
$.data(this, 'plugin_' + readmore, new Readmore(this, options));
});
}
else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
return this.each(function () {
var instance = $.data(this, 'plugin_' + readmore);
if (instance instanceof Readmore && typeof instance[options] === 'function') {
instance[options].apply(instance, Array.prototype.slice.call(args, 1));
}
});
}
};
}));
// Init plugin
$('article').readmore({
speed: 500,
collapsedHeight:200,
collapsedMoreHeight: 400, // This is your new second height. Always bigger than collapsedHeigh. There isn't any control to that. Be careful.
moreLink: '<a class="white-shadow" href="#">More information</a>',
evenMoreLink: '<a class="white-shadow" href="#">Even More informations</a>', // Add new label
lessLink: '<a href="#">Less information</a>'
});
body { font: 16px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; color: #444; }
code { color: #777; font-family: "Source Code Pro", "Menlo", "Courier New", monospace;}
a { color: #178DB1; }
.container { margin: 0 auto; max-width: 960px; }
#info + .readmore-js-toggle { padding-bottom: 1.5em; border-bottom: 1px solid #999; font-weight: bold;}
.white-shadow{
position:relative;
}
.white-shadow:after{
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 85%);
bottom: 100%;
content: '';
display: inline-block;
height: 150px;
position: absolute;
right: 0;
width: 100%;
}
#demo { padding: 0 10%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<section id="demo">
<article>
<h2>Artisanal Narwahls</h2>
<p>From this distant vantage point, the Earth might not seem of any particular interest. But for us, it different. Consider again that dot. That here. That home. That us. On it everyone you love, everyone you know, everyone you ever heard of, every human being who ever was, lived out their lives. The aggregate of our joy and suffering, thousands of confident religions, ideologies, and economic doctrines, every hunter and forager, every hero and coward, every creator and destroyer of civilization, every king and peasant, every young couple in love, every mother and father, hopeful child, inventor and explorer, every teacher of morals, every corrupt politician, every "superstar," every "supreme leader," every saint and sinner in the history of our species lived there – on a mote of dust suspended in a sunbeam.</p>
<p>Space, the final frontier. These are the voyages of the starship Enterprise. Its five year mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no man has gone before!</p>
</article>
<article>
<h2>Portland Leggings</h2>
<p>Here how it is: Earth got used up, so we terraformed a whole new galaxy of Earths, some rich and flush with the new technologies, some not so much. Central Planets, them was formed the Alliance</p>
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut odio neque, dapibus a tincidunt sed, molestie in diam. Quisque quis vulputate tellus. Nulla nisl mi, rhoncus et magna cursus, euismod vehicula erat. Integer fringilla urna orci, at tempor nisi suscipit ut. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec non laoreet ex. Cras et purus augue. Donec a urna et leo malesuada laoreet. Duis tortor massa, fermentum et porta id, pharetra suscipit lorem. Donec molestie nunc nisi, sed faucibus turpis facilisis eget. Morbi eros mauris, fringilla in est a, vehicula tempus felis. Nullam sodales tincidunt turpis sed dapibus.</p>
<p> Proin efficitur, leo ac sagittis faucibus, elit purus consectetur dolor, et scelerisque orci neque a orci. Nullam ut congue libero, in ornare mi. Quisque mattis porttitor nulla non fermentum. Suspendisse euismod facilisis magna, eget interdum leo semper sed. Nullam pretium, nisl sit amet auctor rhoncus, velit ipsum ullamcorper turpis, nec feugiat mauris diam ac lorem. Cras hendrerit non eros id ultricies. Aenean sed felis purus. Sed commodo, enim sed aliquet egestas, nisl odio porta ante, ac euismod justo turpis in mauris. Ut lobortis augue ut ex scelerisque, ut lacinia libero sollicitudin. Pellentesque vestibulum ac tellus sit amet commodo. Phasellus eu nunc nibh. In porta metus sed pharetra aliquet. Etiam eu magna id erat accumsan pellentesque pulvinar eget erat.</p>
<p> Etiam vitae aliquam nisi. Aliquam vel suscipit felis. Donec non dapibus odio. Vivamus tincidunt mauris in tortor fermentum, a laoreet sem semper. Sed luctus vitae turpis vitae vulputate. Integer a libero orci. Morbi eu porttitor nisi, facilisis consectetur velit. Suspendisse sed facilisis velit. Proin rutrum ligula a purus mattis ullamcorper. Quisque sit amet aliquam enim. Etiam eleifend nibh velit, sit amet pulvinar est pulvinar eget. Fusce egestas ornare tellus sagittis pulvinar. Nulla aliquam magna id sem consectetur tristique. Nullam auctor vestibulum ex eget laoreet. Quisque interdum quam in nisi rhoncus rutrum. </p>
</article>
<article>
<h2>This section is shorter than the Readmore minimum</h2>
<p>Space, the final frontier. These are the voyages of the starship Enterprise. Its five year mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no man has gone before!</p>
</article>
<article>
<h2>Portland Leggings</h2>
<p>Here how it is: Earth got used up, so we terraformed a whole new galaxy of Earths, some rich and flush with the new technologies, some not so much. Central Planets, them was formed the Alliance</p>
<p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut odio neque, dapibus a tincidunt sed, molestie in diam. Quisque quis vulputate tellus. Nulla nisl mi, rhoncus et magna cursus, euismod vehicula erat. Integer fringilla urna orci, at tempor nisi suscipit ut. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec non laoreet ex. Cras et purus augue. Donec a urna et leo malesuada laoreet. Duis tortor massa, fermentum et porta id, pharetra suscipit lorem. Donec molestie nunc nisi, sed faucibus turpis facilisis eget. Morbi eros mauris, fringilla in est a, vehicula tempus felis. Nullam sodales tincidunt turpis sed dapibus.</p>
<p> Proin efficitur, leo ac sagittis faucibus, elit purus consectetur dolor, et scelerisque orci neque a orci. Nullam ut congue libero, in ornare mi. Quisque mattis porttitor nulla non fermentum. Suspendisse euismod facilisis magna, eget interdum leo semper sed. Nullam pretium, nisl sit amet auctor rhoncus, velit ipsum ullamcorper turpis, nec feugiat mauris diam ac lorem. Cras hendrerit non eros id ultricies. Aenean sed felis purus. Sed commodo, enim sed aliquet egestas, nisl odio porta ante, ac euismod justo turpis in mauris. Ut lobortis augue ut ex scelerisque, ut lacinia libero sollicitudin. Pellentesque vestibulum ac tellus sit amet commodo. Phasellus eu nunc nibh. In porta metus sed pharetra aliquet. Etiam eu magna id erat accumsan pellentesque pulvinar eget erat.</p>
<p> Etiam vitae aliquam nisi. Aliquam vel suscipit felis. Donec non dapibus odio. Vivamus tincidunt mauris in tortor fermentum, a laoreet sem semper. Sed luctus vitae turpis vitae vulputate. Integer a libero orci. Morbi eu porttitor nisi, facilisis consectetur velit. Suspendisse sed facilisis velit. Proin rutrum ligula a purus mattis ullamcorper. Quisque sit amet aliquam enim. Etiam eleifend nibh velit, sit amet pulvinar est pulvinar eget. Fusce egestas ornare tellus sagittis pulvinar. Nulla aliquam magna id sem consectetur tristique. Nullam auctor vestibulum ex eget laoreet. Quisque interdum quam in nisi rhoncus rutrum. </p>
<p> Proin efficitur, leo ac sagittis faucibus, elit purus consectetur dolor, et scelerisque orci neque a orci. Nullam ut congue libero, in ornare mi. Quisque mattis porttitor nulla non fermentum. Suspendisse euismod facilisis magna, eget interdum leo semper sed. Nullam pretium, nisl sit amet auctor rhoncus, velit ipsum ullamcorper turpis, nec feugiat mauris diam ac lorem. Cras hendrerit non eros id ultricies. Aenean sed felis purus. Sed commodo, enim sed aliquet egestas, nisl odio porta ante, ac euismod justo turpis in mauris. Ut lobortis augue ut ex scelerisque, ut lacinia libero sollicitudin. Pellentesque vestibulum ac tellus sit amet commodo. Phasellus eu nunc nibh. In porta metus sed pharetra aliquet. Etiam eu magna id erat accumsan pellentesque pulvinar eget erat.</p>
<p> Etiam vitae aliquam nisi. Aliquam vel suscipit felis. Donec non dapibus odio. Vivamus tincidunt mauris in tortor fermentum, a laoreet sem semper. Sed luctus vitae turpis vitae vulputate. Integer a libero orci. Morbi eu porttitor nisi, facilisis consectetur velit. Suspendisse sed facilisis velit. Proin rutrum ligula a purus mattis ullamcorper. Quisque sit amet aliquam enim. Etiam eleifend nibh velit, sit amet pulvinar est pulvinar eget. Fusce egestas ornare tellus sagittis pulvinar. Nulla aliquam magna id sem consectetur tristique. Nullam auctor vestibulum ex eget laoreet. Quisque interdum quam in nisi rhoncus rutrum. </p>
</article>
</section>
</div>