I am trying to set the onclick event using javascript. The following code works:
var link = document.createElement('a');
link.setAttribute('href', "#");
link.setAttribute('onclick', "alert('click')");
I then use appendChild to add link to the rest of the document.
But I obviously would like a more complicated callback than alert, so I tried this:
link.onclick = function() {alert('clicked');};
and this:
link.onclick = (function() {alert('clicked');});
But that does nothing. When I click the link, nothing happens. I have testing using chrome and browsing the DOM object shows me for that element that the onclick attribute is NULL.
Why am I not able to pass a function into onclick?
EDIT:
I tried using addEventListener as suggested below with the same results. The DOM for the link shows onclick as null.
My problem may be that the DOM for this element might not have been fully built yet. At this point the page has been loaded and the user clicks a button. The button executes javascript that builds up a new div that it appends to the page by calling document.body.appendChild. This link is a member of the new div. If this is my problem, how do I work around it?
I have been unable to reproduce the problem. Contrary to the OP's findings, the line below works fine on the latest versions of IE, FF, Opera, Chrome and Safari.
link.onclick = function() {alert('clicked');};
You can visit this jsFiddle to test on your own browser:
http://jsfiddle.net/6MjgB/7/
Assuning we have this in the html page:
<div id="x"></div>
The following code works fine on the browsers I have tried it with:
var link = document.createElement('a');
link.appendChild(document.createTextNode("Hi"));
link.setAttribute('href', "#");
link.onclick= function() {link.appendChild(document.createTextNode("Clicked"));}
document.getElementById("x").appendChild(link);
If there is a browser compatibility issue, using jQuery should solve it and make code much much more concise:
var $link = $("<a>").html("Hi").attr("href","#").click(function (){$link.html("Clicked")})
$("#x").html($link)
If brevity is not a strong enough argument for using jQuery, browser compatibility should be ... and vise versa :-)
NOTE: I am not using alert() in the code because jsFiddle does not seem to like it :-(
If you're doing this with JavaScript, then use addEventListener(), with addEventListener('click', function(e) {...}) to get the event stored as e. If you don't pass in the event like this, it will not be accessible (although Chrome appears to be smart enough to figure this out, not all browsers are Chrome).
Full Working JSBin Demo.
StackOverflow Demo...
document.getElementById('my-link').addEventListener('click', function(e) {
console.log('Click happened for: ' + e.target.id);
});
Link
You can add a DOM even listener with addEventListener(...), as David said. I've included attachEvent for compatibility with IE.
var link = document.createElement('a');
link.setAttribute('href', "#");
if(link.addEventListener){
link.addEventListener('click', function(){
alert('clicked');
});
}else if(link.attachEvent){
link.attachEvent('onclick', function(){
alert('clicked');
});
}
Setting an attribute doesn't look right. The simplest way is just this:
link.onclick = function() {
alert('click');
};
But using addEventListener as JCOC611 suggested is more flexible, as it allows you to bind multiple event handlers to the same element. Keep in mind you might need a fallback to attachEvent for compatibility with older Internet Explorer versions.
Use sth like this if you like:
<button id="myBtn">Try it</button>
<p id="demo"></p>
<script>
document.getElementById("myBtn").onclick=function(){displayDate()};
function displayDate()
{
document.getElementById("demo").innerHTML=Date();
}
</script>
Related
The below piece of code is not working in IE8, but, it is working perfectly on FireFox and Google Chorome, Even, there is no error thrown by IE8, but, output is not coming. Any Idea? What is the actual problem?
<html>
<head/>
<body>
<script type="text/javascript">
(function(){
var inpEle = document.createElement("div");
inpEle.setAttribute("id", "div1");
var texEle = document.createTextNode("This is my Sample Para. I am testing it again my own level that prove How i am capable of.");
inpEle.appendChild(texEle);
document.body.appendChild(inpEle);
})();
(function(){
var inpEle1 = document.createElement("input");
inpEle1.setAttribute("type", "button");inpEle1.setAttribute("value", "Show");inpEle1.setAttribute("onclick", "Show()");
document.body.appendChild(inpEle1);
var inpEle2 = document.createElement("input");
inpEle2.setAttribute("type", "button");inpEle2.setAttribute("value", "Hide");inpEle2.setAttribute("onclick", "Hide()");
document.body.appendChild(inpEle2);
})();
</script>
<script type="text/javascript">
window.onload= function(){
document.getElementById('div1').style.display="none";
}
Show = function (){
document.getElementById('div1').style.border="2pt solid green";
document.getElementById('div1').style.display="";
}
Hide = function(){
document.getElementById('div1').style.border="";
document.getElementById('div1').style.display="none";
}
</script>
</body>
</html>
You may not be able to use document.body.appendChild() in IE8 before the </body> tag has been parsed and your code is trying to append to the body while it is still being parsed. Early versions of IE like IE6 might just abort (e.g. literally crash) when you did this. Later versions (like IE8) will just simply ignore your request.
You can use document.write() to add content while the body is being parsed.
You can postpone calling your code until after the body has finished loading and parsing (such a <body onload="xxx()"> handler) or when an event such as window.onload fires.
You can appendChild() to an element that has finished parsing (something that is before your script).
The simplest solution is probably to put a <div id="container"></div> in the body before your script and append to that instead of the body or put your code in a function and have the body onload event call your function.
See this article for description of the issue.
don't use setattribute use anonymous function for events
inpEle1.onclick = function() {
Show();
};
Also it works in IE tester in IE8, but not IE7, do you have it using IE7 compatibility
Go to Internet Options - Security Tab - Internet - click on the "Custom" button then scroll down to the Miscellaneous section."Allow script-initiated windows without size or position constraints" Find "Active Scripting" then check enable.
I noticed than element.style.display doesn't always work with IE8.
Here is a method to improve compatibility :
if (element.style.setAttribute)
element.style.setAttribute("display", value);
else
element.style.display = value;
Best regards,
I have an anchor tag element coming in the html like:
Now in the javascript function, I have written:
function handleEvent(sourceElement, txt) {
console.log(sourceElement);
}
the consoled element is coming as the window in this case.
I tried sourceElement.document.activeElement but it doesnt seem to work in chrome, where it is coming as body element.
I cannot change the structure of the anchor tag to 'onClick' function as this is coming from some other source.
Is there some way to find the calling element in this scenario?
The real answer here is to change the HTML, which you've said you can't do. I'd push back on that if you can. If you're writing the function, and the function name is in the HTML, how is it you can't change the HTML??
But if you really, really can't, you can update the DOM once it's loaded:
var list = document.querySelectorAll('a[href^="javascript:"]');
var x, link;
for (x = 0; x < list.length; ++x) {
link = list[x];
link.onclick = new Function(link.href.substring(11));
link.href = "javascript:;";
}
Live Copy | Live Source
This is fairly naughty, as it uses the Function constructor (which is very much like eval), but if you trust the source of the HTML, that should be okay.
Or of course, if you don't have to use whatever was in the href to start with, just hook up your event handler in the code above and don't use new Function.
try something like this, use jQuery
just select the link tag with your selector
$(function(){
var href = $('a').attr('href');
href = href.replace('javascript:','');
$('a').attr('href','#');
$('a').attr('onclick',href);
})
This is just workaround solution.
If you have access to the js, you could do something like this:
document.addEventListener('DOMContentLoaded', function(){
var link = document.querySelectorAll('a');
link[0].addEventListener('click', function(e){
console.log(e.target);
});
});
With this, you would be just not be doing anything with the inline href event and just be appending your own handler.
And if no other answer here works for you because you can't update the DOM after it's loaded (try doing any of them if you want to modify a squarespace lightbox - not saying it's impossible, but...), here's an out of the box thinking:
Sometimes there will be something hinting where the a href is. So you could use it.
<div class="hint current">
<a href="javascript:handleEvent('.hint')">
In my case, I even knew the hint without needing a parameter, which made things even simpler:
function handleEvent (hint) {
if(!hint) {
hint = $("div.current");
}
hrefElement = $(hint).find('a[href^=javascript]');
}
This of course will make sense if your DOM is constantly being changed by a script you have no access to.
But even if there is nothing hinting on the a href, you still could do something like this:
<a href="javascript:var x=1;handleEvent(1)">
function handleEvent (uniqueId) {
hrefElement = $('a[href^=javascript:var x='+uniqueId);
}
I haven't been able to make sense of the answers to related questions so far(down to my knowledge level), so...
I have a simple script(using jQuery) that opens a new window and adds certain content from the parent into a specified container inside the child. I'm not sure if it's my approach that's wrong or I'm just missing a step - the script to run on the new window runs in IE when it's outside of the window.onload function, but this breaks FF, and FF is happy when it's inside of the window.onload, but then the new window in IE doesn't appear to be doing anything(no alert, no add of content, nada).
Please can anybody explain to me why this is the case/what I'm doing wrong? Is it something to do with the reference to window.open?
This is the script:
var printPage = function(container){
$('.printButton').click(function(){
var printWindow = window.open('printWindow.html');
var contentFromParent = $(container).eq(0).html();
/*works for IE, but not FF
printWindow.alert('works for IE, but not FF');
printWindow.document.getElementById('wrap').innerHTML = contentFromParent;*/
/*works for FF and Chrome but not IE:*/
printWindow.onload = function(){
printWindow.alert('works for FF and Chrome but not IE');
printWindow.document.getElementById('wrap').innerHTML = contentFromParent;
}
/*I also tried:
$(printWindow.document).ready(function(){
printWindow.alert('load the page, fill the div');
printWindow.document.getElementById('wrap').innerHTML = contentFromParent;
}); //works for IE, not working for FF/Chrome*/
})
}
printPage('#printableDiv');
The HTML:
<div id="wrap">
<button href="#" class="printButton">Print</button>
<div id="printableDiv">
<p>I want to see this content in my new window please</p>
</div>
</div>
UPDATE
Thanks for your pointers about onload in the new window - I've gone with this solution for now: Setting OnLoad event for newly opened window in IE6 - simply checking the DOM and delaying the onload - working for IE7/8/9.
I'm not sure if you'd call it an 'elegant' solution, but it's working! Further comments, especially if you think this is flawed, would be appreciated. Thanks.
var newWinBody;
function ieLoaded(){
newWinBody = printWindow.document.getElementsByTagName('body');
if (newWinBody[0]==null){
//page not yet ready
setTimeout(ieLoaded, 10);
} else {
printWindow.onload = function(){
printWindow.alert('now working for all?');
printWindow.document.getElementById('wrap').innerHTML = contentFromParent;
}
}
}
IEloaded();
Can it be that the page you open fires the 'onload' event before you set the event handler printWindow.onload = ... ?
You might consider including some javascript in your 'printWindow.html' page. Let's say you add a short <script>var printWindowLoaded = true;</script> at the end of your page. Then your main script would do something like this:
function doStuff() {
//...
}
if (printWindow.printWindowLoaded)
doStuff();
else
printWindow.onload = doStuff;
It seems this is a known problem and has been asked several times before here in SO however I do not see anything specific to jQTouch so I thought I would give it a try.
jQT will dynamically load pages when a link is clicked. In this page I would like to include something like
<script>
$.include('javascriptfile.js', function() {alert('do something with results of this file to an already existing div element');};
</script>
The $.include is a jquery plugin I found that mimics the $.load with a few more smarts added to it. Tested to work on FF but not in Chrome or most importantly, Safari.
The alert is never displayed. FireBug never shows the javascript even being loaded. If I put an alert before the $.include I still do not see anything.
I have tried an onclick/ontap event that would then run this code that was included in the head tag, no luck.
Edit: I am using the r148 revision of jQT. This was working prior to moving to this version, i believe.
Did you try to add the javascript file using one of these two methods:
Static Way:
<script type="text/javascript">
function staticLoadScript(url){
document.write('<script src="', url, '" type="text/JavaScript"><\/script>');
}
staticLoadScript("javascriptfile.js");
modifyDivFn(processFnInFile());
</script>
Dynamic way:
<script type="text/javascript">
function dhtmlLoadScript(url){
var e = document.createElement("script");
e.src = url;
e.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
}
onload = function(){
dhtmlLoadScript("javascriptfile.js");
modifyDivFn(processFnInFile());
}
</script>
After the include you can call a function that does the processing you want (that being processFnInFile()) which result will be passed to modifyDivFn (and modify the div you want.) You could do this in one function, just to illustrate the idea.
Source: Dynamically Loading Javascript Files
Well Geries, I appreciate your help but ultimately the answer required a drastic rethinking of how I was using JQTouch. The solution was to move everything to an onclick event and make all the hrefs link to #. This might be what you were talking about Geries.
In the onclick function I do the logic, preloading, loading of the page through my own GET through jquery, then use the public object jQT.goTo(div, transition). This seems to get around the WebKit bugs or whatever I was running into and this now owrks on FireFox, Chrome, Safari, iPhone, and the lot.
I do run into a few animation issues with JQT but I think these are known issues that I hope Stark and the gang at JQTouch are working on.
I have a Firefox 3.6.2 problem (3.5.x works just fine).
This is the code:
...
var newImage = new Image();
newImage.onload=function() {swapMapImg(newImage);};
newImage.src = newBackground;
...
function swapMapImg(newImage) {
alert('bingo');
}
Firefox 3.6.2 no longer fires off my onload event, any ideas?
I would personally start using jQuery if you can and use their onload functions. It should make life a LOT easier for you as someone else is maintaining and testing the code
Turns out the following code:
var currentBackground = tableElem.style.backgroundImage;
returns two different strings in 3.5.x and 3.6.x as shown below:
3.5.x --> url(http://localhost:8080/WellSeismicMap/......);
3.6.x --> url("http://localhost:8080/WellSeismicMap/......");
notice the quotation mark in char position 4 in the 3.6.x version well this was throwing my substr function out and generating an invalid url.
Thanks for your help anyway chaps!
I'm using Firefox 3.6.2 and your code works for me. Are you sure:
newImage.src = newBackground;
Is working? I mean, do you still see the image appear on the page? Because if the link's broken, onload isn't going to happen.