Load More v1.0.0
Allow user to reveal additional content by pressing a button to load more items dynamically.
Default Setup Anchor (Default Setup)
Experimental: Experimental examples or components may require additional work, further testing, and may not be fully supported or accessible. They should be carefully evaluated before being used in a production environment.
<div class="load-more">
<div class="load-more__msg" aria-live="polite"></div>
<ul class="load-more__container" role="list">
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 1</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 2</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 3</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 4</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 5</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 6</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 7</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 8</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 9</span>
</a>
</li>
<li class="load-more__item">
<a href="#!">
<img src="https://radancy.dev/placeholder.png" alt="">
<span>Item 10</span>
</a>
</li>
</ul>
</div>/*!
Radancy Component Library: Load More
Contributor(s):
Michael "Spell" Spellacy
Dependencies: Sass
*/
$base-color: #6F00EF;
.load-more {
// Assistive Tech Message - Do not remove!
&__msg {
clip-path: inset(100%);
clip: rect(0 0 0 0);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
&__container {
list-style: none;
margin: 0;
padding: 0;
@media(min-width: 48.625em) {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
}
&__item {
margin-bottom: 1em;
@media(min-width: 48.625em) {
width: 33.3%;
}
a {
display: block;
margin: .5em;
padding: .5em;
}
img {
display: block;
width: 100%;
}
}
&__btn {
background-color: $base-color;
border: 0;
color: #fff;
display: block;
line-height: normal;
margin: 0 auto;
max-width: calc(200rem / 16);
padding: 1.5em;
text-align: center;
text-transform: uppercase;
&[disabled] {
opacity: .5;
}
}
}/*!
Radancy Component Library: Load More
Contributor(s):
Michael "Spell" Spellacy
Dependencies: jQuery
*/
(function() {
// Display which component in use via console:
console.log("%cLoad More%cv1.0.0", "background: #2d2d2d; color: #fff; padding: 6px 10px; border-radius: 16px 0 0 16px; font-weight: 600;" , "background: #6e00ee; color: #fff; padding: 6px 10px; border-radius: 0 16px 16px 0; font-weight: 600;");
var $loadMore = $(".load-more");
var $loadMoreItem = $(".load-more__item");
var $loadMoreMsg = $(".load-more__msg");
var loadMoreBtnTxt = "Load More";
var loadMoreBtnFin = "All Done!";
var loadMoreNewItemTxt = " new items have been loaded.";
var loadMoreNewItemSingleTxt = " new item has been loaded.";
var loadMoreComplete = "All content has been loaded.";
var loadMoreDelay = 500;
var loadMoreDefault = 3;
// Hide all items after nth item
$loadMore.each(function(e) {
if ($(this).data("load-more-show")) {
var loadMoreShow = $(this).data("load-more-show");
} else {
var loadMoreShow = loadMoreDefault;
}
$(this).find($loadMoreItem).slice(loadMoreShow).prop("hidden", "true");
});
// Add Button
$loadMore.append("<button class='load-more__btn'>" + loadMoreBtnTxt + "</button>");
// Apply button class to variable
var $loadMoreBtn = $(".load-more__btn");
// Button Action: Message
$($loadMoreBtn).on("itemsDisplayed", function(e, totalCount){
var $loadMoreItemsHidden = $(this).parent().find(".load-more__item[hidden]");
if(!$loadMoreItemsHidden.length) {
// Change button text when done
$(this).prop("disabled", "true").text(loadMoreBtnFin);
if (totalCount === 1) {
$(this).parent().find($loadMoreMsg).html(totalCount + loadMoreNewItemSingleTxt + " " + loadMoreComplete);
} else {
$(this).parent().find($loadMoreMsg).html(totalCount + loadMoreNewItemTxt + " " + loadMoreComplete);
}
}
});
$loadMoreBtn.on("click", function() {
// Get Hidden Item(s)
var $loadMoreItemsHidden = $(this).parent().find(".load-more__item[hidden]");
// Remove hidden attr on every group of nth item(s)
if ($(this).parent().data("load-more-show")) {
var itemsToLoad = $(this).parent().data("load-more-show");
} else {
var itemsToLoad = loadMoreDefault;
}
var itemsToRemove = $loadMoreItemsHidden.slice(0, itemsToLoad);
itemsToRemove.slice(0, itemsToLoad).removeAttr("hidden");
var totalItems = itemsToRemove.length;
var loadMoreTxt = totalItems + loadMoreNewItemTxt;
$(this).parent().find($loadMoreMsg).html(loadMoreTxt);
// In not knowing what kind of content may exist in item, we are applying temporary focus to item itself.
// Question: Is it better to apply focus here or keep focus on the 'Load More' button itself, allowing
// keyboard user to navigate through newly revealed items?
// Also, is it better to put focus on item or first focusable element within item?
// TODO: More research will be required.
// $loadMoreItemsHidden.first().attr("tabindex", "-1").focus();
var $focusElms = "a, audio, button, input, select, video";
$loadMoreItemsHidden.find($focusElms).first().focus();
$(this).trigger("itemsDisplayed", [totalItems]);
// Remove message
// Note: Message needs to be removed so we can add it again
// when loading next selection of items.
setTimeout(function(){
$loadMoreMsg.empty();
}, loadMoreDelay);
});
})();Properties Anchor (Properties)
Use the following properties to configure this component.
| Attribute | Applies To | Note | Description |
|---|---|---|---|
data-load-more-max |
.load-more |
Number, Optional | Used to set the maximum number of items first shown on page load and items shown when the "Load More" button is pressed. The default is 3. |
| Class | Applies To | Note | Description |
|---|---|---|---|
.load-more |
div, section |
Mandatory | Used on the parent element that wraps your list. |
.load-more__btn |
button |
Component | Used on the button that loads more content. |
.load-more__container |
ul, ol |
Mandatory | Used on the list element that wraps your list items. |
.load-more__item |
li |
Mandatory | Used on the list items that wrap your content. |
.load-more__msg |
div |
Mandatory | Used to alert assistive technology users that a change has occured on the page after clicking .load-more__btn. |
Report Issues
Find a bug? Want a new feature? Report it on JIRA. You're so awesome!