i have some project that need to change multiple iframe with some array
example
<ul>
<li>
<iframe src="test.html">
<head></head>
<body>
<div class="content">
<p>test</p>
</div>
</body>
</iframe>
</li>
<li>
<iframe src="test.html">
<head></head>
<body>
<div class="content">
<p>test</p>
</div>
</body>
</iframe>
</li>
</ul>
I need to change <div class="content"><p>test</p></div> for each iframe with an array ["<h1>tittle</h1>","<h1>tittle2</h1>"].
For the first iframe it will be replaced with the HTML in array[0] and second iframe with array[1].
Can anyone help? Thanks
Try with replaceWith()
var array = ["<h1>tittle</h1>", "<h1>tittle2</h1>"]
$(document).ready(function() {
$('iframe').load(function() {
$('iframe').each(function(a) {
$(this).contents().find('body').children('.content').replaceWith(array[a]);
})
})
})
Here you go :
var arr = ["<h1>tittle</h1>","<h1>tittle2</h1>"];
var found=0;
$('iframe').each(function(){
if($(this).find('.content p').length > 0){
$(this).find('.content p').parent().replaceWith(arr[found]);
found++;
}
});
It searches for every iframe, then checks if it contains the tags you want, then replaces them with your array's replacement.
The variable 'found' allows you to travel through the array.
As much as you tagged your post with "jQuery", I suppose you can use this library.
So you just need to iterate over the .each() function.
var array = ["<h1>tittle</h1>","<h1>tittle2</h1>"];
$(".content").each(function(i) {
$(this).html(array[i]);
});
You can obviously replace html() with replaceWith() if you really want to delete the div.
You could try this:
var iframe = $('iframe');
for (i=0; i<iframe.length; i++){
var current = $('iframe')[i+1].contentWindow.document.body.innerHTML;
$('iframe')[i].contents().find('html').html(current);
}
Related
I am trying to modify the body section based on the tagName, using JavaScript. But my webpage is loading infinitely when I use insertBefore() method to insert a tag before the <h1> tag. This problem is not happening when I try to insert before some other elements. I am new to JS, please help me.
This is my HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>Para 1</p>
<p>Para 2</p>
<h1 id="head1">Para 3</h1>
<p id="parax"></p>
<div id="div1">
<p>Hello</p>
</div>
<ul id="mylist1">
<li>Script</li>
<li>deep learning</li>
<li>software testing</li>
<li>Python programming</li>
<li>Database systems</li>
</ul>
<p id="firstp">I was supposed to be first.</p>
<input type="button" onclick="myFunc()">
</body>
<script type="text/javascript">
var cn=document.body.children;
for(var i=0;i<cn.length;i++){
if(cn[i].tagName=="DIV"){
var h1 = document.createElement("H1");
var text = document.createTextNode("h1 tag inserted");
h1.appendChild(text);
cn[i].appendChild(h1);
}
else if(cn[i].tagName=="UL"){
var lis= cn[i].childNodes;
for(var j=0;j<lis.length;j++){
if(lis[j].innerHTML=="Python programming")
lis[j].innerHTML="machine learning";
}
}
else if(cn[i].tagName=="H1"){
var p=document.createElement("P");
var text=document.createTextNode("New para inserted before");
p.appendChild(text);
document.body.insertBefore(p,cn[i]);
}
else
document.write();
}
</script>
</html>
At this line i am facing problem (I think so) :
document.body.insertBefore(p,cn[i]);
Because you with this line code:
document.body.insertBefore(p,cn[i]);
increase number of document.body.children and every time you insert child you and number of body children and you never not hit last index.
please add this to see:
document.body.insertBefore(p,cn[i]);
alert(document.body.children.length); // add this line after insertBefore
see every alert show the number of document.body.children was increase
Thanks to Mr #foad , I got the answer for my question. Actually the insertBefore() method is inside a for loop. So in every iteration, a new tag is added to the body and the length of the body increases by 1. This caused the infinite loading.
The correction is to add a break statement after the insertBefore method:
document.body.insertBefore(p,cn[i]);
break;
This terminates the loop after adding the <p> tag before <h1> tag.
Hello everybody I would like to hide some divs and display others when I click on a specifiks links.
Actually I did like this :
<html>
<head>
<script>
function loadA(){
document.getElementById("A").style.display="block";
document.getElementById("B").style.display="none";
document.getElementById("C").style.display="none";
document.getElementById("D").style.display="none";
}
function loadB(){
document.getElementById("A").style.display="none";
document.getElementById("B").style.display="block";
document.getElementById("C").style.display="none";
document.getElementById("D").style.display="none";
}
function loadC(){
document.getElementById("A").style.display="none";
document.getElementById("B").style.display="none";
document.getElementById("C").style.display="block";
document.getElementById("D").style.display="none";
}
function loadD(){
document.getElementById("A").style.display="none";
document.getElementById("B").style.display="none";
document.getElementById("C").style.display="none";
document.getElementById("D").style.display="block";
}
</script>
</head>
<body>
<div class="menu">
A
B
C
D
</div>
</body>
</html>
This is work with me but as you see it's not a good practice and sure there is another way better than this , can you show me please !
A solution without javascript:
.container > div{
display:none
}
.container > div:target{
display:block
}
<div class="menu">
<a href="#A" >A</a>
<a href="#B" >B</a>
<a href="#C" >C</a>
<a href="#D" >D</a>
</div>
<div class="container">
<div id="A" >A content</div>
<div id="B" >B content</div>
<div id="C" >C content</div>
<div id="D" >D content</div>
</div>
https://developer.mozilla.org/en-US/docs/Web/CSS/%3Atarget
https://css-tricks.com/css3-tabs/
You can create one function and reuse it for each element:
function loadDiv(id){
document.getElementById("A").style.display="none";
document.getElementById("B").style.display="none";
document.getElementById("C").style.display="none";
document.getElementById("D").style.display="none";
document.getElementById(id).style.display="block";
}
And pass the correct id into each onclick:
<div class="menu">
A
B
C
D
</div>
Here's how you should do it. No inline javascript, handling click events with an eventListener and wrapping all elements together with a class, making it much less code to write and maintain:
JS:
function divLoader(e){
var hide = document.getElementsByClassName("hideAndShow");
for (var i = 0; i<hide.length;i++) {
hide[i].style.display="none";
}
document.getElementById(e.target.getAttribute('data-link')).style.display="block";
}
var anchors = document.querySelectorAll('.menu > a');
for (var i = 0; i<anchors.length; i++) {
anchors[i].addEventListener('click',divLoader);
}
HTML:
<div class="menu">
A
B
C
D
</div>
<div id="A" class="hideAndShow" style="display:none;">A</div>
<div id="B" class="hideAndShow" style="display:none;">B</div>
<div id="C" class="hideAndShow" style="display:none;">C</div>
<div id="D" class="hideAndShow" style="display:none;">D</div>
In such cases where you have similar repetitive code you can use a common technique called "Abstraction". The main idea is the turn the common code into parameters of a single function in your case it would be:
function loadByID(id){
document.getElementById("A").style.display="none";
document.getElementById("B").style.display="none";
document.getElementById("C").style.display="none";
document.getElementById("D").style.display="none";
document.getElementById(id).style.display="block";
}
However this is also still a little bit redundant, for larger menus and displaying multiple links you can do something like
function loadByIDs(ids){
var links = document.getElementsByTagName("a");
for(var i = 0; i < links.length; i++){
document.getElementById(links[i].id).style.display = none;
}
for each(var id in ids){
document.getElementById(id).style.display = block;
}
}
This will work much better when you have too much links and want to display more than one link at a time (so you will need to pass in an array)
Note: If you are using Jquery you can just use .each() function to get rid of the first for loop
Hope this helps!
I think the best practice in your case is to define a general function that work however the number of links with specific class in my example the class is link, take a look at Working Fiddle.
Now your script will work with dynamic links added in div, you have just to add html without touching the js will detect change.
HTML :
<div class="menu">
A
B
C
D
</div>
JS :
load = function(e){
//select all links
var links = document.getElementsByClassName('link');
//Hide all the links
for (i = 0; i < links.length; i++) {
links[i].style.display = "none";
}
//Show clicked link
e.target.style.display = "block";
}
Hope this make sens.
HTML
<body>
<div id="main">
<ul id="nav">
<li>Home</li>
<li>About Us</li>
</ul>
<div id="container">
<div id="wrapper">
<div class="content">
<div id="menu_home">
<h2>Menu 1</h2>
</div>
<div id="menu_about">
<h2>Menu 2</h2>
</div>
</div><!--content-->
</div><!--wrapper-->
</div><!--container-->
</div><!-- main-->
</body>
JS
$(document).ready(function(){
$("#menu_home").slideUp("fast");
$("#menu_about").slideUp("fast");
$("#menu_home").show();
$("#nav a").click(function(){
var id = $(this).attr('id');
id = id.split('_');
$(".content div").slideUp("fast");;
$(".content #menu_"+id[1]).slideToggle("fast");
});
});
Here is the example
function loadA()
{
document.getElementById("A").style.visiblity="show";
document.getElementById("B").style.visiblity="hide";
document.getElementById("C").style.visiblity="hide";
document.getElementById("D").style.visiblity="hide";
}
if visibility dont work,just change the visibility keyword with visible and hide with hidden.
and one more thing,u should not write function for each div..what can u do just pass id of a div which u want to show and hide others..see below
function trigger(id)
{
var alldiv={"A","B","C","D"};
for(i=0;i<alldiv.length;i++)
{
if(alldiv[i]==id)
document.getElementById(id).style.visiblity="show";
else
document.getElementById(alldiv[i]).style.visiblity="hide";
}
}
I'm trying to load an array filled with the src attribute from a series of img tags in my HTML document.
HTML:
<html>
<head>
<title>
JQuery Slider
</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<div id = "wrapper">
<h1 class="dark-header">2014 Salt Lake Comic Con FanX</h1>
<div id="background-img">
<img src="img/img01.jpg"/>
</div>
<div>
<img src="img/img02.jpg"/>
</div>
<div>
<img src="img/img03.jpg"/>
</div>
<div>
<img src="img/img04.jpg"/>
</div>
<div>
<img src="img/img05.jpg"/>
</div>
<div>
<img src="img/img06.jpg"/>
</div>
<div>
<img src="img/img07.jpg"/>
</div>
<div>
<img src="img/img08.jpg"/>
</div>
<div>
<img src="img/img09.jpg"/>
</div>
<div>
<img src="img/img10.jpg"/>
</div>
</div>
</body>
</html>
JQuery:
$(document).ready(function() {
var source = new Array();
$('img').each(function(attr) {
source.push($('img').attr('src'))
});
console.log(source)
});//end document.ready
The output to the console is an array of 10 elements, but only using the first img attribute. I'm not sure how to get the each function to go through all elements and push them to the array.
Your issue is that $('img').attr('src') will always return the value of the first element in the collection of elements.
As pointed out in comments , you need to look at specific instances within your loop
Another way you can do this is using map() which will create the array for you
var source = $('img').map(function(){
return $(this).attr('src');
}).get();
DEMO
You could try something like this:
var source = [];
$('img').each(function() {
source.push( this.getAttribute('src') );
});
In your each code, you re-select the entire group with $('img') so it is only adding the first one of THAT Selection to your array.
OR
If you aren't using jQuery for anything else, you could do it in straight javascript like this:
document.addEventListener('DOMContentLoaded', getImgAttr);
var source = [];
function getImgAttr() {
var imgs = document.querySelectorAll('img');
[].forEach.call(imgs, function( img ) {
source.push( img.src);
});
}
you need to use 'this' while inside the loop to reference the image, otherwise you are getting the reference to first 'img ' tag.
it should be like this:
$('img').each(function(attr) {
source.push($(this).attr('src'))
});
Your callback function needs to accept a second param...
The first param is the current index of the array and the second param is the object at that index.
You may also utilize the keyword this as suggested above.
Based on my answer your code would look like this:
$('img').each(function(i, img) {
source.push($(img).attr('src'));
// alternatively -> source.push($(this).attr('src'));
});
A second option you may like and puts what you're trying to do onto a single line would be to use the jQuery map function...
var source = $.map($('img'), function(img) { return $(img).attr('src'); });
I have two similar selections. The first uses a <div> tag, which works fine, the second uses a newly <template> tag, which doesn't work anymore.
Can anyone tell me how to get this to work with jQuery using the <template> tag?
HTML
<div id="div">
<div>content</div>
</div>
<template id="template">
<div>content</div>
</template>
JavaScript
var $div = $('#div');
var $content = $div.find('div');
console.log($content); //works ($content.length == 1)
var $template = $('#template');
var $content = $template.find('div');
console.log($content); //doesn't work ($content.length == 0)
http://jsfiddle.net/s8b5w0Le/1/
HTMLTemplateElement saves the DOM into a seperate attribute:
JQuery
<script src="jquery-3.1.0.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
var $div = $('#div');
var $content = $div.find('div');
console.log($content.text()); // output "content", inner div
var $template = $('#template');
var node = $template.prop('content');
var $content = $(node).find('div');
console.log($content.text()); // output "content", inner template
});
JavaScript
document.createElement('template').content
I'm fairly certain this has to do with Chrome's use of shadow dom (thank Polymer... )
You can either try your luck using the /deep/ combinator (probably won't work on other browsers), but I think the most robust solution would be $template[0].outerHTML as in your comment if you just need the text.
If you need jQuery functionality, using $.parseXML (to avoid Chrome's native dom construction) would probably do the trick across all browsers (can confirm Chrome + FF).
Example here: http://jsfiddle.net/3fe9jjfj
var tc = $('#template')[0].outerHTML;
$template = $($.parseXML(tc)).contents();
console.log($template);
console.log($template.find('div'));
Both logs return as we'd expect, and $template can now be treated as an ordinary jQuery object.
As others have noted, Chrome puts <template> child elements into a shadow DOM. To access them:
// Access the JavaScript object for the template content
$('template')[0]
// Make a jQuery selection out of it
$($('template')[0])
// Now you can search it
$($('template')[0]).find('div.someclass').css('color','#000');
A way, too late for the party but I ended up doing this:
function resolveTemplate(id) {
return $(id).contents();
}
...
var $searchIcon = resolveTemplate('#search-icon-template');
$('#div').append($searchIcon);
You can use all the JQuery methods as usual if the element inside the template element are wrapped with a container.
const temp = $("#template").contents().clone();
$(temp).find("h1").text("A dynamic title");
temp.appendTo($("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="app"></div>
<template id="template">
<div class="container">
<h1>lorem ipsum</h1>
<p>lorem ipsum </p>
<img src="" alt="">
</div>
</template>
The container can also be appended dynamically with JQuery. Or if you don't want a container, you can append its content.
const temp = $('<div></div>').html($("#template").contents().clone());
$(temp).find("h1").text('dynamic title');
$(temp).find("p").text('But no container this time');
temp.contents().appendTo($("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="app"></div>
<template id="template">
<h1>lorem ipsum</h1>
<p>lorem ipsum </p>
<img src="" alt="">
</template>
<template>
<div class="template-container">
<div class="content">content</div>
</div>
</template>
var templateHtml = ('#template').html() // this will return the template container div
var template = $(templateHtml);
var content = template.find('.content');
console.log(content);
var $content = $template.content.find('div');
... instead of ...
var $content = $template.find('div');
Worked for me.
HTML5 template is display: none; by default, childNodes in template is invalid, if you inspect it in console you'll find something different
Sorry if this is a silly question, but I've been trying to use AJAX to display my javascript variables in 'real time' with little luck. I'm definitely a beginner though so this could be the problem haha- When I see the AJAX code, it always seems to require an additional url that it refreshes, but I just want to refresh the javascript variables on click.
http://jsfiddle.net/bagelpirate/m9Pm2/
<script>
var one = 0;
var two = 0;
var three = 0;
</script>
<body>
<div id="div_1">
One: <script>document.write(one)</script> |
Two: <script>document.write(two)</script> |
Three: <script>document.write(three)</script>
</div>
<div id="div_2">
<img id="mine" src="https://si0.twimg.com/profile_images/3170725828/ac1d6621fc3c3ecaa541d8073d4421cc.jpeg" onclick="one++;" />
<img id="forest" src="http://blogs.dallasobserver.com/sportatorium/No.%202.png" onclick="two++;" />
<img id="farm" src="https://si0.twimg.com/profile_images/3732261215/bd041d1f0948b6ea0493f90507d67ef2.png" onclick="three++;" />
</div>
</body>
As you can see in the above code, when a user clicks one of the images, I want to increment the count and display it at the top of the page. I found the HTML5 output tag, and was wondering if it's possible to use this to display the javascript variable in real time? Everything I've read seems to imply it can't be done because the output tag only works on forms? Anyway, I figured it couldn't hurt to ask!
Thanks for your time!
You shouldn't use document.write to write to the DOM after it's finished loading. You have tagged your question with jQuery, so I'll assume you can use that to update things. Instead, update the DOM from within your script block. Here is an example that might help you get started.
http://jsfiddle.net/prxBb/
<script type="text/javascript">
$(function() {
var one = 0;
var two = 0;
var three = 0;
$('img#mine').click(function() {
one++;
$('span#one').html(one);
});
$('img#forest').click(function() {
two++;
$('span#two').html(two);
});
$('img#farm').click(function() {
three++;
$('span#three').html(three);
});
});
</script>
<body>
<div id="div_1">
One: <span id="one"></span> |
Two: <span id="two"></span> |
Three: <span id="three"></span>
</div>
<div id="div_2">
<img id="mine" src="https://si0.twimg.com/profile_images/3170725828/ac1d6621fc3c3ecaa541d8073d4421cc.jpeg" />
<img id="forest" src="http://blogs.dallasobserver.com/sportatorium/No.%202.png" />
<img id="farm" src="https://si0.twimg.com/profile_images/3732261215/bd041d1f0948b6ea0493f90507d67ef2.png" />
</div>
</body>
Maybe you should try putting all your variables inside a named object, iterating through it at predefined interval and displaying the values.
var varContainer = {
one:0,
two:0,
three:0
};
jQuery("#div_2 img").on('click',function(){
jQuery.each(varContainer,function(key,value){
//Add key + value to the DOM
if(jQuery("."+key+value).length<1)
jQuery("#div_2").append("<div class='"+key+value+"'></div>");
var newHtmlVal= "<p><span>Var name: "+key+"</span><br><span>Value: "+value+"</span>";
jQuery("."+key+value).html();
});
});
HTML
<div id="div_2">
</div>
Of course the script could be upgraded to look through each variable recursivley in case of nested objects/arrays...
Hope this helps!