-
Notifications
You must be signed in to change notification settings - Fork 1
/
mTruncate.js
150 lines (121 loc) · 6.6 KB
/
mTruncate.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
(function ($) {
$.fn.mtruncate = function (options) {
var self = this;
var settings = $.extend({
maxLines: 11,
expandText: 'Expand',
collapseText: 'Collapse',
hideImageOnCollapse: true
}, options);
return this.each(function () {
//Modify the container so that it supports collapsing
var truncateElement = $(this).css('overflow', 'hidden');
var wrapper = truncateElement.wrap('<div class="mTruncate-wrapper mTruncate-collapsed" />').parent();
var control = $('<div class="mTruncate-control">' + settings.expandText + '</div>').appendTo(wrapper);
var floatStyle = truncateElement.css('float');
if (floatStyle == 'left' || floatStyle == 'right') {
wrapper.css('float', floatStyle);
}
var collapsedHeight = 0;
var foundLines = 0;
function calculateLines(first, element) {
if (first == true) {
collapsedHeight = 0;
foundLines = 0;
}
//Iterate through every element in the container
element.each(function (key, value) {
//Type 8 is a comment node, this item is not displayed
if (value.nodeType == 8) {
return true;
}
var tagName = value.tagName ? value.tagName.toLowerCase() : undefined;
// Unwrapped elements inside the container must be text, calculate the height based on lineheight
if (typeof tagName == 'undefined') {
//When the item has no height, stop calculating
var text = value.textContent.trim();
if (text.length == 0) {
return true;
}
//Calculate the height and lines of the text element
var textParent = $(this).parent();
var height = textParent.height();
var lineHeight = parseFloat(textParent.css('line-height'));
var containerLinesThatHaveToBeVisible = Math.round(height / lineHeight);
//Add size to ignore, we want to collapse with lines, not size
collapsedHeight += parseFloat(textParent.css('margin-top'));
//When there are too much lines, determine how many can be shown
var thisIsTheLastElementThatIsShown = foundLines + containerLinesThatHaveToBeVisible == settings.maxLines;
if ((foundLines + containerLinesThatHaveToBeVisible) >= settings.maxLines) {
containerLinesThatHaveToBeVisible = (settings.maxLines - foundLines);
}
//Set the new collapsedHeight and increase the total lines
collapsedHeight += containerLinesThatHaveToBeVisible * lineHeight;
foundLines += containerLinesThatHaveToBeVisible;
//When this element is folly shown, add the bottom margin
if (foundLines < settings.maxLines || thisIsTheLastElementThatIsShown) {
collapsedHeight += parseFloat(textParent.css('margin-bottom'));
}
return true;
} else if (tagName.length == 2 && tagName[0] == 'h' && isNaN(tagName[1]) == false) {
//Include all header items, even when they have to be truncated, so the user will see that he is missing text
collapsedHeight += $(value).height();
collapsedHeight += parseFloat($(value).css('margin-top'));
collapsedHeight += parseFloat($(value).css('margin-bottom'));
foundLines++;
} else if (tagName == 'img') {
//An image is not text, always show
if (settings.hideImageOnCollapse) {
if ($(value).hasClass('mTruncate-hidden') == false) {
$(value).addClass('mTruncate-hidden');
}
return true;
}
collapsedHeight += $(value).height();
collapsedHeight += parseFloat($(value).css('margin-top'));
collapsedHeight += parseFloat($(value).css('margin-bottom'));
foundLines++;
} else if ($(value).contents().length > 0) {
// Add height of children
calculateLines(false, $(value).contents());
}
if (foundLines >= settings.maxLines) {
return false;
}
});
}
//On resize, recalculate the show more
$(window).resize(function () {
calculateLines(true, truncateElement.contents());
if (collapsedHeight == self.height() || foundLines < settings.maxLines) {
control.hide();
}
if (wrapper.hasClass('mTruncate-collapsed')) {
truncateElement.height(collapsedHeight);
}
}).trigger('resize');
//Show hide the element
control.click(function () {
if (wrapper.hasClass('mTruncate-collapsed')) {
$('.mTruncate-hidden').show();
var fullHeight = truncateElement.css('height', '100%').outerHeight();
$('.mTruncate-hidden').hide();
truncateElement.css('height', collapsedHeight);
truncateElement.animate({height: fullHeight}, 'slow', function () {
truncateElement.css('height', '');
});
control.html(settings.collapseText);
$('.mTruncate-hidden').fadeIn('slow');
wrapper.removeClass('mTruncate-collapsed');
} else {
if (settings.hideImageOnCollapse == true) {
$('.mTruncate-hidden').fadeOut('slow');
}
truncateElement.animate({height: collapsedHeight}, 'slow');
control.html(settings.expandText);
wrapper.addClass('mTruncate-collapsed');
}
});
});
};
}(jQuery));