split html content into fixed height and width divs with jQuery - javascript

I'm trying to split a large html page into smaller fixed height and width chunks (pages).
Its pretty easy if I know the pages count - I can generate required number of pages first and then fill them with source content children:
children = $('#source').children();
width = 600;
height = 600;
// already generated 'pages'
divs = $('.page');
$(divs).width(width);
pages = divs.length;
i = 0;
for (var c = 0; c < pages; ++c) {
var div = $(divs).eq(c);
while (i < children.length && div.height() < height) {
$(children[i++]).clone().appendTo(div);
}
if(div.height() > height) {
div.contents().last().remove();
i--;
}
}
But how can I do the same thing if I don't know the pages count?
How to wrap content with $('div.page') and keep adding pages until I reach the end of content?
thanks

You would want to use a loop to keep creating pages / filling them with content until you hit some endpoint, where you'd break out of the loop. The key here is dynamically creating the page divs in the loop. You can use document.createElement or simply $("") (or other jQuery ways). Something like this:
var i = 0;
while(true) {
if (content /* have more content */) {
var page = document.createElement("div");
$(page).addClass('page');
var children = $(content).children();
while (i < children.length && div.height() < height) {
$(children[i++]).clone().appendTo(page);
}
$(body).append(page);
} else {
break;
}
}
You may also want to use jQuery's each method if you have defined blocks of content to add to each 'page'.
Comment if you need more help.

Related

Different/Increasing CSS Value for Many DIVs With Same Class

I want to use javascript to change the left-margin value of many separate DIVs. The catch is that:
I want to use only one className and
I want the margin to increase, for example, 100px for each instance of the class. This way, instead of having all the DIVs land on top of each other, each DIV will be space out: the first at margin-left:0px, the second at margin-left:100px, the third at margin-left:200px, and so on.
Here is the code that I have which simply applies the same margin-left to all DIVs.
<script>
b = document.getElementsByClassName('spacing');
for (i = 0; i < b.length; i++) {
b[i].style.marginLeft = "100px";
}
</script>
Is there a way to get the javascript to find each instance of the class sequentially and instead of simply applying margin-left:100px to all, it does something like (margin applied to last instance of class + X) so each of 100 DIVs with the same className end up with a unique marginLeft value?
Yes there is a way You can simply multiply the amount of margin by iteration number like this i*100+'px' instead of this "100px"
var b = document.getElementsByClassName('spacing');
for (i = 0; i < b.length; i++) {
b[i].style.marginLeft = i*5+'px';
}
Here is the working example
What you want to do is keeping track of your increasing margin by every iteration of the loop:
b = document.getElementsByClassName('spacing');
var margin = 0;
for (i = 0; i < b.length; i++) {
margin += 100;
b[i].style.marginLeft = margin + "px";
}
That should do the trick.
Check out a working example here: https://jsfiddle.net/c4p9ry46/

Get the text from a div with a certain condition

I have a big div containing many divs inside, I need to get the text from those inner divs but at certain condition, something like this:
for (var i = 0; i < g; i++)
{
var h = $('#infor > div').["dataid = i"].text();
alert(h);
}
(infor) is the id for the big div and (dataid) is the attribute of the inner divs
You need to use:
var h = $('#infor > div[dataid = '+ i +']').text();

Get Z-index of each element on the page

I am trying to find the highest z-index on a page. I am using this
var getStyleProp = function(el, prop){
return window.getComputedStyle(el, null).getPropertyValue(prop);
}
var getHighestZIndex = function(){
var highestZIndex = 0,
HTMLElems = ["a","abbr","acronym","address","applet","area","article","audio","b","base","basefont","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","embed","fieldset","figcaption","figure","footer","form","frame","frameset","h1, h2, h3, h4, h5, h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","isindex","kbd","keygen","label","legend","li","link","listing","main","map","mark","menu","menuitem","meta","meter","nav","noembed","noscript","object","ol","optgroup","option","output","p","param","plaintext","pre","progress","q","rp","rt","rtc","ruby","s","samp","script","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr","xmp"],
tags,
zIndex;
for (var i = 0; i < HTMLElems.length; i++){
tags = document.getElementsByTagName(HTMLElems[i]);
if (tags){
for (var c = 0; c < tags.length; c++){
zIndex =getStyleProp(tags[c], "z-index");
console.log(tags[c], "zIndex=", zIndex);
if (zIndex > highestZIndex){
highestZIndex = zIndex;
}
}
}
}
return highestZIndex;
}
console.log(getHighestZIndex());
But everything is coming back as "auto". This ancient article explains how a "bug" is causing this behavior. I've tried to make clones of each node, set the position to relative, and then get the z-index,
cl.style.display = "none";
cl.style.position = "absolute";
zIndex = (getStyleProp(cl, "z-index"));
but that is not working either. What is wrong here? Is there a cheaper way to do this than recreating everything on the page?
JSBIN
The node's clone does not seem to get the z-index, while the node itself returns the right value. You could try using it instead (not sure how it might react on a page with lots of content):
var getHighestZIndex = function () {
var highestZIndex = 0,
zIndex,
pos,
tags = document.body.getElementsByTagName('*');
for (var c = 0; c < tags.length; c++) {
// Get the original 'position' property
pos = getComputedStyle(tags[c]).position;
// Set it temporarily to 'relative'
tags[c].style.position = "relative";
// Grab the z-index
zIndex = getComputedStyle(tags[c]).zIndex;
// Reset the 'position'
tags[c].style.position = pos;
console.log(tags[c], "zIndex=", zIndex);
if (zIndex > highestZIndex) { highestZIndex = zIndex; }
}
return highestZIndex;
};
console.log(getHighestZIndex());
JS Fiddle Demo
Changing the element's position temporarily might produce a glitch. You'll need to test that on a page with lots of contents and elements that are position:absolute; or position:fixed;.
If this doesn't fit your use-case, just let me know, and I'll remove it. However, as a thought.
Can you loop through all the tags, and if the value is "auto" assume it's 999. If it's >= 1000, take that as your "highest" value. Then, increment your zIndex up from your highest number that way. This way, the first tag you place will be 1000, the next will be 1001.
var elements = document.getElementsByTagName("*"),
maxZIndex = 999;
for( var i=0; i < elements.length; i++ ) {
var zIndex = parseInt(elements[0].style.zIndex) || 999;
maxZIndex = zIndex > maxZIndex ? zIndex : maxZIndex;
}
return maxZIndex;
This would fit a use case where you are just trying to make sure that the tag you are placing is greater than anything on the page...such as placing a modal.
999 is overkill...somewhat of a "just in case" I missed something because anything with z-index:auto is equivalent to zero. See the following "proof" where even though my z-index is only "1" it overlaps boxes that are 3-deep of "auto".
<div style='position:absolute;background-color:white;z-index:1;width:94px;height:94px;'>
</div>
<div style='position:absolute;background-color:red;width:100px;height:100px;'>
<div style='position:absolute;background-color:blue;width:98px;height:98px;'>
<div style='position:absolute;background-color:green;width:96px;height:96px;'>
</div>
</div>
</div>

Force begin rendering with javascript

I've an ajax-call that will give me a 500 row return. Each row will create a HTML-object that will be added to the DOM. This all works fine, but it's slow.
I would like to add 20, then render what is done, and then continue to add the last 480. However, I can't figure out how to force rendering.
The code is something like this:
for (i = 0; i < 500; i += 1) {
$(newdata[i]).insertAfter('#object');
}
Where newdata is a textstring, for example
"<p>hello world</p>"
Edit
I might have left out some critical information in my post. The nodes are not to be inserted in order. It's a tree and each node has a parent that I know about. And each parent is garanteed to be inserted before the node. So I can't just append nodes after eachother since they might be in different branches.
Stop inserting one node at the time, insert collections of nodes instead.
It's not the loop that's slow, it's DOM manipulation that is slow, and inserting 500 DOM nodes one node at the time will be slow.
var nodes = $();
for (i = 0; i < 20; i++) {
nodes.append(newdata[i])
}
$('#object').after(nodes);
var more_nodes = $();
for (i = 20; i < 500; i++) {
more_nodes.append(newdata[i])
}
$('#object').after(more_nodes);
If you do it like this, it will probably be ten times faster, and you don't have to insert 20, then 480 etc.
Give the rendering code time to run. Write a few rows, call setInterval() to let other code run, and continue:
function renderLines(newdata) {
var len = newdata.length;
var sofar = 0;
var obj = $('#object');
var renderSome = function() {
for ( var i = 0; (i < 20) && ((i + sofar) < len); ++i )
{
$(newdata[i + sofar]).insertAfter(obj);
}
sofar += 20;
if (sofar < len)
setTimeout(renderSome, 10);
};
setTimeout(renderSome, 10);
}

How do i get the link of the topmost positioned image in a website?

I'm writing a script which needs the src of the image which is positioned topmost on any website, NOT the FIRST image in the source, but the one positioned the highest.
i tried something really basic, which is, retrieving the first image tag, however this wont work for images positioned by css/jquery/javascript.
so any idea how i can accomplish this?
|-----------------
| .....title....
| |------|
| |image | <==== link needed
| |------|
|//text content
|Lorem dolor ipsum
I'm not certain about the jQuery reply but I believe that will still only give
you relative image coordinate. Following this earlier post showing a method to get the
absolute x, y coordinates of a html element on a page, and stealing the same method
from PrototypeJS, the following code should do what you need,
Caveats, I think that the 0 top check is safe to use to determine if an image is
invisible or not, but it might be problematic. Also, this will only get images inside img tags, not image links or anything set with css.
// cumulative offset function stolen from PrototypeJS
var cumulativeOffset = function(element) {
var top = 0, left = 0;
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while(element);
return {
top: top,
left: left
};
};
// get all images
var results = document.getElementsByTagName("img");
var images = [];
for (result in results) {
if (results.hasOwnProperty(result)) {
images.push(results[result]);
}
}
// map our offset function across the images
var offsets = images.map(cumulativeOffset);
// pull out the highest image by checking for min offset
// offset of 0 means that the image is invisible (I think...)
var highest = images[0];
var minOffset = offsets[0];
for (i in offsets) {
if (minOffset.top === 0 ||
(offsets[i].top > 0 && offsets[i].top < minOffset.top)) {
minOffset = offsets[i];
highest = images[i];
}
}
// highest is your image element
console.log(highest);
You need to compare the .y property of each element.
function getTopMostImage() {
//Get all images
var imgs = document.querySelectorAll("img");
//Define a variable that marks the topmost image
var topmost = imgs[0];
//Check all image positions and mark the topmost
for (i = 1; i < imgs.length; i++) {
if (topmost.y > imgs[i].y)
topmost = imgs[i];
}
return topmost.src;
}
After load you can check the first img element present in Dom by first() Docs are here
Hope it helps
// Use the most appropriate selector for your images such as "body img" or bla bla...
var images = jQuery('img');
var topMostImageIndex = 0;
for (var i = 0; i < images.length; i++) {
if (jQuery(images[i]).position().top < jQuery(images[topMostImageIndex]).position().top) {
topMostImageIndex = i;
}
}
// It's the top-most image
images[topMostImageIndex];

Categories