let me just give a quick story. I have made a page. (VERY simple - two divs with a different background image, see here.)
Anyway, I need to make it so that when a new page loads, the two divs that I have load in a random order over and over, filling the entire screen content. So there's no pattern of the first div and then the second, it's just randomly generated. Sort of like a huge grid, with the two divs repeated with no pattern.
My question is...is that possible? I assume I'd need to know PHP, but I have no knowledge of it.
Thanks guys, I appreciate all help!
http://jsfiddle.net/uYPRq/
jquery
var div1 = '<div class="one">';
var div2 = '<div class="two">';
var len =
Math.floor(window.innerWidth/30)*Math.floor(window.innerHeight/30);
for (x = 0; x < len; x++) {
if ( Math.random() > 0.5 ) {
$(div1).appendTo('body');
}
else {
$(div2).appendTo('body');
}
}
css
div.one, div.two {
height:30px;
width:30px;
float:left;
}
div.one { background-color:#EBE1E4; }
div.two { background-color:#F0F5DF; }
edit:
changed screen.availWidth to window.innerWidth
Something like so? Just loop through how ever many times you like and add elements in.
for (i = 0; i < 300; i++) {
var type1 = document.createElement("div");
var type2 = document.createElement("div");
type1.innerHTML = "div1";
type2.innerHTML = "div2";
type1.setAttribute("class", "type1");
type2.setAttribute("class", "type2");
document.body.appendChild(type1);
document.body.appendChild(type2);
}
No PHP needed. This can be done client-side using Javascript (Jquery might be easier).
Related
I wrote a script in a section of my HTML code to output an image to my browser 10 times by using a for loop. This works fine, but I also want to write a script in the head element of the markup where I can maybe use a function to first create an HTMLCollection from the image elements, and then loop through all ten images in the collection, adding 5 pixels to the width and height properties of each succeeding image element from left to right when any one of the ten images is clicked.
I've tried to research information on HTMLCollections combined with DOM related properties and other equations, but have been unsuccessful so far.
Script from the body element
<section>
<h2>Growing Pumpkins</h2>
<p id="smashingPumpkins" onclick="growingPumpkins(this)" ></p>
<script>
for (var i = 0; i < 10; i++) {
document.getElementById("smashingPumpkins").innerHTML += "<img src='bandit.png' />";
}
</script>
</section>
Script from the head element:
<script>
function growingPumpkins(img) {
var img = document.images;
for (index in img) {
document.getElementById("smashingPumpkins").innerHTML = img[index].style.width + 1.05;
document.getElementById("smashingPumpkins").innerHTML = img[index].style.height + 1.05;
}
}
</script>
The size of each image should increase by 5 pixels spanning from left to right (apologies for the redundancy) when output to the browser. However, I have been unable to accomplish this, and only see the number 1.05 when I click on one of the images.
What about this?
for (var i = 0; i < 10; i++) {
document.getElementById("smashingPumpkins").innerHTML +=
`<img src='bandit.png' style="width:${base + i*5}px; height:${base + i*5}px "/>`;
}
Of course the 'base' being used in the style attribute is something you set, like 100 or however many pixels you want the height and width of the first one to be
EDIT:
That was just to make each picture bigger than the last, which is not exactly what you asked. But your comment makes me think I should leave it for learning purposes. What you could do have each picture expand on click, and each one expand 10px bigger than the one before it, is this:
Add a class to your images to easy targeting, then target them into an array:
for (var i = 0; i < 10; i++) {
document.getElementById("smashingPumpkins").innerHTML +=
"<img src='bandit.png' class="expandingImg" />";
}
var images = document.querySelectorAll('.expandingImg') // creates an array of your image elements
Now loop through your array of elements and attach an event listener to each one. The event listener will change the style element of that element, based on the element's position in the array. So elements later in the array will expand more than ones earlier in the array. This also eliminates the need for your onclick="growingPumpkins(this)" because the eventlisteners are being added in this immediately invoked functional expression (IIFE):
(function growingPumpkins() {
for (let i = 0; i < images.length; i++) {
images.addEventListener('click', function(){
images[i].style = `style="width:${base + i*5}px; height:${base + i*5}px`
}, false)
})()
I think that should do it. You'll need to add another event listener so that they shrink back down to their original size, like mouseleave or something like that. Hopefully this works and is helpful.
I created a small script that counts images that I uploaded/inserted to my html source code. After I inserted images script creates div containers for those images. If I gave three images, then script will create three divs with class name etc. I have css rule with that class name. This was create before any images were in that container. Everything works but I just can't append those newly images to newly created divs. Is there a way using JavaScript only?
Here is a code:
if (document.getElementsByClassName("Multimedia")[0].getElementsByTagName("IMG")) {
total_number_of_images = document.getElementsByClassName("Multimedia")[0].getElementsByTagName("IMG").length;
for (i = 0; i < total_number_of_images; i = i + 1) {
document.getElementsByTagName("IMG")[i].className = "Image_clip";
child = document.getElementsByTagName("IMG")[i];
image_container = document.createElement("DIV");
image_container.className = "Image_container_div";
document.getElementsByClassName("Multimedia")[0].appendChild(image_container);
document.getElementsByTagName("IMG")[i].style.opacity = "0.8";
}
}
I tried somthenig like this:
image_container.appendChild(child);
But then I can get only two images into container... my third is out and also without className. Without this code, I get className for every image
You should cache the reference to elements rather than querying DOM in loops.
If I understood correctly, Your code should look something like the following for wrapping each image in a container <div>:
var container = document.getElementsByClassName("multimedia")[0];
// if there is only one match, use an id instead ------------^ ?
var images = container.getElementsByTagName("img");
for (var i = 0; i < images.length; i++) {
var img = images[i];
img.className = "imageClip";
img.style.opacity = "0.8"; // Why not define this in imageClip class ..?
imageContainer = document.createElement("div");
imageContainer.className = "imageContainer";
imageContainer.appendChild(img);
container.appendChild(imageContainer);
}
This I get on Yahoo answer. Posted by YaYox: http://jsfiddle.net/ffxad4bq/4
function myFunction() {
var multimedia = document.getElementsByClassName("Multimedia")[0]
var imgs = multimedia.getElementsByTagName("IMG");
for (var i = 0; i < imgs.length; i++) {
imgs[0].className = "Image_clip";
imgs[0].style.opacity = "0.3";
multimedia.innerHTML += '<div class="Image_container_div">'+imgs[0].outerHTML+'</div>';
imgs[0].remove()
}
}
I realized what was the problem. I shouldn't itaret through images. Just leave it on zero because, when loops start, code append one image at a time. When second loop starts I don't have any more 3 images, but two, that is why one image always stays out because loop goes three times.
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 have a large HTML source, and I'd like to break it into multiple parts. I've been able to achieve most of this task, but I'm struggling with a single aspect.
When all of the HTML is wrapped in tags, I have no problem; however, if text nodes are mixed with HTML tags, I'm unable to capture all parts.
What am I doing wrong?
Below, is a jsFiddle that shows an example of the problem.
http://jsfiddle.net/acrashik/aDm8L/1/
Here is the code I have written so far to attempt to break up the HTML:
function parseElement(selector,parts, cycle) {
var cc = $(selector),
content = cc.children(),
total = content.length,
maxHeight = cc.height(),
spaceLeft = maxHeight,
cycle = cycle || 0;
function addToPage(elem,elemSize) {
elem.appendTo(parts[cycle]);
spaceLeft -= elemSize;
}
function startNewPage() {
cycle++
parseElement(selector,parts, cycle);
}
$.each(content,function(index,v){
var elem = $(v),
tag = elem[0].tagName.toLowerCase(),
elemSize = elem.outerHeight(true);
if (elemSize <= spaceLeft) {
addToPage(elem,elemSize);
} else if (elemSize > spaceLeft) {
startNewPage();
}
});
}
Question
How can I parse all the HTML text, even unwrapped text nodes, preserving structure and order?
Update
Thanks for help, case solved, only possible way to measure text node height is to wrap it, here is code how to achieve that:
$(selector).contents().filter(function(){
return this.nodeType === 3
}).wrap('<span />');
and here is fully working example:
http://jsfiddle.net/acrashik/aDm8L/20/
thanks everyone.
The problem you are facing comes from using jQuery.children():
Note also that like most jQuery methods, .children() does not return
text nodes;
Instead, you should use the native DOM property, childNodes which does contain text nodes:
cc[0].childNodes;
Or, better yet, pass in the reference to the DOM node:
function parseElement(element, parts, cycle) {
var cc = $(element),
content = element.childNodes,
total = content.length,
maxHeight = cc.height(),
spaceLeft = maxHeight,
cycle = cycle || 0;
//Your other functions down here...
}
And call like:
parseElement(document.getElementById('source2'), ['#part3','#part4']);
Notice You'll need to revisit your other methods to accommodate these changes.
You can use css to split into several columns. I don't know your targeted browsers but here is the code (only on modern browsers) :
html :
<div class="columns">
very long text split into 4 columns
</div>
css :
.columns {
-webkit-columns: 4;
-moz-columns: 4;
columns: 4;
}
sample here : http://codepen.io/raphaelgoetter/pen/ehfxb
OK basically i need help to create a code that increase font size on a mouse click.
Here is an example:
http://www.rnib.org.uk/ in the top right corner there are 3 AAA's which increase the pages font size etc
my current code is
// JavaScript Document
var min = 12;
var max = 32;
function increaseFontSize() {
var p = document.getElementsByTagName('p');
for (i = 0; i < p.length; i++) {
if (p[i].style.fontSize) {
var s = parseInt(p[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
}
if (s != max) {
s += 1;
}
p[i].style.fontSize = s + "px"
}
}
function decreaseFontSize() {
var p = document.getElementsByTagName('p');
for (i = 0; i < p.length; i++) {
if (p[i].style.fontSize) {
var s = parseInt(p[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
}
if (s != min) {
s -= 1;
}
p[i].style.fontSize = s + "px"
}
}
it is implemented in the HTML like this:
-
+
mine only works for items tagged as 'p' can anyone help me create it so the function works like the RNIB.org website cheers
I think you may be overcomplicating things. I would approach this issue more from a CSS perspective with a little minor work through JS. I would:
Use a class name on a container element
Use CSS to style several different sizes
Use JS to change the class name when the plus/minus links are clicked
HTML:
Small Font
Large Font
Normal Font
<div id="myContainer" class="size-normal">
<h1>Some header</h1>
<p>Some paragraph</p>
<ul>
<li>Some list item</li>
</ul>
</div>
CSS:
#myContainer.size-normal { font-size: 12px; }
#myContainer.size-large { font-size: 14px; }
#myContainer.size-small { font-size: 10px; }
JS:
var containerEle = document.getElementById('myContainer');
function smallFontSize() {
containerEle.className = "size-small";
}
function largeFontSize() {
containerEle.className = "size-large";
}
function normalFontSize() {
containerEle.className = "size-normal";
}
If your CSS is set up so that you have a body font-size set to 100% and all element font sizes defined as 1.1 em, 1.5em, etc. Then your buttons can trigger these to increase or decrease the font size of the whole page.
document.getElementsByTagName('body')[0].style.fontSize.smaller;
document.getElementsByTagName('body')[0].style.fontSize.larger;
All elements will then change size relative to each other, e.g. your h1, h2, etc. will still be bigger than your p elements.
I would consider 'larger' and 'smaller' buttons more user-friendly than three predefined sizes.
Instead of doing this just for your site, what if you keep the icons there, but when someone presses them, you show a popup explaining that zoom/font-size increase is built-in to almost every browser out there already?
That gets around the complications of writing a script or what interval to use for the font size, plus it has the added benefit of teaching users that this functionality is already available on almost any website they use.
You can also do a little UA sniffing to determine which hot-key they should press and show that in the pop-up.
Personally, I'm not recommended to increase/decrease the font size by 1 every click. It is because you have to iterate many elements and set the font size. I will suggestion use 3-5 class to define the font-size and set to body to affect the further elements. But if you insist to increase/decrease the font size by 1 every click, you can reference the following code. If you would like to select elements from header, you can select it like this document.getElementById("menu").getElementsByTagName("h1")
function increaseFontSizeInternal(list) {
for(i=0;i<list.length;i++)
{
var s = 12;
if(list[i].style.fontSize)
{
s = parseInt(list[i].style.fontSize.replace("px",""));
}
if(s!=max)
{
s += 1;
}
list[i].style.fontSize = s+"px"
}
}
function increaseFontSize()
{
var paragraph = document.getElementsByTagName('p');
increaseFontSizeInternal(paragraph);
var links = document.getElementsByTagName('a');
increaseFontSizeInternal(links);
var headerInMenu = document.getElementById("menu").getElementsByTagName("h1")
increaseFontSizeInternal(headerInMenu);
}
function decreaseFontSizeInternal(list)
{
for(i=0;i<list.length;i++)
{
var s = 12;
if(list[i].style.fontSize)
{
s = parseInt(list[i].style.fontSize.replace("px",""));
}
if(s!=min) {
s -= 1;
}
list[i].style.fontSize = s+"px"
}
}
function decreaseFontSize()
{
var paragraph = document.getElementsByTagName('p');
decreaseFontSizeInternal(paragraph);
var links = document.getElementsByTagName('a');
decreaseFontSizeInternal(links);
var headerInMenu = document.getElementById("menu").getElementsByTagName("h1")
decreaseFontSizeInternal(headerInMenu);
}
I recommend you to just to change page zoom. This will not break the design of website.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
A+<br>
A-