readmore-lines
Version:
A lightweight JavaScript library for creating 'read more/read less' functionality with text truncation
360 lines (274 loc) ⢠8.94 kB
Markdown
# ReadMore.js
A lightweight, high-performance JavaScript library for creating "read more/read less" functionality with text truncation. Features automatic caching, smooth animations, and comprehensive browser support.
## Features
- š **High Performance**: Cached line height calculations and CSS styles
- š§ **Smart Caching**: Automatic memory management with WeakMap
- š± **Responsive**: Works with any text content and container size
- āæ **Accessible**: ARIA attributes, keyboard navigation, and semantic HTML
- šØ **Customizable**: Flexible styling and configuration options
- š¦ **Lightweight**: No external dependencies, ~3KB minified
## Installation
### npm
```bash
npm install readmore-lines
```
### yarn
```bash
yarn add readmore-lines
```
### CDN
```html
<!-- Development version (unminified) -->
<script src="https://unpkg.com/readmore-lines@latest/dist/readmore.js"></script>
<!-- Production version (minified) -->
<script src="https://unpkg.com/readmore-lines@latest/dist/readmore.min.js"></script>
```
### UMD usage (script tag)
When using the UMD build via a script tag, the global is a callable function. Call it as `readmore(...)`:
```html
<div id="my-text">Long content here...</div>
<script src="./dist/readmore.js"></script>
<script>
readmore({ targetElement: document.getElementById('my-text'), linesLimit: 4 });
// Utilities are available on the same namespace:
// readmore.destroyReadMore(...)
</script>
```
## Quick Start
### Basic Usage
```javascript
import readmore from 'readmore-lines';
// Simple implementation
readmore({
targetElement: document.getElementById('my-text')
});
```
## API Reference
### `readmore(options)`
The main function that implements the read more/less functionality.
#### Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `targetElement` | `HTMLElement` | ā
| - | The DOM element to apply readmore functionality to |
| `readMoreLabel` | `string` | ā | `'Read more...'` | Text for the "read more" link |
| `readLessLabel` | `string` | ā | `'Read less'` | Text for the "read less" link |
| `targetClass` | `string` | ā | `'read-more-target'` | CSS class applied to the target element |
| `linkClass` | `string` | ā | `'read-more-link'` | CSS class applied to the toggle link |
| `linesLimit` | `number` | ā | `8` | Maximum number of lines before truncating |
#### Example
```javascript
readmore({
targetElement: document.getElementById('article-content'),
readMoreLabel: 'Continue reading...',
readLessLabel: 'Show less',
linesLimit: 5,
targetClass: 'article-truncate',
linkClass: 'read-more-button'
});
```
## Styling
### Default Styles
The library automatically adds CSS for text truncation:
```css
.read-more-target {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 8; /* or your specified linesLimit */
-webkit-box-orient: vertical;
}
```
### Custom Styling
You can customize the appearance by targeting the generated classes:
```css
.read-more-target {
/* Your custom truncation styles */
}
.read-more-link {
color: #007bff;
text-decoration: none;
font-weight: bold;
}
.read-more-link:hover {
text-decoration: underline;
}
```
## Accessibility Features
### ARIA Support
- **aria-expanded**: Automatically updates to reflect content state
- **aria-controls**: Links button to controlled content
- **role="button"**: Proper semantic role for screen readers
### Keyboard Navigation
- **Enter key**: Activates the toggle functionality
- **Space key**: Activates the toggle functionality
- **Tab navigation**: Button is focusable and follows tab order
### Semantic HTML
- Uses `<button>` element instead of `<a>` for better semantics
- Automatically assigns unique IDs for proper ARIA relationships
- Maintains focus management during interactions
## Browser Support
- Chrome 6+
- Firefox 3.6+
- Safari 5+
- Edge 12+
- IE 9+ (with polyfills for `WeakMap`)
## Build Outputs
The library provides multiple build formats for different use cases:
| File | Size | Description |
|------|------|-------------|
| `readmore.js` | ~11KB | Development version (unminified, with sourcemap) |
| `readmore.min.js` | ~2.5KB | Production version (minified, optimized) |
| `readmore.esm.js` | ~10KB | ES Module version |
### File Size Comparison
- **Unminified**: ~11KB (readable, with comments)
- **Minified**: ~2.5KB (77% size reduction)
- **Gzipped**: ~1.2KB (estimated)
## Performance
### Caching System
- **CSS Caching**: Prevents duplicate style additions
- **Line Height Caching**: Caches computed line heights per element
- **Memory Management**: Uses WeakMap for automatic garbage collection
### Optimization Features
- Efficient line height calculations
- Minimal DOM queries
- Automatic cache invalidation
## Examples
### Multiple Elements
```javascript
// Apply to multiple elements efficiently
document.querySelectorAll('.truncate').forEach(element => {
readmore({
targetElement: element,
linesLimit: 3
});
});
```
### Custom Styling
```html
<style>
.my-custom-truncate {
background: linear-gradient(to bottom, transparent 0%, white 100%);
}
.my-custom-link {
background: #007bff;
color: white;
padding: 5px 10px;
border-radius: 3px;
text-decoration: none;
}
</style>
<script>
readmore({
targetElement: document.getElementById('content'),
targetClass: 'my-custom-truncate',
linkClass: 'my-custom-link',
readMoreLabel: 'Read Full Article',
readLessLabel: 'Collapse'
});
</script>
```
### Cleanup and Instance Management
```javascript
import readmore, {
destroyReadMore,
hasReadMoreInstance,
getReadMoreInstance,
} from 'readmore-lines';
// Check if element has readmore functionality
if (hasReadMoreInstance(element)) {
console.log('Element has readmore functionality');
}
// Get the instance for advanced control
const instance = getReadMoreInstance(element);
if (instance) {
console.log('Instance configuration:', instance.config);
}
// Destroy readmore functionality and clean up resources
destroyReadMore(element);
// Clear all CSS cache (useful for complete reset)
clearReadMoreCache();
```
### Dynamic Content Management
```javascript
// Handle dynamic content updates
function updateContent(element, newContent) {
// Destroy existing readmore if present
if (hasReadMoreInstance(element)) {
destroyReadMore(element);
}
// Update content
element.innerHTML = newContent;
// Reapply readmore functionality
readmore({
targetElement: element,
linesLimit: 4
});
}
// Handle style changes that affect line height
function updateElementStyles(element) {
// Apply new styles
element.style.fontSize = '18px';
element.style.lineHeight = '1.5';
// Recalculate if readmore is active
if (hasReadMoreInstance(element)) {
const instance = getReadMoreInstance(element);
// Force recalculation by destroying and recreating
destroyReadMore(element);
readmore({
targetElement: element,
linesLimit: instance.config.linesLimit
});
}
}
```
## Development
### Building
```bash
# Install dependencies
npm install
# Build all versions (development + production)
npm run build
# Build development version only (unminified)
npm run build:dev
# Build production version only (minified)
npm run build:prod
# Run tests
npm test
# Lint code
npm run lint
```
### Project Structure
```
readmore-lines/
āāā src/
ā āāā readmore.js # Main library file
ā āāā readmore.d.ts # TypeScript declarations
āāā dist/ # Built files
ā āāā readmore.js # Development build (unminified)
ā āāā readmore.min.js # Production build (minified)
ā āāā readmore.esm.js # ES Module build
ā āāā *.map # Source maps
āāā tests/ # Test files
āāā package.json
āāā rollup.config.js
āāā README.md
```
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Changelog
### v1.0.0
- Initial release
- Core readmore functionality
- CSS and line height caching
- TypeScript support
- Comprehensive documentation
## Support
If you encounter any issues or have questions, please file an issue on [GitHub](https://github.com/konstantin-agafonov/readmore-lines/issues).
---
Made with ā¤ļø by [Konstantin Agafonov](https://github.com/konstantin-agafonov)