This question already has answers here:
setAttribute is not working for 'style' attribute on IE
(6 answers)
Closed 9 years ago.
document.getElementById(...).setAttribute('style',... is not working in Internet Explorer 7.0. How can I make this work in Internet Explorer?
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
var myarray=new Array(3);
for (i=0; i <1000; i++){
myarray[i]=new Array(3);
}
myarray[0][0]="new"; myarray[0][1]="old";
function swapText(id){
document.getElementById('id' + id).setAttribute('style', 'font-weight: bold; color: red; font-size:150%;');
document.getElementById('id'+ id).innerHTML = myarray[id][0];
}
function originalText(id){
document.getElementById('id' + id).setAttribute('style', 'color:' + 'black' + ';');
document.getElementById('id' + id).innerHTML = myarray[id][1];
}
</script>
</head>
<body>
<div id="scoreboard" border='1'> </div>
<div id="qa">
<div id="col1" class="column">
<div id="id0" onmouseover="swapText(0)"; onmouseout="originalText(0)">old</div>
</div>
</div>
</body>
</html>
Using setAttribute is unreliable if you want the change to be reflected in the document. Use Element.style instead:
var el = document.getElementById('id' + id);
el.style.fontWeight = 'bold';
el.style.color = 'red';
el.style.fontSize = '150%';
and suchlike.
Use jQuery.
jQuery is a very powerful JavaScript library that lets you do almost anything with very little code. One of its main advantages (except for its beautiful syntax) is that it is specifically designed to be platform- and browser-independent, so you shouldn't have to worry about any of that anymore.
Doing the same thing you do now, but in jQuery, could look something like this:
function swapText(id) {
$('#id' + id)
.css('font-weight','bold').css('color','red').css('font-size','150%')
.html(myarray[id][0]);
}
function originalText(id) {
$('#id' + id).css('color','black').html(myarray[id][1]);
}
Of course, if you define a CSS class for your "swapped" style, you could simply use $('#id'+id).addClass('swapped'); and $('#id'+id).removeClass('swapped');.
Also, there are really nice ways to hook up events, so you don't even need to define the functions with names if you don't want to:
$('div').hover(function() {
$(this)
.css('font-weight','bold').css('color','red').css('font-size','150%')
.html(myarray[id][0]);
},
function() {
$('#id' + id).css('color','black').html(myarray[id][1]);
});
From MSDN: This attribute is not accessible through scripting. To access styles through scripting, use the style object
you can use setAttribute that is also compatible with IE-8 and IE-7
var el = document.getElementById('id' + id);
el.setAttribute('fontWeight','bold');
el.setAttribute('color','red');
el.setAttribute('fontSize','150%');
for assigning a class to an element, i suggest following
el.className = "class-name";
Related
Javascript createElement() is not working in Chrome but it works in IE and Firefox fine. Why?
It's working perfectly, use this code:
var catDiv = document.createElement("div");
catDiv.innerHTML = "Test";
document.body.appendChild(catDiv);
Another working example (if you have an element with Id = myTableBody in your HTML)
var appendingTo = document.getElementById("myTableBody");
var tr = document.createElement("tr");
tr.setAttribute("name", "i");
appendingTo.appendChild(tr);
var name = document.createElement("Div" );
will work. And later you can add the attributes like
name.colSpan="2";
document.body.appendChild(name);
Note: don't try to use angular brackets like createElement("<div />").
It will not work in Chrome.
Edit: syntax issue in above code fixed. there should be a dot instead of comma.
Beacause your code is messed up, there's nothing wrong with "createElement":
<html>
<head>
<meta charset = "utf-8">
<title></title>
<script>
window.onload = function () {
for (var i = 0; i < 100; i ++) {
var div = document.createElement ("div");
div.style.border = "1px solid black";
div.style.margin = "20px";
div.style.padding = "10px";
document.body.appendChild (div);
}
}
</script>
<style></style>
</head>
<body></body>
</html>
So I also couldn't get createElement() to work in chrome. After reading Caio's post and testing the code provided I figured out what I was doing wrong.
On w3schools.com the examples they provide always use the tag name in all caps ex. createElement("DIV"), which is the way I was using it and with poor results.
After changing from "DIV" to "div" in my own code it instantly worked.
Thanks Caio.
I made a function that overwrite the the :hover of some elements on a page. It fades between the normal and the :hover effect. That for i had to create a .hover class in my CSS file. I think this is a little unclean. How could i read the the :hover pseudo class contents?
Using getComputedStyle as on the accepted answer won't work, because:
The computed style for the hover state is only available when the element is actually on that state.
The second parameter to getComputedStyle should be empty or a pseudo-element. It doesn't work with :hover because it's a pseudo-class.
Here is an alternative solution:
function getCssPropertyForRule(rule, prop) {
var sheets = document.styleSheets;
var slen = sheets.length;
for(var i=0; i<slen; i++) {
var rules = document.styleSheets[i].cssRules;
var rlen = rules.length;
for(var j=0; j<rlen; j++) {
if(rules[j].selectorText == rule) {
return rules[j].style[prop];
}
}
}
}
// Get the "color" value defined on a "div:hover" rule,
// and output it to the console
console.log(getCssPropertyForRule('div:hover', 'color'));
Demo
You could access document.styleSheets and look for a rule that is applied on that specific element. But that’s not any cleaner than using a simple additional class.
UPDATE: I somehow got this wrong. The below example doesn't work. See #bfavaretto's comment for an explanation.
In Firefox, Opera and Chrome or any other browser that correctly implements window.getComputedStyle is very simple. You just have to pass "hover" as the second argument:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
div {
display: block;
width: 200px;
height: 200px;
background: red;
}
div:hover {
background: green;
}
</style>
</head>
<body>
<div></div>
<script type="text/javascript">
window.onload = function () {
var div = document.getElementsByTagName("div")[0];
var style = window.getComputedStyle(div, "hover");
alert(style.backgroundColor);
};
</script>
</body>
</html>
But I don't believe there's yet a solution for Internet Explorer, except for using document.styleSheets as Gumbo suggested. But there will be differences. So, having a .hover class is the best solution so far. Not unclean at all.
If there are any people here who use the questions accepted answer but it won't work, here's a nice function that might:
function getPseudoStyle(id, style) {
var all = document.getElementsByTagName("*");
for (var i=0, max=all.length; i < max; i++) {
var targetrule = "";
if (all[i].id === id) {
if(all[i].selectorText.toLowerCase()== id + ":" + style) { //example. find "a:hover" rule
targetrule=myrules[i]
}
}
return targetrule;
}
}
There is an alterantive way to get :hover pseudo class with javascript. You can write your styles of hover pseudo class in a content property.
p::before,
p::after{
content: 'background-color: blue; color:blue; font-size: 14px;';
}
then read from it via getComputedStyle() method:
console.log(getComputedStyle(document.querySelector('p'),':before').getPropertyValue('content'));
All that I have read says to use the element.onclick property, but that doesn't seem to be working in my situation. I'm trying to parse the number: 629216818 and set it to a varialbe: fbid. This is a Greasemonkey script, so the HTML can't be edited directly. I'm no pro, so I may be just doing something stupid, but here is my HTML and Javascript:
<div id="petRightContainer">
<a title = "Pet trainer bonus: Your companion will level 5% faster." href="setup.php?type=companion>Random=8167343321487308">
<div class="petRight" style="background-image:url(/fb/res/gui4/companion/cu_sith.jpg)"></div>
</a>
<div class="petRightLevel">
Dog
</div>
etc.
<script type="text/javascript">
fbid = 0;
fbidRegex = /\d{3,}(?=&fromWall=1)/;
if ( document.getElementsByClassName("petRightLevel")[0]){
element = document.getElementsByClassName("petRightLevel")[0].firstChild;
codeStore = element.onclick;
fbid = fbidRegex.exec(codeStore);
document.write("it is working ");
}
document.write(fbid);
</script>
The problem is in this line:
element = document.getElementsByClassName("petRightLevel")[0].firstChild;
If you are using Firefox and other browsers which support document.getElementsByClassName and in your HTML, there are spaces between <div class="petRightLevel"> and
<a href="#" onClick= ...>
, the firstChild is actually a text node not the link. All you need to do is remove the spaces and/or line break in between the two elements.
If you are using IE, the problem is still at the same line of the javascript because IE doesn't support document.getElementsByClassName up until version 8.
Update: The following javascript code work for all the browsers I tested without touching HTML:
<script type="text/javascript">
fbid = 0;
fbidRegex = /\d{3,}(?=&fromWall=1)/;
var divs = document.getElementsByTagName("div");
var link = null;
for (var i=0;i<divs.length;i++)
{
if(divs[i].getAttribute("class") ==="petRightLevel")
{
link = divs[i].getElementsByTagName("a")[0];
break;
}
}
if (link){
codeStore = link.onclick;
fbid = fbidRegex.exec(codeStore);
document.write("it is working ");
}
document.write(fbid);
</script>
If you only need to get the anchors, it would be much simpler than this.
I think this might work for you.
<script type="text/javascript">
fbid = 0;
fbidRegex = /\d{3,}(?=&fromWall=1)/;
if(document.getElementsByClassName("petRightLevel")[0]){
element = document.getElementsByClassName("petRightLevel")[0].firstChild;
// callback function to execute when the element onclick event occurs.
codeStore = element.onclick = function(){
fbid = fbidRegex.exec(codeStore);
document.write("it is working ");
document.write(fbid);
}
}
</script>
Here's a very basic question: why is the finishLoading() function in the code below not able to access the 'opacity' property for the #myStyle CSS selector? The alert doesn't display anything, and I've verified that the 'opacity' property is 'false'.
Thanks very much!
<html>
<head>
<style type="text/css">
<!--
#myStyle
{
opacity: 0.50;
}
-->
</style>
<script type="text/javascript">
<!--
function finishedLoading()
{
alert(document.getElementById('myStyle').style.opacity);
}
-->
</script>
</head>
<body onload="finishedLoading();">
<div id="myStyle">
hello
</div>
</body>
</html>
You can get the values set through class only after their computation.
var oElm = document.getElementById ( "myStyle" );
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle)
{
strValue = document.defaultView.getComputedStyle(oElm, null).getPropertyValue("-moz-opacity");
}
else if(oElm.currentStyle) // For IE
{
strValue = oElm.currentStyle["opacity"];
}
alert ( strValue );
The problem is, that element.style.opacity only stores values, that are set inside the element's style attribute. If you want to access style values, that come from other stylesheets, take a look at quirksmode.
Cheers,
I suggest you take a look at jQuery and some of the posts at Learning jQuery, it will make doing things like this very easy.
Opacity should be a number rather than a boolean. Is it working in any other browseR?
this link help
http://www.quirksmode.org/js/opacity.html
function setOpacity(value) {
testObj.style.opacity = value/10;
testObj.style.filter = 'alpha(opacity=' + value*10 + ')';
}
opacity is for Mozilla and Safari, filter for Explorer. value ranges from 0 to 10.
I'm working on a web page where I'm making an AJAX call that returns a chunk of HTML like:
<div>
<!-- some html -->
<script type="text/javascript">
/** some javascript */
</script>
</div>
I'm inserting the whole thing into the DOM, but the JavaScript isn't being run. Is there a way to run it?
Some details: I can't control what's in the script block (so I can't change it to a function that could be called), I just need the whole block to be executed. I can't call eval on the response because the JavaScript is within a larger block of HTML. I could do some kind of regex to separate out the JavaScript and then call eval on it, but that's pretty yucky. Anyone know a better way?
Script added by setting the innerHTML property of an element doesn't get executed. Try creating a new div, setting its innerHTML, then adding this new div to the DOM. For example:
<html>
<head>
<script type='text/javascript'>
function addScript()
{
var str = "<script>alert('i am here');<\/script>";
var newdiv = document.createElement('div');
newdiv.innerHTML = str;
document.getElementById('target').appendChild(newdiv);
}
</script>
</head>
<body>
<input type="button" value="add script" onclick="addScript()"/>
<div>hello world</div>
<div id="target"></div>
</body>
</html>
You don't have to use regex if you are using the response to fill a div or something. You can use getElementsByTagName.
div.innerHTML = response;
var scripts = div.getElementsByTagName('script');
for (var ix = 0; ix < scripts.length; ix++) {
eval(scripts[ix].text);
}
While the accepted answer from #Ed. does not work on current versions of Firefox, Google Chrome or Safari browsers I managed to adept his example in order to invoke dynamically added scripts.
The necessary changes are only in the way scripts are added to DOM. Instead of adding it as innerHTML the trick was to create a new script element and add the actual script content as innerHTML to the created element and then append the script element to the actual target.
<html>
<head>
<script type='text/javascript'>
function addScript()
{
var newdiv = document.createElement('div');
var p = document.createElement('p');
p.innerHTML = "Dynamically added text";
newdiv.appendChild(p);
var script = document.createElement('script');
script.innerHTML = "alert('i am here');";
newdiv.appendChild(script);
document.getElementById('target').appendChild(newdiv);
}
</script>
</head>
<body>
<input type="button" value="add script" onclick="addScript()"/>
<div>hello world</div>
<div id="target"></div>
</body>
</html>
This works for me on Firefox 42, Google Chrome 48 and Safari 9.0.3
An alternative is to not just dump the return from the Ajax call into the DOM using InnerHTML.
You can insert each node dynamically, and then the script will run.
Otherwise, the browser just assumes you are inserting a text node, and ignores the scripts.
Using Eval is rather evil, because it requires another instance of the Javascript VM to be fired up and JIT the passed string.
The best method would probably be to identify and eval the contents of the script block directly via the DOM.
I would be careful though.. if you are implementing this to overcome a limitation of some off site call you are opening up a security hole.
Whatever you implement could be exploited for XSS.
You can use one of the popular Ajax libraries that do this for you natively. I like Prototype. You can just add evalScripts:true as part of your Ajax call and it happens automagically.
For those who like to live dangerously:
// This is the HTML with script element(s) we want to inject
var newHtml = '<b>After!</b>\r\n<' +
'script>\r\nchangeColorEverySecond();\r\n</' +
'script>';
// Here, we separate the script tags from the non-script HTML
var parts = separateScriptElementsFromHtml(newHtml);
function separateScriptElementsFromHtml(fullHtmlString) {
var inner = [], outer = [], m;
while (m = /<script>([^<]*)<\/script>/gi.exec(fullHtmlString)) {
outer.push(fullHtmlString.substr(0, m.index));
inner.push(m[1]);
fullHtmlString = fullHtmlString.substr(m.index + m[0].length);
}
outer.push(fullHtmlString);
return {
html: outer.join('\r\n'),
js: inner.join('\r\n')
};
}
// In 2 seconds, inject the new HTML, and run the JS
setTimeout(function(){
document.getElementsByTagName('P')[0].innerHTML = parts.html;
eval(parts.js);
}, 2000);
// This is the function inside the script tag
function changeColorEverySecond() {
document.getElementsByTagName('p')[0].style.color = getRandomColor();
setTimeout(changeColorEverySecond, 1000);
}
// Here is a fun fun function copied from:
// https://stackoverflow.com/a/1484514/2413712
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
<p>Before</p>