I need to check the display property of a header element on the page. Based on it different operations are to be done. I tried using
document.getElementsByTagName('header')[0].style.display
and comparing it to various display attributes, but this is executing false part whatever property I check for.
Here is my html :
<body>
<header id="main">
<p>Test to find the display property of an element (header in this case).</p>
</header>
</body>
And here is my Javascript :
var test1 = document.createElement('div');
var test2 = document.createElement('div');
test1.innerText = 'Testing for block : ';
test2.innerText = 'Testing for none : ';
var body = document.getElementById('main');
if (document.getElementsByTagName('header')[0].style.display == 'block') {
test1.innerText = test1.innerText + 'true part is executed';
body.appendChild(test1);
} else {
test1.innerText = test1.innerText + 'false part is executed';
body.appendChild(test1);
}
if (document.getElementsByTagName('header')[0].style.display == 'none') {
test2.innerText = test2.innerText + 'true part is executed';
body.appendChild(test2);
} else {
test2.innerText = test2.innerText + 'false part is executed';
body.appendChild(test2);
}
I put this also on jsfiddle http://jsfiddle.net/n8zDc/1/
What am I doing wrong ?
You want to use window.getComputedStyle. You haven't defined a display property value anywhere in the DOM
var header = document.getElementById('main');
var style = window.getComputedStyle(header);
console.log(style.display);
The reason is that .style doesn't really compute which style is actually applied to the element, but simply the style attribute on the DOM (either the HTML, or applied through JavaScript). As an example, consider this CSS:
* {
float: right;
}
.foo {
float: left;
}
And HTML:
<div>Foo</div>
<div class='foo'>Bar</div>
Neither of these have any style values in them, yet their computed styles will have a bunch of values, browser defaults such as display: block, and the CSS rules applied to them.
Related
I am currently using the following script to echo visible text on the screen...
<h1 id="MyText"></h1>
<script>
var el = document.getElementById('MyText');
{ if (italian || french || german)
{ el.innerHTML = (
(italian && 'ciao') ||
(french && 'salut') ||
(german && 'hallo') ); }
else { el.innerHTML = 'hello';}
}
</script>
How should I edit this script, to make it work in case I want it to type a non visible word in the html?
Example:
In CSS I have:
#ciao{height:350px;}
#salut{height:10px;}
#hallo{height:3000px;}
In my code I want to define my table height basing on these conditions:
<div id="MyText">
The problem is with the above code, this will result in printing a visible text, instead of rather choosing the css id. So how am I supposed to edit the script?
It is more idiomatic to add an appropriate class to the div element. [edit] it appears as though you are looking to set the class based on the contents of the div. This is generally a difficult thing to do but here is one approach. Another would be to set a property of the div and then do a :before hack to create a pseudo element with the text of the property.
const langauges = {
"ciao":"italian",
"salut":"french",
"hallo":"german",
"hello":"english"
}
const updateClass = (el)=>{
if(langauges[el.innerHTML] != undefined){
el.className = langauges[el.innerHTML];
}
}
const onChange = (event)=>{
const el = event.target;
updateClass(el);
}
var el = document.getElementById('MyText');
el.addEventListener("input",onChange,false);
updateClass(el);
.italian{height:350px; color:blue;}
.french{height:10px; color:red;}
.german{height:3000px; color:yellow;}
.english{height:3000px; color:purple;}
<h1 id="MyText" contenteditable="true">ciao</h1>
I'm stuck on how to get number of all elements that has inline style.
var galleryElements = document.getElementsByClassName("popup-gallery")[0].children;
$('.myButton').click(function() {
var totalItems = galleryElements.length;
var itemsWithStyle = ($(galleryElements).css('display') == 'inline').length;
if (totalItems == itemsWithStyle){
/* do something */
}
});
Say I have a NodeList of the children of some div, i.e.
const div = document.querySelector('#target');
const children = div.children;
If I want to get the number of children with the display attribute set to inline, then I can iterate through children and increment a counter each time I encounter a child element with the display attribute set to inline.
For example:
let count = 0;
for (let child of children) {
if (child.style.display === 'inline') count++;
}
Where count represents the number of child elements of the parent div that have a display attribute set to inline.
this is without jquery
You can check this out for starters:
https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
basic
<h1 id="hello">index.html</h1>
<-- css -->
#hello {display: inline;}
// js
const title = document.getElementById('hello');
let res = window.getComputedStyle(title)
let count = 0;
if(res.getPropertyValue('display') === 'inline') {
console.log('yes')
count ++;
console.log(count)
// 1
}
what I learned:
" The object from getComputedStyle is read-only, and should be used to inspect the element's style — including those set by a element or an external stylesheet.
The element.style object should be used to set styles on that element, or inspect styles directly added to it from JavaScript manipulation or the global style attribute."
You are in fact checking if all gallery elements are display: inline, so you can simplify your code a bit:
const $galleryElements = $('.popup-gallery').first().children();
$('.myButton').click(function() {
const areAllInline = $galleryElements.filter(function () {
$(this).css('display') !== 'inline';
}).length === 0;
if (areAllInline) {
/* do something */
}
});
If there are no elements with display different than inline, you're good to go.
This will give you a tally of both inline (including inline-block) and other. If there is a class associated with the element, it will report back that as well.
$('.myButton').click(function() {
let inline = [], block = []
$('.popup-gallery *').each(function() {
let tg = $(this).prop('tagName').toLowerCase()
if ($(this).attr('class')) tg += "." + $(this).attr('class');
if (['inline','inline-block'].includes($(this).css('display'))) inline.push(tg)
else block.push(tg)
})
console.log('inline',inline)
console.log('not-inline',block)
console.log('inline/total',inline.length + "/" + (inline.length + block.length))
console.log('has inline elements?',inline.length>0)
});
.special{
display:inline;
}
.special-ib{
display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='popup-gallery'>
<div>A div
<ul>
<li>li list - <i>italics...</i></li>
</ul>
</div>
<div class='special'>inline div</div>
<div class='special-ib'>inline-block div</div>
<p>paragraph</p>
<span>span, <dd>dd</dd></span>
</div>
<button class='myButton'>Click me </button>
These answers are good, however I feel it is even easier than how others are solving this problem.
console.log(
[...document.querySelectorAll(".popup-gallery")]
.filter(element =>
"inline" ==
window.getComputedStyle(element)
.getPropertyValue("display")
).length
);
I have a simple function to change the innerHTML of a span element.
here is the code :
function changeElementAnswered() {
var dataq = this.getAttribute('data-num');
var ele = document.getElementById('qp-' + dataq);
if(ele){
if(this.value != ""){
ele.className = 'qp-item qp-item-answered';
} else {
ele.className = 'qp-item qp-item-unanswered';
}
var cele = document.getElementById('revq-' + dataq);
if(cele) {
cele.innerHTML = this.value.toString();
alert(cele.innerHTML);
}
}
}
and this is the HTML code :
<span class="test-answer-rev" data-num="1" id="revq-1"></span>
I successfully update the inner html of the span class. the alert function shows the correct answer but the problem is that the HTML code (of the current instance) does not get updated (can't see changes in Developer mode). What am i missing here ?
-- Already tried .textContent is doesn't work
Update 1 : I use the span in a popup which means the parent div is hidden (display:none;)
innerHTML will make changes for the current instance of the web page only. It wont change the original HTML code in your file. If you go to developer tools and look at the HTML it will be changed, but you cannot manipulate the source file using innerHTML.
function changeElementAnswered(e) {
var dataq = e.getAttribute('data-num');
var ele = document.getElementById('qp-' + dataq);
if(ele){
if(ele.value != ""){
ele.className = 'qp-item qp-item-answered';
} else {
ele.className = 'qp-item qp-item-unanswered';
}
var cele = document.getElementById('revq-' + dataq);
if(cele) {
cele.innerHTML = ele.value.toString();
alert(cele.innerHTML);
}
}
}
<span class="test-answer-rev" onclick="changeElementAnswered(this)" data-num="1" id="revq-1">gg</span>
<input value="a" id="qp-1">
In my if/else statement, instead of having:
todoTextWithCompletion = '(x) ' + todo.todoText;
I want to display a strike string (todo.todoText input) in the DOM. I've tried replacing it to
todoTextWithCompletion = todo.todoText.strike();
But it's displaying <strike>todo.todoText</strike> in the DOM.
displayTodos: function () {
var todosUl = document.querySelector('ul');
todosUl.innerHTML = '';
todoList.todos.forEach(function (todo, position) {
var todoLi = document.createElement('li');
var todoTextWithCompletion = '';
if (todo.completed === true) {
todoTextWithCompletion = '(x) ' + todo.todoText;
} else {
todoTextWithCompletion = '( ) ' + todo.todoText;
}
todoLi.id = position;
todoLi.textContent = todoTextWithCompletion;
todoLi.appendChild(this.createToggleButton());
todoLi.appendChild(this.createDeleteButton());
todosUl.appendChild(todoLi);
}, this);
},
You can also style your text content using JavaScript.
Assuming todoLi is the element you want to strike-through:
todoLi.style.textDecoration = "line-through";
Using the new CSS Typed Object Model, this will be:
todoLi.attributeStyleMap.set('text-decoration', 'line-through');
Both will have the same effect as if you're applying the text-decoration: line-through; property using CSS.
Also keep in mind that The <strike> tag is not supported in HTML5.
Use <del> or <s> instead.
You are setting textContent to an HTML string. textContent is not parsed as HTML, it is added as plain text:
Differences from innerHTML
Element.innerHTML returns HTML as its name indicates. Sometimes people
use innerHTML to retrieve or write text inside an element. textContent
has better performance because its value is not parsed as HTML.
Moreover, using textContent can prevent XSS attacks.
Instead, you should construct the <strike> node using document.createElement("strike");, use innerHTML, or as U-ways suggested, add the text-decoration: line-through CSS style.
document.getElementById("text-content").textContent = "<strike>foo</strike>"
document.getElementById("inner-html").innerHTML = "<strike>foo</strike>"
<div id="text-content"></div>
<div id="inner-html"></div>
Rather than adding a raw style to the element, you can add a class using the classList API:
CSS
.item-completed {
text-decoration: line-through;
}
Javascript
var todoLi = document.createElement('li');
if (todo.completed === true) {
todoLi.classList.add('item-completed');
}
No idea where the problem lies, tried various things and I'm not having any luck. I've done this successfully before in the past but now it won't work, any help would be great...
HTML snippet:
<tr>
<td class="tableContent noBorderSides paddingAll"><img class="imgResize" src="images/emptyCircle.png" onclick="expandItem()"/>
<div id="Expand" class="hiddenDiv">
HELLO?
</div>
JavaScript:
function expandItem() {
if (document.getElementById("Expand").style.display == 'block') {
document.getElementById("Expand").style.display = 'none';
}
else if (document.getElementById("Expand").style.display == 'none') {
document.getElementById("Expand").style.display = 'block';
}
}
CSS:
.hiddenDiv {
display: none;
}
What am I doing wrong?
The initial display that is set in your CSS won't be reachable from the .style property.
Do it like this:
function expandItem() {
var expand = document.getElementById("Expand");
if (expand.style.display == '') {
expand.style.display = 'block';
}
else if (expand.style.display == 'block') {
expand.style.display = '';
}
}
Or a little shorter like this:
function expandItem() {
var expand = document.getElementById("Expand");
expand.style.display = (expand.style.display == '') ? 'none' : '';
}
Use .getComputedStyle() to get any style attributes associated with a given element. Notice, that the object returned is read only, so you'll want to use this for the initial if statement, and then set the style as you were doing above.
You could just remove the class from the element that defines the hidden property and add when you want to hide:
if (document.getElementById("Expand").className == '') {
document.getElementById("Expand").className = 'hiddenDiv';
}
else if (document.getElementById("Expand").className == 'hiddenDiv') {
document.getElementById("Expand").className = '';
}
Do note that if you have other classes on that element you will need to do a little string manip rather than just a straight check and remove.
//Temporary solution
//Replace your javascript code with following code
if (document.getElementById("Expand").style.display == 'block') {
document.getElementById("Expand").style.display = 'none';
}
else{
document.getElementById("Expand").style.display = 'block';
}
//Note :- Javascript detect '' (empty) when it try to search display property for expand block
#user1689607's answer is right if you need to just use javascript. If you have access to jQuery you can do it like so
$("#Expand").toggle();
And a simple jsfiddle to demonstrate: http://jsfiddle.net/P36YA/