Why Does an Onclick Property Set with Setattribute Fail to Work in Ie

Why does an onclick property set with setAttribute fail to work in IE?

to make this work in both FF and IE you must write both ways:


button_element.setAttribute('onclick','doSomething();'); // for FF
button_element.onclick = function() {doSomething();}; // for IE

thanks to this post.

UPDATE:
This is to demonstrate that sometimes it is necessary to use setAttribute! This method works if you need to take the original onclick attribute from the HTML and add it to the onclick event, so that it doesn't get overridden:

// get old onclick attribute
var onclick = button_element.getAttribute("onclick");

// if onclick is not a function, it's not IE7, so use setAttribute
if(typeof(onclick) != "function") {
button_element.setAttribute('onclick','doSomething();' + onclick); // for FF,IE8,Chrome

// if onclick is a function, use the IE7 method and call onclick() in the anonymous function
} else {
button_element.onclick = function() {
doSomething();
onclick();
}; // for IE7
}

javascript function working in chrome but not working in IE8

According to the first answer here -- IE not allowing onClick event on dynamically created DOM 'a' element -- IE8 does not bind click event handlers automatically when the onclick attribute of an element is changed dynamically. That is, you're setting the onclick attribute of your tag in HTML, but the browser isn't converting that attribute into an actual event handler.

Try replacing

remove.setAttribute("onclick", "Remover("+ val +")");

with

var removeFunc = function() { Remover(val) };
if (!remove.addEventListener) //Old IE
remove.attachEvent("onclick", removeFunc);
else //Other browsers
remove.addEventListener("click", removeFunc );

That actually binds the click event handler directly, rather than setting the attribute in the expectation that the browser will react by binding it.

Adding an onclick function with setAttribute()


Problem
--

"Why the following is not working? Apparently the function isn't being added!"

dev_input.setAttribute("onclick","add_device_input(event, this);");

Explanation
---

Although I haven't found a reference to this specific circumstance, I'll point out what I observed:
  • Look in Devtools F12 and you'll see that the onclick attribute is added and the value as well. Although it is there and syntactically correct, it doesn't function. See section Demo - Source: #btn3

  • If the same attribute and value is added via JavaScript as a property it works, as a property. An attribute will not show up in markup, whilst a property does not. For all intents and purposes, the onclick property and onclick attribute is one and the same/sup>.

  • This behavior is is standard with jQuery methods attr() and prop(). As an example I see this frequently:

    $(":checkbox").prop("checked", true);

    $(":checkbox").attr("checked", true);


Event Handling
----

Events are registered to either an element within the DOM or browser related Non-DOM Object like Window. There are 3 types of event registration:
  1. On-event Attribute: Old as dirt and discouraged and frowned upon by the web developing community in general. This is the type of event handler the OP code was trying to create programmatically with setAttribute() method. It appears that an on event is beyond the reach of set/get/removeAttribute() methods and most likely jQuery method attr() as well (untested and not that curious). See Section: Demo - Source: #btn0

    <button onclick="funcName(event)">Discouraged</button>

2. ⭐ **On-event Property:** This is event handling is old and looked down upon as well but because it's limited compared to its predecessor *Event Listener*. **An onclick property and onclick attribute are one and the same as far as DOM elements are concerned. Use this and not `setAttribute()`.** ***See section Demo - Source: `#btn1`***

document.getElementById('id').onclick = funcName;


3. **Event Listener:** This type of event handling employs the methods `add/removeEventListener("event", funcName)` and is the most standard, current, and preferred way. ***See section Demo - Source: `#btn2`***

document.getElementById('id').addEventListener("event", funcName);


For details why the first 2 types of event handling are reviled, read **[DOM on-event handlers][1]** for the technical reasons and this **[Reddit article][2]** for development and design oriented reasons. I'm personally ambivalent about the subject because on-event handlers aren't deprecated and concepts such as separation of presentation, behavior, structure, semantics, etc. are not as important as they were before.

##Solution


Other than using an On-event Property/sup> we can parse a htmlString of the entire element with the onclick attribute. This can be done using:

  • innerHTML overwrites content

OR

  • **insertAdjacentHTML()** doesn't overwrite content; flexible; fast

### See section: Demo - source: #btn4 /p>

var htmlString = `<button onclick="funcName(event, this)">4</button>`

document.querySelector('${selectorOfTarget}').insertAdjacentHTML("${position}", htmlString);
  • "selelectorOfTarget": A CSS string that represents the DOM element we wish to insert an htmlString into or around.
  • "div".......: <div id="ID" class="CLASS"></div>
  • "#ID".......: <div id="ID" class="CLASS"></div>
  • ".CLASS"....: <div id="ID" class="CLASS"></div>
  • #ID + ul....: <div id="ID" class="CLASS"></div>
    <ul></ul>
  • #ID + ul li.: <div id="ID" class="CLASS"></div>
    <ul><li></li></ul>

* ***"position":*** A string that determines where the htmlSting will be inseted in relation to the target element:
    <!--"beforebegin"-->
<ul>
<!--"afterbegin"-->
<li>ITEM</li>
<li>ITEM</li>
<li>ITEM</li>
<!--"beforeend"-->
</ul>
<!--"afterend"-->

* ***htmlString:*** A String that literally represents HTML. Instead of using String Literals, use **[Template Literals][4]**:

String Literal

    '<div id="'+ID+'" class="'+CLASS+'">+CONTENT+</div>'

Template Literal

    `<div id="${ID}" class="${CLASS}">${CONTENT}</div>`

/sup>(See section: **Event Handling** - list item: 2. **On-event Property** and section: **Demo** - source: `#btn1`.)

##Demo

var htmlString = `<button id='btn4' onclick='showHide(event)'>4</button>
<div class='content hide'>
<h4>Dynamically Registered On Event Attribute by Parsing htmlString</h4>
<pre><code>
document.querySelector('#btn3+div+hr').insertAdjacentHTML('afterend', htmlString);
</code></pre>
</div>
<hr>`;

function showHide(event) {
var tgt = event.target;
if (tgt.tagName === "BUTTON") {
var code = tgt.nextElementSibling;
code.classList.toggle('hide');
}
return false;
}

//#btn1
//On-Event Property
document.getElementById('btn1').onclick = showHide;

//#btn2
//EventListener
document.getElementById('btn2').addEventListener('click', showHide);

//#btn3
//Dynamically registered On event Attribute by setAttribute() method.
document.getElementById('btn3').setAttribute('onclick', "showHide(event, this)");

//#btn4
//Dynamically Registered On Event Attribute by Parsing htmlString
document.querySelector('#btn3+div+hr').insertAdjacentHTML('afterend', htmlString);
* {
margin: 0;
padding: 0
}

button {
padding: 2px 5px;
}

button+div {
opacity: 1;
transition: opacity 1s ease;
}
.content {
margin: 0 0 20px 0
}
button+div.hide {
opacity: 0;
transition: 1s ease;
}
code {
background: #000;
color: lime;
}
<!--#btn0-->
<button id='btn0' onclick="showHide(event, this)">0</button>
<div class='content hide'>
<h4>On-Event Attribute</h4>
<pre><code>
<button id='btn0' onclick="showHide(event, this)">On-Event Attribute</button>
</code></pre>
</div>
<hr>

<!--#btn1-->
<button id="btn1">1</button>
<div class='content hide'>
<h4>On-Event Property</h4>
<pre><code>
document.getElementById('btn1').onclick = showHide;
</code></pre>
</div>
<hr>

<!--#btn2-->
<button id='btn2'>2</button>
<div class='content hide'>
<h4>EventListener</h4>
<pre><code>
document.getElementById('btn2').addEventListener('click', showHide);
</code></pre>
</div>
<hr>

<!--#btn3-->
<button id='btn3'><del>3</del></button>
<div class='content'>
<h4>Dynamically Registered On Event Attribute by <code>setAttribute()</code> method <b>FAILED</b></h4>
<pre><code>
<del>document.getElementById('btn3').setAttribute('onclick', 'showHide(event)');</del>
</code></pre>
</div>
<hr>

<!--#btn4 is dynamically created and will be inserted here-->
<!--Selector: '#btn3+div+hr' || Position: 'afterend'-->

Problems with JavaScript in IE

IE has an issue with the setAttribute function and event handlers. (Read here.) Use the onclick property in addition to setAttribute.

buttonnode.setAttribute('onclick','removeValue(this)');
buttonnode.onclick = function() { removeValue(buttonnode); };

Why is this onclick button not working, in javascript

In you scripts.js file you can replace the following code

function myFunction(elmnt,clr) {
elmnt.style.color = clr;
}

td.setAttribute("onclick", "random(element, red)")

by

function random(elmnt,clr) {
elmnt.style.color = clr;
}

document.querySelectorAll('td').forEach(function(td) {
td.setAttribute("onclick", "random(this, 'red')")
});

There were few mistakes in the code.

td.setAttribute("onclick", "random(element, red)")
  1. td is not defined.
  2. random is not defined
  3. element is not defined
  4. red is not defined

You can fix those by:
First select all the tds using the document.querySelectorAll function, then loop through the result. And then in the loop replace random(element, red) by random(this, 'red'). You see the this is a reference to the clicked td and red is wrapped in quotes.
And lastly you have to fix the function declaration. function myFunction(elmnt,clr) { to function random(elmnt,clr) {

Change onclick event

Try

document.getElementById("back").addEventListener("click", function(){
window.location.href='../../';
});

HTML changes with element.setAttribute(onclick,alert('Test');) and element.onclick = alert('Test');;

Yes. setAttribute adds an attribute to an Element DOM node. For the onclick attribute, there is a side effect under the covers of also adding an onclick event handler, which is made by 'compiling' the attribute value into a javascript function.

Assigning a function to the onclick property of the element directly does attach the handler, but does not automatically add an attribute to the DOM node.

Now it is possible that there are browsers that do not make the distinction between adding the attribute and attaching the handler directy. But keep in mind that although modifying the document may create scriptable objects as side effect, the reverse does not have to be the case: programmatically creating DOM structures may or may not change the HTML underlying the document according to the browser you happen to be using.

Javascript: Receiving onClick on top of image inside a div, can it be done?

Rather than overwriting the innerHTML of the div, why not do something like this?

var img = document.createElement('img');
img.setAttribute('src', myImage);
img.setAttribute('width', myDiv.width);
img.setAttribute('height', myDiv.height);
myDiv.appendChild(img);

Internet Explorer 7 onclick event on submit button does not fire

IE7 has a lot of compatibility issues, of which this is just one. If you're writing javascript that needs to be compatible with IE7, you will end up writing a lot of redundant code that does the same thing in two different ways to cater for different browsers you're supporting.

Issues like this in old browsers are precicely the reason why libraries like jQuery exist. jQuery does a lot of things, but one thing it does very well is iron out many of these nasty little quirks that crop up when writing cross-browser javascript.

The cross-browser issues have become less important in recent years, as modern browsers (including IE) have much better standards support, but if you're supporting old browsers , and old IE versions in particular, my recommendation is to use jQuery (or a similar library), because they have already solved this problem, and plenty of others that will catch you out.

If you do use jQuery, your code will become:

$(element).click(function() {alert('test');});

Before anyone points it out, yes I know the OP didn't specify jQuery in the question, and may not want a jQuery answer, but in this case I would say it is the best answer available, because if you don't use it, you will end up having to write much of the same compatibility code yourself that is already in jQuery.



Related Topics



Leave a reply



Submit