html
<ul class="wrap">
<li title="Lorem ipsum dolor sit amet"></li>
<li title="consectetur adipisicing elit"></li>
<li title="incididunt ut labore et dolore magna aliqua"></li>
<li title="Ut enim ad minim veniam"></li>
<li title="quis nostrud exercitation ullamco"></li>
<li title="laboris nisi ut aliquip ex ea commodo"></li>
<li title="Duis aute irure dolor in reprehenderit"></li>
<li title=" Excepteur sint occaecat cupidatat non"></li>
<div class="sub">
<div class="bg"></div>
</div>
</ul>
CSS
*{
padding: 0;
margin: 0;
border: none;
}
body{
padding: 100px;
}
ul{
list-style: none;
overflow: hidden;
position: relative;
}
li{
width: 220px;
height: 220px;
background: rgba(0, 0, 0, 0.6);
position: relative;
overflow: hidden;
cursor: pointer;
float: left;
margin-right: 20px;
margin-bottom: 20px;
display: block;
}
.sub{
width: 210px;
height: 210px;
background: #ff3030;
color: #fff;
padding: 5px;
position: absolute;
display: none;
}
JQUERY
var li = $('.wrap').children('li'),
sub = $('.sub');
li.on('mouseover', function() {
sub.show();
var left = $(this).offset().left,
top = $(this).offset().top,
text = $(this).attr('title'),
bg = $('.bg');
sub.stop().animate({
left: left - $('.wrap').offset().left,
top: top - $('.wrap').offset().top
});
bg.stop().animate({
opacity: 0
}, function() {
bg.text(text);
bg.animate({
opacity: 1
});
});
}).on('mouseleave', function() {
sub.fadeOut();
});
This is fiddle
http://jsfiddle.net/GTHM4/
And it better looks in full width
http://jsfiddle.net/GTHM4/embedded/result/
As you can see problem is in "broken" work 'mouseleave' event, and the div "bg" always 'wants' go away... What's wrong?
It works fine
var li = $('.wrap').children('li'),
sub = $('.sub'),
wrap = $('.wrap');
wrap.on('mouseover','li', function() {
sub.show();
var left = $(this).offset().left,
top = $(this).offset().top,
text = $(this).attr('title'),
bg = $('.bg');
sub.stop().animate({
left: left - $('.wrap').offset().left,
top: top - $('.wrap').offset().top
});
bg.stop().animate({
opacity: 0
}, function() {
bg.text(text);
bg.animate({
opacity: 1
});
});
}).on('mouseleave', function() {
sub.fadeOut();
});
demo http://jsfiddle.net/fazalrasel/GTHM4/1/
Related
Google uses a feedback feature that highlights the background color of content elements (ex:p, div, ul, h2, etc.) when the user mouses over a div to the right side of the content.
I believe the following CSS class is applied to the element to highlight its background:
.inline-feedback__highlight {
background: #d2e3fc;
-webkit-border-radius: .3125rem;
border-radius: .3125rem;
}
Using jQuery or JavaScript and CSS, I'd like to achieve the same result.
My Question
How can I identify what the closest element in <div id="content">...</div> is?
I was thinking some form of x,y coordinates and offset from the top of the content div.
My Code
$(function() {
let halfBtnHt = Math.ceil($('#track-button-div').height() / 2);
$('#track-container').on('mousemove', function(e) {
// console.log(e.offsetX, e.offsetY);
$('#track-button').css({
'transform': `translateX(0) translateY(${e.offsetY - halfBtnHt}px)`,
'visibility': 'visible',
})
}).on('mouseout', function(e) {
$('#track-button').css({
'visibility': 'hidden'
})
})
})
#content-container {
position: relative;
border: 1px solid black;
width: 500px;
height: auto;
margin: 100px auto;
}
#content {
padding: 2rem;
}
#track-container {
position: absolute;
text-align: center;
top: 0;
bottom: 0;
width: 64px;
right: -56px;
z-index: 1;
}
#track-button {
width: 42px;
height: 42px;
border-radius: 30px;
pointer-events: none !important;
}
#track-button-div {
visibility: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="content-container">
<div id="content">
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam, iusto? Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dolores earum esse eveniet libero minima pariatur repellat sed sunt ut?</div>
<pre class="prettyprint linenums prettyprinted">
<ol class="linenums">
<li class="L0">Hey</li>
</ol>
</pre>
<p>Blanditiis corporis ducimus laudantium nisi pariatur quasi repellat sunt, ut? Consequuntur dolores earum</p>
</div>
<div id="track-container">
<div id="track-button-div">
<button id="track-button" class="btn btn-outline-primary">
<i class="fas fa-quote-right"></i>
</button>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<script src="track.js"></script>
</body>
</html>
Here's what Google's Feedback Feature Looks Like
Look at snippet below:
(function ($) {
'use strict';
$(function () {
var
namespace = 'mmdm',
//-----
mainElementID = '#__elements_container',
highlightClass = 'founded-element__highlight',
//-----
mainElement = $(mainElementID),
movableElementContainer = $('#__movable_element_container'),
movableElement = $('#__movable_element');
// some utility
function getTouch(event) {
var touch = event;
if (('ontouchstart' in document.documentElement) || navigator.maxTouchPoints > 0) {
touch = event.originalEvent.touches && event.originalEvent.touches.length ? event.originalEvent.touches[0] : event;
if (event.type === 'touchstart' || event.type === 'touchmove') {
touch = event.targetTouches[0] || event.changedTouches[0];
}
}
return touch;
}
// define function(s)
function removeHighlightClass() {
mainElement.find('*').removeClass(highlightClass);
}
function findElementsWithSameYNHighlightIt(e) {
var x, y, meOffset, el;
meOffset = mainElement.offset();
x = (e.pageX - meOffset.left) / 2;
y = e.pageY - $(window).scrollTop();
el = document.elementFromPoint(x, y);
if (!$(el).is(mainElement) && $(el).closest(mainElementID).length) {
$(el).addClass(highlightClass);
}
}
function showMovableElement() {
movableElement.addClass('show');
}
function hideMovableElement() {
movableElement.removeClass('show');
}
function moveMovableElement(e) {
var y, mecTop = movableElementContainer.offset().top;
y = e.pageY;
// bound move to the main movable container
if (y >= mecTop && y <= (mecTop + movableElementContainer.outerHeight())) {
movableElement.css({
'top': y - mecTop - (movableElement.outerHeight() / 2)
});
}
removeHighlightClass();
}
// attach event(s)
movableElementContainer
.on('mousemove.' + namespace + ' touchmove.' + namespace + ' mouseenter.' + namespace + ' touchstart.' + namespace, function (e) {
if (!e.defaultPrevented && e.cancelable) {
e.preventDefault();
}
//-----
var touch = getTouch(e);
showMovableElement();
moveMovableElement(touch);
findElementsWithSameYNHighlightIt(touch);
}).on('mouseleave.' + namespace + ' touchend.' + namespace, function (e) {
if (!e.defaultPrevented && e.cancelable) {
e.preventDefault();
}
//-----
hideMovableElement();
removeHighlightClass();
});
});
})(jQuery);
* {
box-sizing: border-box;
}
#__elements_main_container {
display: flex;
}
#__elements_container {
width: 500px;
}
#__movable_element_container {
position: relative;
width: 40px;
}
#__movable_element_container::after {
content: '';
position: absolute;
top: 0;
left: 50%;
width: 1px;
height: 100%;
background-color: #ccc;
transform: translate(-50%);
z-index: 1;
}
#__movable_element {
position: absolute;
display: none;
align-items: center;
justify-content: center;
left: 50%;
width: 40px;
height: 40px;
text-align: center;
border-radius: 50rem;
border: 1px solid #ccc;
background-color: #fff;
box-shadow: 0 2px 5px rgba(0, 0, 0, .26);
transform: translate(-50%);
z-index: 2;
}
#__movable_element.show {
display: flex;
}
.founded-element__highlight {
background-color: #cecdff;
border-radius: 3px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="__elements_main_container">
<div id="__elements_container">
<h1>
A heading tag!
</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<ul>
<li>First list item</li>
<li>Second list item</li>
</ul>
</div>
<div id="__movable_element_container">
<i id="__movable_element" class="fa fa-quote-right"></i>
</div>
</div>
Please don't judge the code quality, I made it just for the sake of testing and making it do what you initially asked about selecting the closest element.
Check this sandbox with a working example
The key here is the usage of elementFromPoint function, the sandbox should just give a general idea and you can tailor it to your needs!
I am expecting result: as I've implemented this codes for hover popup in website, as website is dynamic in nature. When I see the result in mobile version, same code is not working.
As I've used js for this, let me know any other way to tackle this situation.
Expected output is in image below:
Here's why I've tried.
jQuery(function($) {
var pop = $('.map-popup');
pop.click(function(e) {
e.stopPropagation();
});
$('a.marker').mouseenter(function(e) {
e.preventDefault();
e.stopPropagation();
$(this).next('.map-popup').toggleClass('open');
$(this).parent().siblings().children('.map-popup').removeClass('open');
});
$(document).click(function() {
pop.removeClass('open');
});
pop.each(function() {
var w = $(window).outerWidth(),
edge = Math.round( ($(this).offset().left) + ($(this).outerWidth()) );
if( w < edge ) {
$(this).addClass('edge');
}
});
});
.markerstylea1{
overflow: auto;
height:170px;
width:350px; }
.map-popup {
position: absolute;
left: 58px;
width: auto;
transform: translateY(-50%);
padding: 5px 15px;
}
.map-popup:before {
content: "";
position: absolute;
top: 50%;
left: -16px;
margin-top: -16px;
width: 0;
height: 0;
border-style: solid;
border-width: 16px 16px 16px 0;
border-color: transparent #feb830 transparent transparent;
}
.map-popup .popup-title{
font-size: 20px!important;
}
.map-popup.edge {
left: auto;
right: calc(100% + 24px);
}
.map-popup.edge:before {
left: auto;
right: -16px;
border-width: 16px 0 16px 16px;
border-color: transparent transparent transparent #fff;
}
.marker::selection {
background: #feb82f;
color: #fff;
text-shadow: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a class="marker marker1 markerstyle1a" href="#marker1" >
<i class="fa fa-thumb-tack" aria-hidden="true"></i>
</a>
<aside id="marker1" class="map-popup markerstyle1" >
<h3 class="popup-title">xyz</h3>
<p><strong>xyz</strong><br>Lorem ipsum</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia pariatur laudantium deserunt minima delectus illum dolor, nesciunt sit iure, debitis eligendi blanditiis, tempore quidem cupiditate quaerat incidunt sapiente aliquam? Debitis!</p>\
<a class="btn" href="#">Find Out More</a>
</aside>
</div>
Unfortunately a mobile device has no 'hover' status as you can only click (touch). There is simply no mouse to trigger a hover state. Another way would be to have the trigger to open the modal on something else for mobile devices, such as a timed trigger or a button.
I am creating some cards with dynamic data using jquery. There is a description property that either fits on the card or not. When it does not fit, i would like to keep the card the same size as the others but add a "show more/less" button that would expand the card to show the rest of the description.
I have created a fiddle showing the card creation as well as what i have tried so far.
At this point i have a function checkTruncation that will check if the text would fit in its container or not. The issue seems to rely on the fact that the elements are not yet rendered so their width is 0 which makes the function return always true.
The function is as this:
let checkTruncation = function (jqueryElement) {
var $element = jqueryElement;
if ($element) {
var $c = $element
.clone()
.css({ display: 'inline', width: 'auto', visibility: 'hidden' })
.appendTo('body');
let truncated = $c.width() > $element.width()
console.log($c.width(), $element.width(), $c.width() > $element.width())
$c.remove();
return truncated;
}
return false;
}
Also, instead of me reinventing the wheel, is there any suggested library that could achieve this functionality? I know i have seen such behavior, but cannot remember where.
UPDATE
In the fiddle above, i am just calling the getCard function, which is responsible to provide the template for the card, twice just to show some sample. In the real life situation i am getting data through ajax and populating the cards using the following when a user clicks on a button:
$('.fetchButton').on('click', function(){
$.get(url, filter)
.done(function (data) {
jQuery.each(data, function (index, item) {
$('.container').append(getCard(item));
})
}
})
UPDATE 2
With the help of #LGSon i have come to this scenario which is mostly using CSS to achieve what i need. Still the answer given is valid and did solve my issue so i will keep it as an answer.
In addition to given answer, which explained why the original code didn't work, here is a different approach, showing how one can use CSS to show/hide a "Read more..." button
With absolute: position and overflow: hidden we can hide a "button" at the bottom of a "text" element, and when that element reach the "wrapper's" height, the hidden "button" becomes visible.
I also made use of a pseudo element and data-* attribute to keep "button text" in the markup, and the CSS attr() to toggle it when showing/hiding the text.
Stack snippet
document.querySelectorAll('.readmore').forEach( function(link) {
link.addEventListener('click', function() {
this.closest('.wrapper').classList.toggle('show');
});
});
.wrapper {
height: 70px;
border: 1px solid gray;
overflow: hidden;
}
.wrapper.show {
height: auto;
}
.text {
position: relative;
overflow: hidden;
}
.readmore {
position: absolute;
width: 100%;
top: 52px;
left: 0;
background: white;
color: red;
cursor: pointer;
}
.readmore::before {
content: attr(data-more)
}
.wrapper.show .readmore {
position: relative;
top: auto;
display: block;
}
.wrapper.show .readmore::before {
content: attr(data-less)
}
<div class="wrapper">
<div class="text">
Some smaller dummy text here
<span class="readmore" data-more="Show more..." data-less="Show less..."></span>
</div>
</div>
<div class="wrapper">
<div class="text">
Some bigger dummy text here <br>
Some bigger dummy text here <br>
Some bigger dummy text here <br>
Some bigger dummy text here <br>
Some bigger dummy text here <br>
<span class="readmore" data-more="Show more..." data-less="Show less..."></span>
</div>
</div>
If possible, the "Show more/less..." text can of course be set in the CSS, to simplify maintenance and have it in one place.
document.querySelectorAll('.readmore').forEach( function(link) {
link.addEventListener('click', function() {
this.closest('.wrapper').classList.toggle('show');
});
});
.wrapper {
height: 70px;
border: 1px solid gray;
overflow: hidden;
}
.wrapper.show {
height: auto;
}
.text {
position: relative;
overflow: hidden;
}
.readmore {
position: absolute;
width: 100%;
top: 52px;
left: 0;
background: white;
color: red;
cursor: pointer;
}
.readmore::before {
content: 'Show more...'
}
.wrapper.show .readmore {
position: relative;
top: auto;
display: block;
}
.wrapper.show .readmore::before {
content: 'Show less...'
}
<div class="wrapper">
<div class="text">
Some smaller dummy text here
<span class="readmore"></span>
</div>
</div>
<div class="wrapper">
<div class="text">
Some bigger dummy text here <br>
Some bigger dummy text here <br>
Some bigger dummy text here <br>
Some bigger dummy text here <br>
Some bigger dummy text here <br>
<span class="readmore"></span>
</div>
</div>
Updated based on a comment
Here is an updated Stack snippet version of your Fiddle/Codepen sample's
let getCard = function(options) {
let item = options.data;
let $parent = options.parent;
let outerDiv = $('<div>').addClass('shops-content-right');
let boxDiv = $('<div>').addClass('boxes-right row');
let shopDiv = $('<div>').addClass('one-shop-box col-md-6 offset-md-3');
let cubeDiv = $('<div>').addClass('cube text-center');
let wrapperDiv = $('<div>').addClass('wrapper');
let textDiv = $('<div>').addClass('text');
let descriptionP = $('<p>').addClass('text-disc').text(item.description);
let loadMoreP = $('<span>More >').addClass('readmore');
textDiv.append([descriptionP, loadMoreP]);
wrapperDiv.append(textDiv);
cubeDiv
.append(wrapperDiv);
shopDiv.append(cubeDiv);
boxDiv.append(shopDiv);
outerDiv.append(boxDiv);
$parent.append(outerDiv);
loadMoreP.on('click', function() {
if (wrapperDiv.hasClass('collapsed')) {
wrapperDiv.removeClass('collapsed');
loadMoreP.text("More >");
} else {
wrapperDiv.addClass('collapsed');
loadMoreP.text("Less <");
}
})
return outerDiv;
}
$('.fetchButton').on('click', function() {
getCard({
data: {
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
},
parent: $('.container'),
lines: 3
})
getCard({
data: {
description: 'Lorem ipsum dolor sit amet, consectetur'
},
parent: $('.container'),
lines: 3
})
})
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
.one-shop-box {
border: 1px solid;
}
.shops-content-right .one-shop-box .cube p.text-disc {
font-size: 16px;
/*height: 50px;*/
overflow: hidden;
}
.wrapper {
height: 90px;
overflow: hidden;
}
.wrapper.collapsed {
height: auto;
}
.text {
position: relative;
overflow: hidden;
}
.readmore {
position: absolute;
width: 100%;
top: 72px;
left: 0;
background: white;
color: red;
}
.wrapper.collapsed .readmore {
position: relative;
top: auto;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--
Bootstrap docs: https://getbootstrap.com/docs
-->
<div class="container">
<button class="fetchButton">
Fetch Data
</button>
</div>
This happens beacuse you doesn't append your element to document, so its width is 0. So, update your code as the following:
let checkTruncation = function($element) {
if ($element) {
var $c = $element
.clone()
.css({ display: 'inline', width: 'auto', visibility: 'hidden' })
.appendTo('body');
let truncated = $c.width() > $element.width();
// console.log($c.width(), $element.width(), $c.width() > $element.width());
$c.remove();
return truncated;
}
return false;
};
let baseUrl ='';
let getCard = function(item, $parent) {
let outerDiv = $('<div>').addClass('shops-content-right');
let boxDiv = $('<div>').addClass('boxes-right row');
let shopDiv = $('<div>').addClass('one-shop-box col-md-6 offset-md-3');
let cubeDiv = $('<div>').addClass('cube text-center');
let descriptionP = $('<p>').addClass('text-disc').text(item.description).addClass('collapsed');
let loadMoreP = $('<p>').css({ 'font-size': '16px', 'cursor': 'pointer' }).text("More >");
cubeDiv.append(descriptionP).append(loadMoreP);
shopDiv.append(cubeDiv);
boxDiv.append(shopDiv);
outerDiv.append(boxDiv);
$parent.append(outerDiv);
loadMoreP.on('click', function () {
if (descriptionP.hasClass('collapsed')) {
descriptionP.removeClass('collapsed');
loadMoreP.text("Less <");
} else {
descriptionP.addClass('collapsed');
loadMoreP.text("More >");
}
});
if (checkTruncation(descriptionP)) {
loadMoreP.show();
} else {
loadMoreP.hide();
}
};
const $container = $('.container');
getCard({
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
}, $container);
getCard({
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
}, $container);
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
.one-shop-box {
border:1px solid;
}
.shops-content-right .one-shop-box .cube p.text-disc {
font-size: 16px;
height: 50px;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="container"></div>
I pass to the function getCard() the container element, and it append the new element to it before it calls to the function checkTruncation().
And update your code that calls getCard() as follows:
const $container = $('.container');
$('.fetchButton').on('click', function() {
$.get(url, filter).done(function(data) {
$.each(data, function(index, item) {
getCard(item, $container);
});
});
});
I am trying to make this code I made into a library:
$.fn.boxify = function() {
var imageSliding = $('.box > .img');
$(this).click(function() {
$('.backdrop, .box').animate({
'opacity': '.50'
}, 300, 'linear');
$('.box').animate({
'opacity': '1.00'
}, 300, 'linear');
$('.backdrop, .box').css('display', 'block');
});
$('.close').click(function() {
close_box();
});
$('.backdrop').click(function() {
close_box();
});
function close_box() {
$('.backdrop, .box').animate({
'opacity': '0'
}, 300, 'linear', function() {
$('.backdrop, .box').css('display', 'none');
});
}
/* Slider */
var speed = 100;
$(".prev").click(function() {
var gallery = $(this).closest('.box').find("ul.gallery"),
now = gallery.children(":visible"),
last = gallery.children(":last"),
prev = now.prev();
prev = prev.index() == -1 ? last : prev;
now.fadeOut(speed, function() {
prev.fadeIn(speed);
});
});
$(".next").click(function() {
var gallery = $(this).closest('.box').find("ul.gallery"),
now = gallery.children(":visible"),
first = gallery.children(":first"),
next = now.next();
next = next.index() == -1 ? first : next;
now.fadeOut(speed, function() {
next.fadeIn(speed);
});
});
$(".gallery li").click(function() {
var first = $(this).parent().children(':first'),
next = $(this).next();
next = next.index() == -1 ? first : next;
$(this).fadeOut(speed, function() {
next.fadeIn(speed);
});
});
};
$( "a" ).boxify(); // Makes all the links green.
body {
font-family: Helvetica, Arial;
}
.backdrop {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: #000;
opacity: .0;
filter: alpha(opacity=0);
z-index: 50;
display: none;
}
.box {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
left: 50%;
background: black;
text-align: left;
z-index: 51;
padding: 0;
margin: 0;
display: none;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-moz-box-shadow: 0px 0px 5px #444444;
-webkit-box-shadow: 0px 0px 5px #444444;
box-shadow: 0px 0px 5px #444444;
border: 10px solid #000;
color: white;
width: 40%;
}
#media (min-width: 320px) and (max-width: 900px) {
.box {
width: 98%;
}
}
#media (min-width: 901px) and (max-width: 1200px) {
.box {
width: 60%;
}
}
#media (min-width: 1201px) {
.box {
width: 48%;
}
}
.box img {
width: 100%;
}
.caption {
padding-top: 10px;
font-size: 15px;
}
.prev,
.next {
position: relative;
padding: 3px;
cursor: pointer;
float: right;
border: 1px solid black;
}
.prev:active,
.next:active {
background-color: white;
color: black;
}
.gallery li {
display: none;
list-style: none;
margin-left: -40px;
}
.gallery li:first-child {
display: block;
}
.gallery img {
max-height: 550px;
}
.slideButtons {
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<h1>Welcome Within</h1>
Open Lightbox
<div class="backdrop"></div>
<div class="box">
<ul class="gallery" id="olympGallery">
<li><img src="http://urbanphenomena.net/imgs/trabzoni/trabzoni1.png" alt="" title="" /></li>
<li><img src="http://urbanphenomena.net/imgs/trabzoni/trabzoni2.png" alt="" title="" /></li>
<li><img src="http://urbanphenomena.net/imgs/trabzoni/trabzoni3.png" alt="" /></li>
</ul>
<div class="slideButtons">
<span class="next">Next</span>
<span class="prev">Previous</span>
</div>
<div class="caption">
<p>This thing is called 'Caption'. Let me tell you:</p>
<hr />
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
You see that .box class? As a user I wanna infinitely add more box containing different images and captions!
When I added another <a> which is the Lightbox link to the box, the both boxes display on the same time. I know that the same code is reused this way, but that's what I'm trying to do:
Somehow keep the same code without adding more and more code. Yet, when I add more boxes they are completely different from the others (different images)
You can modify your .click function to use this one:
$(this).click(function(event) {
var lightBoxes = $('a.lightbox'); //Retrieves all a.lightboxes of the page
for (var i = 0; i < lightBoxes.length; i++) {
if (lightBoxes[i] == event.target) { //Checks the clicked element position in the array
//Displays the common .backdrop div
$('.backdrop').animate({
'opacity': '.50'
}, 300, 'linear').css('display', 'block');
//Displays the 'i' .box div
$('.box').eq(i).animate({
'opacity': '1.00'
}, 300, 'linear').css('display', 'block');
break;
}
}
});
This code will check all the 'a' elements with the .lightbox class and will check which one was clicked. Knowing the index (i) of the 'a' element clicked, then the 'i' .box element will display.
Note that the .backdrop element should be unique in the HTML and don't need to be repeated. In the HTML you just need to add a new a href element and a new div .box for each a.
Open Lightbox 2
<div class="box">
<ul class="gallery" id="olympGallery">
<li><img src="http://urbanphenomena.net/imgs/trabzoni/trabzoni1.png" alt="" title="" /></li>
<li><img src="http://urbanphenomena.net/imgs/trabzoni/trabzoni2.png" alt="" title="" /></li>
<li><img src="http://urbanphenomena.net/imgs/trabzoni/trabzoni3.png" alt="" /></li>
</ul>
<div class="slideButtons">
<span class="next">Next</span>
<span class="prev">Previous</span>
</div>
<div class="caption">
<p>This thing is called 'Caption'. Let me tell you:</p>
<hr />
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
Hope this is what you need!
I'm creating a testimonials page for my site, and some of the testimonials I have are rather long. As such I want to cut out anything longer than 3 lines.
To read the rest, the user clicks a button and the text expands to reveal the rest.
I've managed to do the above with line-clamp, however I'd like to have the ... clickable and styled with a different text. Is this possible?
I couldn't find a way to do that, so I tried a workaround. First I find out which elements have overflow so the [Read More] can be inserted. However it gets inserted at the end of the text, and not before the overflow.
I'm clueless as to how to solve this.
Desired result:
Current result (jsfiddle)
HTML
<div class="testimonial container-fluid">
<div class="col-xs-3 rating-container">
<div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
<div class="star"></div>
</div>
</div>
<div class="col-xs-9">
<div class="title">Title</div>
<div class="content">Lorem ipsum dolor sit amet, vero essent gubergren ad pro, regione epicuri contentiones ea mea. Decore omnium id vim, pro et malis molestie, et porro nostro vis. Ei libris debitis reprehendunt est. Te per delenit scaevola scripserit. Partem erroribus rationibus ea vel, nihil euismod ei vim.
His sonet antiopam cotidieque ea, eu unum melius conclusionemque his. Ferri iisque sanctus pri ei. Ut ius tantas nonumy intellegam. Et per solum aliquam, melius elaboraret at qui.</div>
<div class="name_loc" id="demo">Name, London</div>
</div>
</div>
CSS
.testimonial {
width: 920px;
display: -webkit-box;
background-color: #EFEFEF;
color: #333;
padding: 8px;
margin: 0 0 20px;
border: 3px solid #506790;
}
.testimonial:nth-of-type(even) {
background-color: #EFEFEF;
}
.testimonial .rating-container {
height: 144px;
display: table;
}
.testimonial .rating-container > div {
display: table-cell;
vertical-align: middle;
}
.testimonial .star {
width: 32px;
height: 32px;
display: inline-block;
background-repeat: no-repeat;
background-image: url('http://www.timelinecoverbanner.com/cliparts/wp-content/digital-scrapbooking/lemon-star-md1.png');
background-size: cover;
}
.testimonial .title {
font-size: 18pt;
text-align: left;
font-weight: bold;
}
.testimonial .content {
-webkit-box-orient: vertical;
display: -webkit-box;
margin: 5px 0 10px;
font-size: 12pt;
text-align: left;
overflow: hidden;
height: 68px;
}
.testimonial .name_loc {
font-style: italic;
font-size: 12pt;
text-align: right;
}
JS
$('#demo').on('click', function() {
var t = $(this).closest('.testimonial');
var c = t.find('.content');
var h3 = c[0].scrollHeight;
c.animate({'height':h3},500);
});
$('.testimonial').each(function() {
var c = $(this).find('.content');
if (c.height() < c[0].scrollHeight) {
c.css('text-overflow', 'ellipsis');
//also tried:
c.css('line-clamp', '3');
}
});
You could do this with the ::after pseudo-element. I was playing with your fiddle and it seemed to work.
First the .content class needs to be positioned relative. Then add two new CSS classes:
.testimonial .content.collapsed {
/* styles removed from .content */
overflow: hidden;
height: 68px;
}
.testimonial .content.collapsed::after {
display: inline-block;
content: "...";
position: absolute;
bottom: 0;
right: 5px;
}
You could add the click handler to the pseudo element in the JS (I didn't try this part), and then remove the "collapsed" class after the click. You could also style the pseudo element any way you want, or change the content to "Read more..." or whatever.
Try fiddling with your revised JsFiddle. It uses:
$('.testimonial').on(
'click',
'.content',
function(e) {
if (this.scrollHeight > this.offsetHeight) {
$(this).removeClass('clipped')
.addClass('unclipped')
.css('height', this.scrollHeight+'px');
} else {
$(this).removeClass('unclipped')
.addClass('clipped')
.css('height', '');
}
}
);
and 2 extra css-classes: clipped and unclipped:
.clipped:after {
position: absolute;
content: '>';
top: 2.9em;
color: red;
font-weight: bold;
cursor: pointer;
}
.unclipped:after {
position: absolute;
content: '<';
top: 2.9em;
color: green;
font-weight: bold;
cursor: pointer;
}
What about this: http://jsfiddle.net/6nb0wwc3/1/
I added a "readme" div, which on click, shows the complete text.
<div class="name_loc" id="demo">Name, London</div>
<div class="readmore">Read more</div>
$('.readmore').each(function() {
$(this).click( function() {
$(this).parent().find('.content').css('height','100%');
$(this).hide();
});
});
Hope it helps