function setText() {
// doesn't change... why not!?
document.getElementById("demo").firstChild.innerHTML = 'changed!';
}
//calling the function with setTimeout to make sure the HTML is loaded
setTimeout(setText, 500);
<div id="demo">
<p>first</p>
<p>second</p>
</div>
I can't seem to be able to change <p>first</p> to <p>changed!</p>. Why not?
Whitespace inside elements is considered as text, and text is considered as nodes.
If you change the HTML to:
<div id="demo"><p>first</p><p>second</p></div>
it works. Try it.
Or you can use node.firstElementChild to ignore leading text, or use a library like jQuery which takes care of this.
On consoling document.getElementById("demo").firstChild I get this
.
The highlighted part show empty text. That may be the reason as it is not the first p element.
Instead you can use firstElementChild
function setText() {
document.getElementById("demo").firstElementChild.innerHTML = 'changed!';
}
setTimeout(setText, 1000);
<div id="demo">
<p>first</p>
<p>second</p>
</div>
You can always use children method or querySelector
function SetText(){
document.getElementById('demo').children[0].textContent = "changed"
}
Or
function SetText() {
document.querySelector('#demo > *').textContent = "changed"
}
Using ".firstChild" will select the whitespace in a div if there is any. In your case there is some. You have two options, either take our the whitespace/newlines or use this function instead...
function setText() {
// doesn't change because the firstChild isn't the <p> element...
// try using firstElementChild
document.getElementById("demo").firstElementChild.innerHTML = 'changed!';
}
Related
I have a header on my page, and block with boxes. That boxes represents my projects. When I click on one of them it is suppose to change my header background.
<div class="row">
<div class="job-one one-half column" onclick="headerProjBackground()">
<p>First</p>
</div>
<div class="job-two one-half column" onclick="headerProjBackground()">
<p>Second</p>
</div>
</div>
And my function:
function headerProjBackground(){
if($(this).hasClass('job-one')){
console.log('Hi!');
$('header').css('background-image': 'url(css/images/first-thing.png)');
}
if($(this).hasClass('job-one')){
console.log('Hello!');
$('header').css('background-image': 'url(css/images/second-thing.png)');
}
}
But it is not working. It can't understand my (this). There are no errors in the console. So this is logical mistake.
Onlcick attribute in Javascript by default Runs under Window, that means "this" object in the the function will always be window and as it doesn't have any class associated with it, so it will always give false in both if statement.
Refer below updated code snippet -
$('.jSelector').click(function(){
if($(this).hasClass('job-one')){
console.log('First Clicked!');
}
if($(this).hasClass('job-two')){
console.log('Second Clicked!');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="job-one one-half column jSelector">
<p>First</p>
</div>
<div class="job-two one-half column jSelector">
<p>Second</p>
</div>
</div>
Hope this helps!!
Outside of the onclick attribute, this is no longer defined. You can fix this in (at least) two ways.
Alt 1: Pass this as a parameter:
<div class="job-one one-half column" onclick="headerProjBackground(this)">
function headerProjBackground(clicked) {
//Replace this with clicked in the code of the function.
Alt 2: Do the event binding with jQuery instead of with HTML attributes:
<div class="job-one one-half column backgroundchanger">
$(".backgroundchanger").click(function() {
//Put the same code as for headerProjBackground() in your question.
//Here you can use the this keyword.
});
And some further thoughts: The way you have coded this is not very good if you want it compact (and clear). So lets try to improve it some! If you go with Alt 2 you could use a custom data- attribute to shorten the code:
<div class="one-half column" data-background="css/images/first-thing.png">
//If something that has the data-background attribute is clicked.
$('[data-background]').click(function() {
//Get the value from the data-background attribute, and use that as background image.
var background = $(this).attr('data-background');
$('header').css('background-image': 'url(' + background + ')');
});
Or, if you use Alt 1, you could just pass the desired background url as a parameter instead of this.
You can remove the onclick attribute on your divs and add the following, also the .css method has two parameters with comma between them.
<script type="text/javascript">
// once the dom is ready
$(document).ready(function() {
// check if any of the divs with column class is clicked
$('.column').click(function() {
// trigger the function and pass the (this) which is the object for the div clicked
headerProjBackground(this);
});
});
// element passed will be worked on in the function
function headerProjBackground(element){
if($(element).hasClass('job-one')){
console.log('Hi!');
$('header').css('background', '#000');
}
if($(element).hasClass('job-two')){
console.log('Hello!');
$('header').css('background', '#DDD');
}
}
</script>
Let's say I have the following DOM structure, for simplicity:
<div class='myparent'>
<div class='child'>
<div class="label">A</div>
<div class="ico"/>
</div>
<div class='child'>
<div class="label">B</div>
<div class="ico"/>
</div>
<div class='child'>
<div class="label">C</div>
<div class="ico"/>
</div>
</div>
I would like to loop within all child Element returned by the function findAllByCssSelector('.child'). In particular, I would click on the ico div subelement ONLY if the label of the div is B.
I would remember, that findAllByCssSelector() returns Promise.<Array.<leadfoot/Element>>.
Typically I should do something like:
var my_label = null;
this.remote
.findAllByCssSelector('.my-selector').then(function (elementArray) {
for(.....) {
elementArray[i]
.getVisibileText()
.then(function (text) {
if(text == my_label)
elementArray[i].findByCssSelector('.ico').click().end()
}
}
})
I tried this code but did not work, because the elementArray[i] within the getVisibleText().then() function does not exist - it's like I lose its reference. Furthermore, I need also that if the label is not found at the end of the loop, an exception should be thrown.
How can I achieve that? Could anyone help, please?
The simplest way to do this would be to use an Xpath expression to select the item directly, like:
.findByXpath('//div[#class="child" and div[#class="label" and text()="B"]]/div[#class="ico"]')
The expression above will find the first div with class "ico" that's the child of a div with class "child" that has a child div with class "label" and text content "B".
Update
Using an Xpath expression is almost always preferable to looping through elements using Leadfoot commands because it's significantly more efficient, but if looping is desired for some reason, you can do something like:
var my_label = null;
this.remote
.findAllByCssSelector('.my-selector')
.then(function (elementArray) {
return Promise.all(elementArray.map(function (element) {
return element.getVisibleText()
.then(function (text) {
if (text === my_label) {
return element.findByCssSelector('.ico')
.then(function (ico) {
return ico.click();
});
}
});
});
});
A couple of key points to note:
You need to return Promises/Commands from then callbacks when you're performing async operations in the then callbacks
Element methods (like element.findByCssSelector) return Promises, not Commands, so you can't call click on the result.
I just want to ask let say if we have multiple divs with same id how can we display none them using javascript ?
I tried:
<script>
function filterfunc() {
if(document.getElementById('filter_deductible').value == 'id_50'){
document.getElementById('id_0').style.display = 'none';
document.getElementById('id_50').style.display = 'block';
}
}
</script>
And here is my html divs with same ids:
<div id="id_0">0</div>
<div id="id_0">0</div>
<div id="id_50">50</div>
But its hidding only one div of id id_0 instead of all div having id_0
Any suggestions please
Id must be unique, you should use class like,
<div class="id_0">0</div>
<div class="id_0">0</div>
<div class="id_50">50</div>
And to hide all id_0 use
function filterfunc() {
if($('#filter_deductible').val() == 'id_50'){
$('div.id_0').hide();
$('div.id_50').show();
}
}
It simple using jQuery like
HTML
<select name="filter_deductible" id="filter_deductible">
<option value="id_0">0</option>
<option value="id_50">50</option>
</select>
<div id="id_0">0</div>
<div id="id_0">0</div>
<div id="id_50">50</div>
jQuery
$("#filter_deductible").change(function(){
if($(this).val()=="id_50")
{
$('[id="id_0"]').hide();
}
});
Demo
you should use a class in case there are multiple elements. Or use different ids.
Ids are meant to be unique.
<script>
function filterfunc() {
if(document.getElementById('filter_deductible').value == 'id_50'){
$('.id_0').css("display","none")
$('.id_50').css("display","block")
}
}
</script>
<div class="id_0">0</div>
<div class="id_0">0</div>
<div class="id_50">50</div>
Or
<script>
function filterfunc() {
if(document.getElementById('filter_deductible').value == 'id_50'){
$('.id_0').hide()
$('.id_50').css("display","block")
}
}
</script>
<div class="id_0">0</div>
<div class="id_0">0</div>
<div class="id_50">50</div>
Do not do this. Having multiple elements with the same ids leads to undefined behaviour. If you need to attach information to your dome nodes use data attributes or classes.
Notice how getElementById is singular form? It only ever expects to select and return one element.
That being said, you can probably get away with
document.querySelectorAll("#id_0")
if you want to use javascript functions on dom elements you have to use class not id attribute.
id attribute is unique in whole html document.
try to use jquery.
$.(document).ready(function(){
$("#filter_deductible").change(function(){
var $this = $(this); //instance of element where was changed value
if($this.val() == 'id_50'){
$(".id_0").hide();
$(".id_50").show();
}
});
});
your document html should looks like.
<div class="id_0">0</div>
<div class="id_0">0</div>
<div class="id_50">50</div>
this will works only if you will include jquery library inside tags. And your dom element #filter_deductible allows change event trigger.
hope i helped you
Use classes in this case ID is unique.
<div class="zero">0</div>
<div class="zero">0</div>
<div class="class_50">50</div>
you can use jQuery:
$('.zero').hide();
$('.class_50').show();
The HTML spec requires that the ID attribute to be unique in a page:
If you want to have several elements with the same ID your code will not work as the method getElementByID only ever returns one value and ID's need to be unique. If you have two ID's with the same value then your HTML is invalid.
What you would want to do is use div class="id_0" and use the method getElementsByClassName as this returns an Array of elements
function filterFunc() {
var n = document.getElementsByClassName("id_0");
var a = [];
var i;
while(n) {
// Do whatever you want to do with the Element
// This returns as many Elements that exist with this class name so `enter code here`you can set each value as visible.
}
}
I have HTML like that :
<div id="MyArea">
<div class="data-content">The content is not satisfied </div>
<div class="data-content">[value] </div>
<div class="data-content">[valueme] </div>
</div>
Now, I want run a Function in each class (data-content) that have brackets. Others class (have no brackets), keep default and do not change anything. I use script below, but it is be error.
$("#MyArea .data-content").each(function() {
var content = $(this).html(),
values = content.match(/[^[\]]+(?=])/g);
if (value !== "") {
$(this).closest(".data-content").myFunc({
//Run myFunc in this .data-content if values has brackets.
}
else {
//return the default value and do not change the content inside of that class if it has no brackets. How can I do that?}
});
}
);
I'm not sure exactly what you're trying to do here given the numerous syntax problems, but you can use test in the condition to see if the regex matches anything. Also, you cannot return anything from each iteration in a $.each loop, so that is redundant.
Try this:
$("#MyArea .data-content").each(function () {
var content = $(this).html();
if (/[^[\]]+(?=])/g.test(content)) {
$(this).closest(".data-content").css('color', '#C00');
};
});
Example fiddle
In place of .css() in my example you could call your function.
I am looking for a way to wrap, with jQuery, an element into a comment, like:
<!--
<div class="my_element"></div>
-->
and also a way to remove the comments.
Is this possible?
To wrap an element with comment, or more specifically to replace an element with a comment node having that element's HTML:
my_element_jq = $('.my_element');
comment = document.createComment(my_element_jq.get(0).outerHTML);
my_element_jq.replaceWith(comment);
To switch it back:
$(comment).replaceWith(comment.nodeValue);
If you don't have the reference to the comment node then you need to traverse the DOM tree and check nodeType of each node. If its value is 8 then it is a comment.
For example:
<div id="foo">
<div>bar</div>
<!-- <div>hello world!</div> -->
<div>bar</div>
</div>
JavaScript:
// .contents() returns the children of each element in the set of matched elements,
// including text and comment nodes.
$("#foo").contents().each(function(index, node) {
if (node.nodeType == 8) {
// node is a comment
$(node).replaceWith(node.nodeValue);
}
});
You can comment the element out by doing the following:
function comment(element){
element.wrap(function() {
return '<!--' + this.outerHTML + '"-->';
});
}
DEMO:
http://jsfiddle.net/dirtyd77/THBpD/27/
I'm impresed nobody gave the following solution. The following solution require a container. This container will have inside, the commented / uncommented code.
function comment(element) {
element.html('<!--' + element.html() + '-->')
}
function uncomment(element) {
element.html(element.html().substring(4, element.html().length - 3))
}
function isCommented(element) {
return element.html().substring(0, 4) == '<!--';
}
Example: https://jsfiddle.net/ConsoleTVs/r6bm5nhz/
For wrapping?
function wrap(jQueryElement){
jQueryElement.before("<!--").after("-->");
}
Not sure how successful you'd be finding the comments once wrapped though. A text search on the body element using regular expressions is an option.
Or this - is it possible to remove an html comment from dom using jquery