how to avoid dom elements using JS - javascript

I can avoid some div elements using conditions, like
<% if (true) %>{
<div> </div>
<%}%>
can I do this on JavaScript side?

You can do it like this.
if(true){
document.getElementById("div1").style.visibility = "hidden";
}
Fiddle Demo

You can use an if/else statement to avoid specific conditions.
if (something === true ){
//target or add specific div
}else {
//bypass or remove/hide specific div
}
JS can't be used inline the way you wish in your example, but if you really need to do inline Div manipulation, you can use PHP if your server supports it. IN the following example, the div id "content" will only be added to the DOM if "somecondition" is met. Otherwise, it remains hidden (not added to the DOM).
<body>
<?php if (somecondition){ ?>
<div id="content">
Foo
</div>
<?php } ?>
</body>

Related

Markup and Execution of HTML, CSS and JavaScript from seperate textareas

I found a code for real time markup for HTML and CSS in different textareas using a jQuery function that outputs in an iframe:
HTML
<div class="container grid">
<form>
<h3>HTML</h3>
<textarea id="html" class="edit"></textarea> // TEXTAREA FOR HTML
<h3>CSS</h3>
<textarea id="css" class="edit"></textarea> // TEXTAREA FOR CSS
</form>
</div>
<div class="output grid">
<iframe></iframe>
</div>
JQUERY for markup
function() {
$(".grid").height($(window).height());
var contents = $("iframe").contents(),
body = contents.find("body"),
styleTag = $("<style></style>").appendTo(contents.find("head"));
$("textarea.edit").keyup(function() {
var $this = $(this);
if ($this.attr("id") === "html") {
body.html($this.val());
} else {
// it had to be css
styleTag.text($this.val());
}
});
})();
What if I wanted another textarea for javascript? I'm guessing you can't execute it in real time so I have to include a button to to run an eval()
But how?
In your HTML you can have another textarea for the javascript code.
In your textarea.edit event handler, you can add another check for javascript and use something like this -
$iframeEl.append(`<script>${textarea.val()}</script>`);
This line would execute your script as well because the browser re parses the document whenever it encounters a DOM change and it would also execute the script tag.
We should anyways refrain on using the eval keyword because it is an expensive operation and is advised not to be used.

How to get element inside div, inside another html and inside another div?

In "first.html", I load a page inside div using Javascript.
<div id="content">
<div id="lot">Next</div>
</div>
<script>
function load_page()
{
document.getElementById("lot").innerHTML='<object type="text/html" data="next.html"></object>';
}
</script>
Both "first.html" and "next.html" have a div called "banner". I don't want to show "banner" in "next.html". So I add the following lines in "next.html".
<script>
document.getElementById('banner').style.display = "none";
</script>
The weird thing is the banner in "first.html" disappears but not the one in "next.html".
So one way I think to get away with it is if I could reference like this.
"first.html" --> "lot" --> "next.html" --> "banner"
Then try to make it disappear.
I also try this in "next.html", but not working.
<script>
document.getElementById('lot').getElementById('banner').style.display = "none";
</script>
Thanks for the hint.
Solution: When I use iframe, it seems to work. The banner in "next.html" is clearly recognized instead of mixing with the one in "first.html".
I think the simple solution is to use different ID's for the different banners. Something like
id="innerBanner" and id="outerBanner"
Iframe syntax:
<iframe src="URL" width="xxx" height="xxx"></iframe>
I think your problem comes from the folowing line :
document.getElementById("lot").innerHTML='<object type="text/html" data="next.html"> </object>'\
Mabye you can do the same thing with a simple hyperlink:
Next
Than there is no chance, after you write the style in next.html, that it will change something in the previous page's html

document.ready working only once on page load

I have the following code in a .tpl file ("comment_form.tpl"). This file is included in 3 different .tpl files ("file_a", "file_b" and "file_c") once each. And finally these 3 files are included in another .tpl file ("somefile.tpl").
<script type="text/javascript">
$(document).ready(function Hide() {
document.getElementById('div').style.display = 'none';
</script>
So basically, the "comment_form.tpl" is loaded thrice in "somefile.tpl" like so:
.....
</div><!-- .span9 -->
{include file="includes/file_a.tpl"} // includes "file_a.tpl" which already includes "comment_form.tpl" (which contains the code).
</div>
.....//some code
{include file="includes/file_b.tpl.tpl"} // "includes file_b.tpl" which already includes "comment_form.tpl" (which contains the code).
The issue is, the code works the first time. As in, out of the three places where the "comment_form.tpl" is loaded in "somefile.tpl", the target 'div' is hidden only the first time. At the next two places the form (div) isn't hidden.
I hope I am clear enough. What could be the reason??
It is perfectly legal to have multiple $(document).ready(function() {}) calls throughout your page.
It seems that you are hiding your element by ID. Note that IDs must be unique, and if you use the same ID multiple times (#div in your example), only ever the first is selected by getElementById(). That's what you are experiencing.
You must give each <div> a unique ID or group them together with a CSS class and hide the whole class.
Here is an example using a CSS class:
<div class="comment_form">some content</div>
<div class="comment_form">some content</div>
<div class="comment_form">some content</div>
<script type="text/javascript">
$(document).ready(function () {
$('.comment_form').css({'display' : 'none'});
}
</script>
By the way it's far more efficient to directly use CSS for the initial 'hidden' state of your <div>. There is no need to execute JavaScript on page load at all:
<style>
.comment_form { display: none; }
</style>
<div class="comment_form">some content</div>
You can still change the display property of your element later via JavaScript in an onClick event, for example.

If div is empty, set the container div to "display:none"

I've been trying to get this code to work for the past day whilst searching through these forums but without any success.
I'm looking to hide a container div if one of the div's inside has no content.
The script I've got is below:
$('.video-centre').each(function(){
if ($(this).find('.video-thumb p').text().length == "")
$(this).find('.video-centre').css("display", "none");
});
The HTML that I'm trying to apply this to is below:
<div class="video-centre">
<div class="video-point">
<img src="<?php echo get_bloginfo('template_url') ?>/images/video-point.jpg" alt="video pointer" />
</div>
<div class="video-thumb">
<?php the_field('testimonials'); ?>
</div>
<p class="video-more">
View More
</p>
<div id="expandable-1">
<div class="video-thumb">
<?php the_field('testimonials_hidden'); ?>
</div>
<p class="video-close">
Close
</p>
</div>
</div>
Basically, within wordpress, the client will have the opportunity to add videos, it's a bit long winded but they get wrapped in p tags. However if they don't upload anything to a specific area, I would like the container div to have display:none, resulting in only containers being shown if videos have been uploaded.
If there's an easier way to look at the div and say if it's empty then get container div to display none I'd be happy to try that.
Use :empty pseudoclass
if ($(this).find('.video-thumb p').is(':empty'))
this checks if you have an empty paragraph (<p></p>), while
if ($(this).find('.video-thumb').is(':empty'))
checks an empty .video-thumb element
After your edit: if you have spaces inside div the condition return false so it's better to simple check
if ($(this).find('.video-thumb p').length === 0)
Example Fiddle : http://jsfiddle.net/6nyF8/6/
You could do it in several ways.
$('.video-centre').each(function(){
if($(this).find('div.video-thumb').html('') == '')
$(this).hide();
});
OR
$('.video-centre').each(function(){
if($(this).find('div.video-thumb').children().length == 0)
$(this).hide();
});
if ($(this).find('.video-thumb p').text() == "")
or
if ($(this).find('.video-thumb p').is(':empty'))
Hope I understand the Q, here's the fiddle I came up with. Nice and simple.
if ($('.video-centre').find('div:hidden').size() > 0) {
$('.video-centre').children().hide();
}
i would try remowing line feeds between html tags and
<div class="video-thumb">
<?php the_field('testimonials'); ?>
</div>
should be
<div class="video-thumb"><?php the_field('testimonials'); ?></div>
but you could also do the trick in PHP:
<?php if (the_field('testimonials')=="") $style=" style='display:none'";?>
<div class="video-thumb" <?php print $style;?>>
<?php the_field('testimonials'); ?>
</div>
You can also check string with striptags function so from your "testimonials" value remove tags using php in built function "striptags" so now only text will remain which can be compare easily.

getElementsByClassName returns [] instead of asynchronous appended node

(I ask my question again after the first one was terribly formulated)
I face the following problem:
<div class="testA" id="test1"></div>
The above written element is predefined. I now load a xml tree via XMLHttpRequest & Co. delivering the following response:
<response>
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</response>
I now append the first div using
request.responseXML.getElementsByTagName("response")[0]
.getElementsByTagName("div")[0]
into the predefined div
<div class="testA" id="test1">
The final document looks like this (checked using development tools):
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
When I now try to get the element <div class="colorSelector" id="0-0"> using getElementById("0-0") I get the expected result.
But using getElementsByClassName("colorSelector") returns [].
Did I miss something? Is it probably a leftover of the fact the nodes were of type Element and not HTMLElement?
colorSelector is commented out. JavaScript only works within the DOM, and commented out portions aren't in the DOM.
Since you said that your getElementById("0-0") is successful, then clearly you don't actually have the nodes commented out.
I'm guessing you're doing:
document.getElementById("0-0").getElementsByClassName('colorSelector');
...which will not work because the element selected by ID does not have any descendants with that class.
Since you show HTML comments in the markup, I'd also wonder if you have some different element on the page with the ID "0-0". Take a look for that.
If your nodes are actually commented out, you'll need to first select the comment, and replace it with the markup contained inside:
var container = document.getElementById('test1'),
comment = container.firstChild;
while( comment && comment.nodeType !== 8 ) {
comment = comment.nextSibling;
}
if( comment ) {
container.innerHTML = comment.nodeValue;
}
...resulting in:
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
...but there again, this doesn't seem likely since your getElementsById does work.
Here's a way to do it for Firefox, Opera, Chrome and Safari. Basically, you just do div.innerHTML = div.innerHTML to reinterpret its content as HTML, which will make that class attribute from the XML file be treated as an HTML class name.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<script>
window.addEventListener("DOMContentLoaded", function() {
var div = document.getElementsByTagName("div")[0];
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var doc = this.responseXML;
div.appendChild(document.importNode(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0], true));
div.innerHTML = div.innerHTML;
alert(document.getElementsByClassName("colorSelector").length);
}
};
req.open("GET", "div.xml");
req.send();
}, false);
</script>
</head>
<body>
<div class="testA"></div>
</body>
</html>
Remove the this.status === 200 if you're testing locally in browsers that support xhr locally.
The importNode() function doesn't seem to work in IE (9 for example). I get a vague "interface not supported" error.
You could also do it this way:
var doc = this.responseXML;
var markup = (new XMLSerializer()).serializeToString(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0]);
div.innerHTML = markup;
as long as the markup is HTML-friendly as far as end tags for empty elements are concerned.
<!--<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>-->
The above code is gray for a reason: it's a comment. Comments aren't parsed by the browser at all and have no influence on the page whatsoever.
You'll have to parse the HTML, read the comments, and make a new DOM object with the contents of the comment.
Please describe what you are doing with the returned results. There is a significant difference between a nodeList and a node, nodeLists are LIVE.
So if you assign a nodeList returned by getElementsByClassName() (or similar) to a variable, this variable will change when you remove the nodes inside the nodeList from the DOM.
I now append the first div
How do you do that? What you have in the responseXML are XML elements, and not HTML elements.
You shouldn't be able to appendChild them into a non-XHTML HTML document;
actually you shouldn't be able to appendChild them into another document at all, you're supposed to use importNode to get elements from one document to another, otherwise you should get WRONG_DOCUMENT_ERR;
even if you managed to insert them into an HTML due to browser laxness, they're still XML elements and are not semantically HTML elements. Consequently there is nothing special about the class attributes; just having that name doesn't make the attribute actually represent a class. getElementsByClassName won't return elements just because they have attributes with the name class; they have to be elements whose language definition associates the attributes with the concept of classness (which in general means HTML, XHTML or SVG).
(The same should be true of the id attributes; just having an attribute called id doesn't make it conceptually an ID. So getElementById shouldn't be working. There is a way to associate arbitrary XML attributes with ID-ness, which you don't get with class-ness, by using an <!ATTLIST declaration in the doctype. Not usually worth bothering with though. Also xml:id is a special case, in implementations that support XML ID.)
You could potentially make it work if you were using a native-XHTML page by putting suitable xmlns attributes on the content to make it actual-XHTML and not just arbitrary-XML, and then using importNode. But in general this isn't worth it; it tends to be simpler to return HTML markup strings (typically in JSON), or raw XML data from which the client-side script can construct the HTML elements itself.

Categories