I'm working on a website that needs to have a variable grid. It's based on Tumblr so unfortunately we can't use any PHP to solve our problem. We want to make some posts wider than other, but this should be done randomly and photo posts should be excluded from this.
The current markup for each of the text blocks is:
<article class="post text cf post-3">
<a href="#">
<div class="post-overview-header" style="background-image: url(https://31.media.tumblr.com/d4134dd4d2c48674e311ca0bb411d5cc/tumblr_inline_n3v11hGjI61s3vyc9.jpg); background-size: cover; background-position: 50% 0%; background-repeat: no-repeat no-repeat;">
<div class="hoverOverlay"></div>
<div class="post-overview-title">
<span class="post-title">posts adden</span>
<span class="post-date">
April 11, 2014
</span>
<span class="post-readingtime"><span aria-hidden="true" class="icon-readingtimesmall"></span><span class="eta">3 min</span></span>
</div>
</div>
<div class="post-content">
<p>this is the post's content</p>
</div>
</a>
</article>
My best shot at this grid is the following code but I wasn't able to check whether the wide post on the previous row is on the same level because that looks odd but I do want to do that.
var i = 0;
$('.post').each(function() {
// determine whether the count has to be reseted or not
if(i === 3){
i = 1;
}else{
i++;
}
$(this).addClass('post-' + i); // add one so the each post is properly named for this grid to work
if($(this).is(':first-of-type') || $(this).hasClass('text')){
$(this).not('.post-3').addClass('wide');
}
// in case the first of 2 posts is a wide one
if($(this).is('.wide.post-1')){
i = 2;
}
});
Desired effect: http://c.davey.im/Uzq9
Current effect http://c.davey.im/Uzsv
thanks in advance!
Thought I'd have a play and have come up with this: http://jsfiddle.net/andyface/7KCGJ/
Think it does the job you're after.
var i = 0,
prevRowWide = 0;
$('.post').each(function () {
//GENERATE POST POSITIONING INDEX
i === 3 ? i = 1 : i++;
// RANDOMLY GENERATE VALUE TO SAY IF POST SHOULD BE WIDE OR NOT
// CACHE CURRENT OBJECT, AIDDS PERFORMANCE
var addWide = Boolean(Math.round(Math.random())),
$elem = $(this);
$elem.addClass('post-' + i);
// MAKE SURE IT'S NOT A PHOTO
if( ! $elem.hasClass('photo')) {
// IF IT'S CHOSEN TO BE WIDE, THE PREVIOUS ROW DOESN'T HAVE A WIDE AT
// THAT POSITION AND IT'S IN POSITION 3 THEN ADD .wide AND UPDATE VARS
if(addWide && prevRowWide != i && i != 3) {
$elem.addClass('wide');
// STORES THE POSITION OF THE PREVIOUS ROWS WIDE SO YOU DON'T GET CLASHES
prevRowWide = i;
i++;
}
else if (i == prevRowWide) {
// IF WE'VE GOT BACK ROUND TO THE SAME ROW NUMBER AND IT'S NOT JUST
// BEEN SET ABOVE THEN WE CAN GET RID OF IT AS IT'S DONE IT'S JOB AND
// WE DON'T WANT IT AFFECTING THE NEXT ROW AS WELL
prevRowWide = 0;
}
}
});
Related
I'm creating a form where you can choose between different sizes of paper, everything working well and I've made a search form in jQuery that looks in the text() of a div to find matching formats. In example: there's a size 105 x 148 and if I type "105" in #searchformat it hide()s all other divs without "105".
$('#searchformat').keyup(function() {
$('.awspc-image-selection-box').hide();
$('.awspc-image-selection-box-content .awspc-image-selection-box-content-label').each(function() {
if($(this).text().toLowerCase().replace(/\s/g, '').indexOf(""+text+"") != -1 ) {
$(this).closest('.awspc-image-selection-box').show();
}
});
});
This works great. There's just one thing I can't seem to get working, I want to have the ability if you type in the input field for example "104" that it will also show the divs with "105" in it. With a margin of +- 5.
The field where I need to search in is $('.awspc-image-selection-box-content-label').text() and I already tried it with a function having return Math.round(x.match(/\d+/) / text) * text; but this looks for the nearest number and the problem here also is that the value of the field is like this: <div class="awspc-image-selection-box-content-label"> 38.1 x 8 mm </div>
HTML:
<div class="awspc-image-selection-box" data-value="7" data-id="aws_price_calc_45" data-substrate="">
<div class="awspc-image-selection-box-content">
<img style="width: ; height: " src="/uploads/woocommerce-placeholder-768x768.png" alt="170">
<div class="awspc-image-selection-box-content-label">38.1 x 8 mm</div>
</div>
</div>
So how can I in example search for "39" and it will show me the div having "38"?
Thanks a lot!
UPDATE
I figured some working code out but the only problem now is how I can retrieve what the closest() div is from the result...
var tooSearchFor = $('.awspc-image-selection-box-content-label').text();
tooSearchFor = tooSearchFor.split('\n');
for(var i = 0; i < tooSearchFor.length; i++)
tooSearchFor[i] = parseInt(tooSearchFor[i]) || 0;
var goalFormat = textInputSearch;
var closestFormat = null;
$.each(tooSearchFor, function(){
if (closestFormat == null || Math.abs(this - goalFormat) < Math.abs(closestFormat - goalFormat)) {
closestFormat = this;
}
});
console.log ('Closest format:' + closestFormat); // outputs the closest found number
How can I retrieve the div where closestFormat is found in the array...?
Here is the idea behind the code: The article has an avatar object in the beginning. e.g.:
<div class="column-right">
<div class="inner">
<h3>Header of article</h3>
<div id="avatar">
<img>
<div>avatar title</div>
</div>
<p>long text</p>
</div>
</div>
When a user scrolls down, the avatar obviously disappears. So I wanted to make a clone of said avatar and put it in the left column using position fixed.
Here is the JavaScript code:
document.body.onscroll = function(e) {
var scrolled = document.documentElement.scrollTop;
var newAv;
if ( (scrolled > avatarCoords.bottom) && !newAv ) {
//check if user scrolled below the avatar. if clone of avatar exists, do anything:
newAv = avatar.cloneNode(true);
//clone actual element, whick user can't see right now
newAv.style.position = "fixed";
newAv.style.left = 2 + "px";
newAv.style.top = 10 + "px";
document.body.appendChild(newAv); //add clone in document
}
if( (scrolled < avatarCoords.bottom) && newAv ) {
newAv.parentNode.removeChild(newAv);
}
}
function getCoords(element) {
var box = element.getBoundingClientRect();
return {
bottom: box.top + avatar.offsetHeight
}
}
I don't understand why the first condition keeps responding even though the variable newAv is assigned. !newAv is supposed to be false after first cloning.
If you can answer the first question, tell me why newAv can't be removed as well.
Thank you!
You keep redefining newAV inside the onscroll function.
Make this a global variable (so this remembers the value from previous call):
var newAv;
document.body.onscroll = function(e) {
var scrolled = document.documentElement.scrollTop; // etc
I apologise in advance, I'm not allowed to post images until I have 10 reputation. So, I hope that my description would be enough to get across the idea I have.
So, say I have three columns; a, b, and c. And when there's too much content to be hosted in just a, b, and c, I'd want new off-screen columns to be made, d, e, and f. - This goes on until all the content is used.
So, my current setup has the "hidden-text" div play host to all the content, and then I'd have a JavaScript function, or jQuery function to dynamically populate each of the divs, and create divs where needed along with buttons to then get to the new divs it creates.
The way it determines which to populate is simply grabbing the content and putting it into column a. Column a is full when the content reaches the bottom of the screen. Then it grabs the rest of the content and puts it in b, until b is full and so on until all the content available is used.
I really hope I'm being clear enough, I have no idea if anyone is going to even remotely understand what I'm trying to say... Any help at all is much appreciated!
Here's a code snippet of how the HTML is structured, maybe it'll help someone understand what I mean... Thanks again, everyone!
<div id="parent-div">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>
<div id="hidden-text">
This is the content I would like to have displayed across the three divs above.
</div>
Here is some JS that I have so far and I'm rather stuck on where to go from here:
function Populate(){
//paragraph is equal to all of the content in the hidden-text div
var paragraph = document.getElementById('hidden-text').innerHTML;
var newParagraph = "";
//the variable div would play host to the names of each of the divs in the HTML
var div = "";
//words stores each character of paragraph and passes them into the new paragraph
var words = "";
for (words in paragraph)
{
newParagraph += paragraph[words];
}
//the column with the name equal to the value of the div variable gets populated by the value of newParagraph
document.getElementByClassName(div).innerHTML = newParagraph;}
I think it should be something like this:
var divs = ['a', 'b', 'c'];
var word_limit = 50;
var paragraph_words = paragraph.split(' ');
for (var i = 0, div_index = 0; i < paragraph_words.length && div_index < divs.length; i++) {
newParagraph += ' ' + paragraph_words[i];
if (i > 0 && i % word_limit == 0) {
document.getElementsByClassName(divs[div_index])[0].innerHTML = newParagraph;
div_index++;
newParagraph = '';
}
}
if (newParagraph) { // If we didn't fill up the last DIV
document.getElementsByClassName(divs[div_index])[0].innerHTML = newParagraph;
}
I found a simple tab-menu jQuery plugin that needs some adapting for a project of mine. The tabs in question - being absolutely positioned - are taken out of the flow and as such don’t contribute to the wrapping div’s height, so the background behind them don’t show.
I am trying to force the height of the wrapping div (containing the background image) to match the height of the selected tab (+400px for nav and header) and to achieve that on the fly I am adapting the original jQuery file.
Here is the code (with the few extra lines (commented ‘added!’) of mine).
var cbpHorizontalMenu = (function () {
var $listItems = $('#cbp-hrmenu > ul > li'),
$menuItems = $listItems.children('a'),
$body = $('body'),
current = -1;
function init() {
$menuItems.on('click', open);
$listItems.on('click', function (event) {
event.stopPropagation();
});
}
function open(event) {
if (current !== -1) {
$listItems.eq(current).removeClass('cbp-hropen');
}
var $item = $(event.currentTarget).parent('li'),
idx = $item.index();
if (current === idx) {
$item.removeClass('cbp-hropen');
//added!
current = -1;
} else {
$item.addClass('cbp-hropen');
current = idx;
$body.off('click').on('click', close);
var content2Height = jQuery(".cbp-hrsub").height() + 400;
jQuery('#content2').height(content2Height); //added
}
return false;
}
function close(event) {
$listItems.eq(current).removeClass('cbp-hropen');
//added!
current = -1;
}
return {
init: init
};
})();
It does something, but not what I need. It gets the height of the first div.cbp-hrsub and applies it (+400px) to the div.content2. What I need is to target the current tab (a child of event.currentTarget, me thinks?), to calculate its height and to apply it to the content2 div.
This is a simplified HTML if that helps:
<div class="content2">
<nav id="cbp-hrmenu" class="cbp-hrmenu">
<ul>
<li>
tab 1
<div class="cbp-hrsub">
<div class="cbp-hrsub-inner">
I am 1st tab, 100px height.
</div>
</div>
</li>
<li>
tab 2
<div class="cbp-hrsub">
<div class="cbp-hrsub-inner">
I am 2nd tab, 200px height.
</div>
</div>
</li>
<li>
Nigel's CV
<div class="cbp-hrsub">
<div class="cbp-hrsub-inner">
I am 3rd tab, 300px height.
</div>
</div>
</li>
</ul>
</nav>
Just to clarify, I want to keep the original plugin as it is, just to insert something instead of my 2 lines, towards the end of file. (var content2Height = jQuery(".cbp-hrsub").height() + 400;jQuery('#content2').height(content2Height); //added
Thanks everyone for their time.
Zel
I get inconsistent results when targeting a parent-container with .parent(). In this line:
var $item = $(event.currentTarget).parent('li'),
idx = $item.index();
Try instead to use .closest():
var $item = $(event.currentTarget).closest('li'),
idx = $item.index();
Oh, wait! I see the issue:
var content2Height = jQuery(".cbp-hrsub").height() + 400;
You are retrieving all the .cbp-hrsub classed elements, here. It's going to try to return a height, and I'm not exactly certain how jQuery determines that when it's looking at an array, but I'm guessing it just picks the first element out of the array.
What you're really needing at this point, then, is something like this:
var content2Height = $item.first(".cbp-hrsub").height() + 400;
THAT should give you the height of .cbp-hrsub contained within the current item (found above), and not that of the first .cbp-hrsub in the array.
I know there are a ton of questions on here about jquery image carousel, but they all refer to a plugin. I would like to make one from scratch. It's a pretty simple one, there are 2 buttons, one left and one right. when you click the left button, the position of the overall container that has all the images shifts to the left, and the right makes it go right.
This is what I have so far... Right now the problem is only the left button works. (the right button works only once you slide the image to the left once) And I also want it to animate across all the images, and go to the last image when you get to the end of the set of images
JS:
total_entries = $("image-entry").length;
var current_index = 0;
var slider_entries = $('#slider-entries');
$('#home-slider #left').click(function(){
go_to_index(current_index-1);
return false;
});
$('#home-slider #right').click(function(){
go_to_index(current_index+1);
return false;
});
var go_to_index = function(index){
if(index < 0)
index = total_entries - 1;
if(index > total_entries - 1)
index = 0;
if(current_index == index)
return;
var left_offset = -1 * index * 720;
slider_entries.stop().animate({"left": left_offset}, 250);
//description_container.stop().animate({"left":left_offset}, 250);
current_index = index;
};
HTML:
<div id="slider">
<div id="slider-entries">
<div class="image-entry">
<img src="http://placekitten.com/720/230" />
</div>
<div class="image-entry">
<img src="http://placedog.com/720/230" />
</div>
<div class="image-entry">
<img src="http://placedog.com/720/230" />
</div>
</div>
</div>
total width of each image is 720px
total with of slider-entries is
Thanks
You have a problem with the total_entries variable.
First of all you need a "var" in front, to define that it's a new variable.
Second, you forgot a "." (dot) to search for the class in your HTML code..
your first line should be:
var total_entries = $(".image-entry").length;
Hope it works ;-)