How can i print the value of style attribute of an html element using javascript. I can get a specific style property value using document.getElementById('myId').style.property, where property is something like width, height etc.
However, how can I get the entire list of styles for an element?
document.getElementById('myId').style.cssText as a String, or document.getElementById('myId').style as an Object.
Edit:
As far as I can tell, this returns the "actual", inline style. On the element <a id='myId' style='font-size:inherit;'>, document.getElementById('myId').style.cssText should return "font-size:inherit;". If that is not what you want, try document.defaultView.getComputedStyle or document.getElementById('myId').currentStyle (the first one is all except IE, the second one is IE only). See here for more on computed vs. cascaded styles.
<div id="x" style="font-size:15px">a</div>
<script type="text/javascript">
function getStyle(oElm, strCssRule){
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle){
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle){
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
}
// get what style rule you want
alert(getStyle(document.getElementById('x'), 'font-size'));
</script>
Oh srsly... it's as easy as
element.style.cssText
and it's cross browser
http://jsfiddle.net/4F2RQ/
This should do a dump of the object:
Here's an Example
EDIT: Its a little weird:
for (var prop in styles) {
console.log(styles[prop], styles[styles[prop]]);
}
Related
Suppose I have the following structure:
<html>
<head></head>
<body>
<div id="myDiv"></div>
</body>
</html>
By redefining some native JavaScript functions, can I make myDiv unfindable?
For example, I can do:
window.HTMLDocument.prototype.getElementById = (function() {
var oldefinition = window.HTMLDocument.prototype.getElementById;
return function() {
var returnValue = oldefinition.apply(this, arguments);
if (returnValue && returnValue.id === 'myDiv') {
return oldefinition.call(this, 'blablabla');
} else {
return returnValue;
}
}
})();
and I can do the same for the other functions such as:
querySelector
querySelectorAll
getElementsByTagName
getElementsByClassName
etc.
This works, but the div is still available by calling:
document.body.children[0]
Then is there a way to make my div unfindable, that is, can I redefine the value of the children field?
Well, this is an attempt that seems to work okay - at least, with regards to document.body.children. I tested a variation of the following code on MDN's website to hide all script tags that are immediate children of the document body.
The way this works is we tell document.body to use a new property called children. We then return the original contents of children, minus the ones we don't want.
var oldchildren = document.body.children;
Object.defineProperty(document.body, 'children', {
get() {
var lst = [];
for (var item of oldchildren) {
if (!(item.tagName === "div" && item.id === 'myDiv'))
lst.push(item);
}
return lst;
}
});
Any code that references document.body.children after this code runs won't see the div. This code might cause other code on your site to misbehave.
Is there a way to represent this code as plain vanilla Javascript so I can better understand how it works for now?
$("#id").click(function(){
var $x = $("#id");
$x.removeProp("-webkit-animation");
});
Essentially I'm using this to tell the code not to play a css animation given that a certain set of parameters are met.
removeProp removes properties of objects. If that’s definitely what you want, the equivalent is the delete operator:
var element = document.getElementById("id");
element.addEventListener("click", function () {
delete element["-webkit-animation"];
});
If what you really want to do is change a CSS property, though, it needs to be an operation on the element’s style:
element.style.WebkitAnimation = "none";
But what you should probably do is change a class instead:
element.classList.add("no-animation");
and use CSS:
.no-animation {
-webkit-animation: none;
}
The delete element is the somewhat equivalent on vanilla javascript of removeProp()
element = document.getElementById('id');
element.onclick() = function(){
delete element['-webkit-animation'];
}
Yes, you can use the .removeAttribute() function to remove an attribute, like style, title, etc.
Or you can use .removeProperty() to remove a style property (supported in IE9 and above)
Fiddle
(function() {
var myDiv = document.getElementById('myDiv');
myDiv.removeAttribute('style');
var aDiv = document.getElementById('aDiv');
aDiv.style.removeProperty('height');
})();
<div id="aDiv" style="background-color: green;">Hi</div>
<div id="myDiv" style="background-color: green;">Hi</div>
Hope it will help OP
JS
var element = document.getElementById("id");
element.onClick = function(){
this.style.removeProperty("-webkit-animation");
};
I'm trying to find out if a specific element has an inline style attribute or not:
I'm sure there's an easy method to check this, but I can't seem to find it.
I tried multiple things already including this:
var contentWrapper = document.getElementById("contentWrapper");
if(contentWrapper.style.display.toString=="")
alert("Empty");
else
alert("Not Empty");
Thank you for your help!
if(contentWrapper.getAttribute("style")){
if(contentWrapper.getAttribute("style").indexOf("display:") != -1){
alert("Not Empty");
} else {
alert("Empty");
}
}
if(!contentWrapper.getAttribute("style"))
OR
if(contentWrapper.getAttribute("style")==null ||
contentWrapper.getAttribute("style")=="")
the above lines will work for you (anyone can be chosen).
In second solution:
first check watches if style attribute is present in the element, 2nd check ensures that style attribute is not present as an empty string e.g. <div id="contentWrapper" style="">
Complete code is given below:
var contentWrapper = document.getElementById("contentWrapper");
if(contentWrapper.getAttribute("style")==null || contentWrapper.getAttribute("style")=="")
alert("Empty");
else
alert("Not Empty");
http://jsfiddle.net/mastermindw/fjuZW/ (1st Solution)
http://jsfiddle.net/mastermindw/fjuZW/1/ (2nd Solution)
I missed #plalx's comment the first time I scanned this page.
if (element.hasAttribute("style"))
{
var styleText = element.getAttribute("style")
}
On a related note, regarding styles...
//to get info about the end results of CSS
var computedStyle = element.currentStyle || getComputedStyle(element, null);
and
//to iterate over css styles from style tags or linked CSS
for i ...
document.styleSheets[i].rules ...
//great for searching with
var elements = document.querySelectorAll(rules[i].selectorText);
The style object has a length property which tells you if the element has any inline styles or not. This also avoids the problem of having the attribute style being present but empty.
// Would be 0 if no styles are applied and > 0 if there are inline styles applied
contentWrapper.style.length
// So you can check for it like this
contentWrapper.style.length === 0
To check style attribute exist or not for given Id
if(document.getElementById("idname").hasAttribute("style")){
alert("Style attribute found");
}else{
alert("Style attribute not found");
}
I am trying to run a function that executes if a div only contains inline elements
I am not sure how to go about this short of having to list out every single block element and checking that the div doesn't contain that.
$(this).children().each(function(){
if(this.nodeName.toLowerCase() == 'p' || this.nodeName.toLowerCase() == 'h1' etc...){
check = true; //it contains block element so it is not only inline elements
return false;
}
});
Is there a better way?
Edit
To help clarify, I have a content editable div and the problem is that the user can delete all the block elements out of the div. I need to check this and add a block element to the div.
Check to see if those elements are actually block-level, as CSS can change their behavior completely:
var has_inline = $('#parent').children().filter(function() {
return $(this).css('display') !== 'block';
}).length > 0;
I'm not sure what you consider inline-block to be, so I'll just assume it behaves like an inline element for your purposes.
Demo: http://jsfiddle.net/hXckq/2/
How about has() in jQuery:
if ($(this).has("p,h1, ...")) { ... }
You could put the inline elements into a hash, then use in or hasOwnProperty:
var inline = {
"span": true,
"a": true,
...
};
if(this.nodeName.toLowerCase() in inline) {
}
Maybe try this, check if the css property of each element is indeed inline, this should work though I did not test this syntax may be incorrect:
$(this).children().each(function(){
if($(this).css('display', 'inline') == true){
return true;
}else{
return false;
}
}
I have the following HTML snippet:
<span class="target">Change me <a class="changeme" href="#">now</a></span>
I'd like to change the text node (i.e. "Change me ") inside the span from jQuery, while leaving the nested <a> tag with all attributes etc. intact. My initial huch was to use .text(...) on the span node, but as it turns out this will replace the whole inner part with the passed textual content.
I solved this with first cloning the <a> tag, then setting the new text content of <span> (which will remove the original <a> tag), and finally appending the cloned <a> tag to my <span>. This works, but feels such an overkill for a simple task like this. Btw. I can't guarantee that there will be an initial text node inside the span - it might be empty, just like:
<span class="target"><a class="changeme" href="#">now</a></span>
I did a jsfiddle too. So, what would be the neat way to do this?
Try something like:
$('a.changeme').on('click', function() {
$(this).closest('.target').contents().not(this).eq(0).replaceWith('Do it again ');
});
demo: http://jsfiddle.net/eEMGz/
ref: http://api.jquery.com/contents/
Update:
I guess I read your question wrong, and you're trying to replace the text if it's already there and inject it otherwise. For this, try:
$('a.changeme').on('click', function() {
var
$tmp = $(this).closest('.target').contents().not(this).eq(0),
dia = document.createTextNode('Do it again ');
$tmp.length > 0 ? $tmp.replaceWith(dia) : $(dia).insertBefore(this);
});
Demo: http://jsfiddle.net/eEMGz/3/
You can use .contents():
//set the new text to replace the old text
var newText = 'New Text';
//bind `click` event handler to the `.changeme` elements
$('.changeme').on('click', function () {
//iterate over the nodes in this `<span>` element
$.each($(this).parent().contents(), function () {
//if the type of this node is undefined then it's a text node and we want to replace it
if (typeof this.tagName == 'undefined') {
//to replace the node we can use `.replaceWith()`
$(this).replaceWith(newText);
}
});
});
Here is a demo: http://jsfiddle.net/jasper/PURHA/1/
Some docs for ya:
.contents(): http://api.jquery.com/contents
.replaceWith(): http://api.jquery.com/replacewith
typeof: https://developer.mozilla.org/en/JavaScript/Reference/Operators/typeof
Update
var newText = 'New Text';
$('a').on('click', function () {
$.each($(this).parent().contents(), function () {
if (typeof this.tagName == 'undefined') {
//instead of replacing this node with the replacement string, just replace it with a blank string
$(this).replaceWith('');
}
});
//then add the replacement string to the `<span>` element regardless of it's initial state
$(this).parent().prepend(newText);
});
Demo: http://jsfiddle.net/jasper/PURHA/2/
You can try this.
var $textNode, $parent;
$('.changeme').on('click', function(){
$parent = $(this).parent();
$textNode= $parent.contents().filter(function() {
return this.nodeType == 3;
});
if($textNode.length){
$textNode.replaceWith('Content changed')
}
else{
$parent.prepend('New content');
}
});
Working demo - http://jsfiddle.net/ShankarSangoli/yx5Ju/8/
You step out of jQuery because it doesn't help you to deal with text nodes. The following will remove the first child of every <span> element with class "target" if and only if it exists and is a text node.
Demo: http://jsfiddle.net/yx5Ju/11/
Code:
$('span.target').each(function() {
var firstChild = this.firstChild;
if (firstChild && firstChild.nodeType == 3) {
firstChild.data = "Do it again";
}
});
This is not a perfect example I guess, but you could use contents function.
console.log($("span.target").contents()[0].data);
You could wrap the text into a span ... but ...
try this.
http://jsfiddle.net/Y8tMk/
$(function(){
var txt = '';
$('.target').contents().each(function(){
if(this.nodeType==3){
this.textContent = 'done ';
}
});
});
You can change the native (non-jquery) data property of the object. Updated jsfiddle here: http://jsfiddle.net/elgreg/yx5Ju/2/
Something like:
$('a.changeme3').click(function(){
$('span.target3').contents().get(0).data = 'Do it again';
});
The contents() gets the innards and the get(0) gets us back to the original element and the .data is now a reference to the native js textnode. (I haven't tested this cross browser.)
This jsfiddle and answer are really just an expanded explanation of the answer to this question:
Change text-nodes text
$('a.changeme').click(function() {
var firstNode= $(this).parent().contents()[0];
if( firstNode.nodeType==3){
firstNode.nodeValue='New text';
}
})
EDIT: not sure what layout rules you need, update to test only first node, otherwise adapt as needed