js truncate
by AntowaKartowa
HTML
<div class="container">
<div class="block">
<label class="heading">Enter result limitations</label>
<div class="subblock">
<label for="width" class="left">Width</label>
<input type="number" name="width" id="width" class="width" max="999" min="0" value="300">
<span>px</span>
</div>
<div class="subblock">
<label for="rows" class="left">Rows</label>
<input type="number" name="rows" id="rows" class="rows" max="20" min="0" value="3">
</div>
</div>
<div class="block">
<label for="input" class="heading">Enter text</label>
<textarea name="input" id="input" cols="40" rows="5" class="input">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Totam veniam nulla, quam nobis facere corporis autem ullam ratione, explicabo ab officia rem, repellendus facilis. Dignissimos ad, dolore odit aliquam voluptatem.</textarea>
<button class="truncate">Truncate</button>
</div>
<div class="block">
<label for="output" class="heading">Result</label>
<div id="output" class="output">
</div>
</div>
</div>
CSS
body {
padding: 0 20px;
background-color: #fff;
}
.container {
width: 400px;
padding: 20px 50px 50px;
margin: 50px auto;
background-color: cornsilk;
}
.block,
.subblock,
.heading,
.truncate,
.input {
display: block;
margin-bottom: 8px;
}
.heading {
margin-bottom: 10px;
}
.block {
margin-top: 30px;
}
.left {
display: inline-block;
width: 70px;
}
.width,
.rows {
width: 50px;
}
.input {
padding: 0;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
line-height: 1.3em;
background-color: aliceblue;
border-color: transparent;
outline: none;
}
.output {
position: relative;
width: 300px;
padding: 0;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
line-height: 1.3em;
max-height: 3.9em;
background-color: mistyrose;
}
#measure {
position: absolute;
top: 0;
opcity: 0;
z-index: -1;
}
JavaScript
class Truncate {
constructor({width, rows, input, button, output}) {
if (!this._isDOMElement(output)) throw new Error("Output parameter should be link to DOM element");
this._outputEl = output;
this._width = 300;
this.__width = parseInt(width.value, 10) || 300;
this._rows = 3;
this.__rows = parseInt(rows.value, 10) || 3;
this._text = "";
this.__text = input.value;
this._markedup = "";
this._breaksOffset = [];
width.addEventListener("blur", this._widthBlurHandler.bind(this));
rows.addEventListener("blur", this._rowsBlurHandler.bind(this));
["change", "blur"].forEach(e => input.addEventListener(e, this._textChangeHandler.bind(this)));
button.addEventListener("click", this.calcTruncation.bind(this));
}
_isDOMElement(o) {
if (typeof HTMLElement === "object") {
return o instanceof HTMLElement;
} else {
return o && typeof o === "object"
&& o !== null
&& o.nodeType === 1
&& typeof o.nodeName === "string"
}
}
_widthBlurHandler(e) {
e = e || window.event;
this.updateWidth(e.target.value);
}
updateWidth(width=300) {
this.__width = parseInt(width, 10);
}
_rowsBlurHandler(e) {
e = e || window.event;
this.updateRows(e.target.value);
}
updateRows(rows=3) {
this.__rows = parseInt(rows, 10);
}
_textChangeHandler(e) {
e = e || window.event;
this.updateText(e.target.value);
}
updateText(text) {
this.__text = text;
}
_isPropsChanged() {
return this._isTextChanged() || this._isSizeChanged();
}
_isTextChanged() {
return this.__text !== this._text;
}
_isSizeChanged() {
return this.__width !== this._width || this.__rows !== this._rows;
}
_isNoMeasures() {
return !this._mHeight || !this._m2Width;
}
calcTruncation(ev, text, width, rows) {
text && this.updateText(text);
width && this.updateWidth(width || this.__width);
rows &&...