This question already has answers here:
JS function named `animate` doesn't work in Chrome, but works in IE
(3 answers)
Closed 1 year ago.
It's an issue with google chrome version 53.0.2785.101 (64-bit). I tried running a simple html file and it throws the error 'slot.testFun is not a function' when I used the word 'slot'.
<html>
<head>
<title>TEST</title>
</head>
<body>
Click Here
<script type="text/javascript">
var slot = {
testFun: function(){
console.log('clicked');
}
}
</script>
</body>
</html>
There are no conflicts with this variable in our code. It's just the browser, not allowing the variable name in this latest version.
If you use any other name except the word 'slot', it works fine.
This isn't an ECMAScript issue, it is a DOM issue.
The slot attribute has a corresponding slot property, and onclick attributes do stupid things with with so you are effectively calling this.slot.testFun() because it finds slot (which defaults to being an empty string) before it gets to the right scope.
slot is a new addition to the DOM and support for slot is new in Chrome 53. It does not appear in Chrome 52 and might not have made it even into the latest version of other browsers.
The solution: Avoid intrinsic event attributes. Bind event handlers with DOM instead. That protects you from his clash and future-proofs you from future additions to the DOM.
Click Here
<script type="text/javascript">
var slot = {
testFun: function(){
console.log('clicked');
}
}
document.querySelector("a").addEventListener("click", slot.testFun);
</script>
Related
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 years ago.
I'm making a calendar script and it works ok with the Opera browser, but not with firefox. The trouble happens in the day selection. This particular snippet illustrates the problem. In this case, dayofweek[] contains 31 DIV tags each containing its own number that people can click on.
<script type="text/javascript">
var maxdays=31;
for (var n=1;n<=maxdays;n++){
dayofweek[n].onclick="selectday("+n+")";
}
function selectday(day){alert(day+" is selected");}
</script>
This script works (in opera) by printing a message that the correct number is selected. In Firefox, the onclick event never is executed even tho I made clicks..
The other method I tried is this:
<script type="text/javascript">
var maxdays=31;
for (var n=1;n<=maxdays;n++){
dayofweek[n].onclick=function(){selectday(n);}
}
function selectday(day){alert(day+" is selected");}
</script>
This time, both firefox and opera respond, but the problem is that "31 is selected" appears no matter which number I select.
Does anyone know what I can do to make all javascript enabled internet browsers cooperate with my code?
Javascript is not block scoped. Try this:
<script type="text/javascript">
var maxdays=31;
for (var n=1;n<=maxdays;n++){
dayofweek[n].onclick=selectdaywrapper(n);
}
function selectdaywrapper(day) {
function selectday(){
alert(day+" is selected");
}
return selectday;
}
</script>
The issue you are running into has to do with scoping and how variables are bound in js. The functions you are creating in the loops are binding to the loop variable, but are not evaluated till after the loop finishes, so all the onclick events are executing with the final value of n
I'm working with a legacy frames website that was just moved into an iFrame.
Assuming I have the following function:
<script language = "javascript">
function myFunction(){
<!-- no console.log in IE 7 (my required target browser) -->
alert('sup, yo?');
}
</script>
and the following hyperlink triggering the function:
click me
before the move into an iFrame this worked ok. Once the website was moved into the iframe, clicking the link in IE (not FF or Chrome), I would get the ever-so-helpful error:
Line: 1
Object expected
Once I removed the target="_top" attribute the function would work, so I don't need help solving the problem, but my question is:
What is IE doing with the target attribute when calling a javascript function to invoke this behavior? I don't have other versions of IE installed, is this current behavior in 8+ as well?
Thanks.
It does not make sense to try to understand the behavior. You're using a technique that is not well defined and is not used by developers nowadays.
Instead of href="javascript:myFunction();, just use onclick="myFunction(); return false" or even better, set the handler from JS like the following
<a href="pageForUsersWithoutJs.html" id="my-link" >click me</a>
<script type="text/javascript">
// This is old school, but works for all browsers, you should use a library instead
document.getElementById('my-link').onclick = function() {
// Do your thing
return false; // so the link isn't followed
};
</script>
This question already has answers here:
Load event not fired on Safari when reloading page
(2 answers)
Closed 4 years ago.
I have an object element in my html with a blank data attribute which is then set later upon a ajax response. Now I want to get the event when the DOM for the object content document is ready.
If I use onload on the object element it works in firefox and Opera but it does not work in Webkit based browser.
How can I have the onload event trigger in all the browsers
The html looks like this
<object id="myobj" data="" />
the javascript that works in FF but not in WebKit is
e = doc.getElementById("myobj")
e.onload = function(){}
e.data="http://myurl"
In theory onload is strictly for the body element. If certain browsers allow it for other elements more power to them but it's not required.
Also: is your semicolon key broken?
I've tried the code with Safari 5.0.2 and it worked. You can verify by alerting after assigning the new value. When you view the source it isn't there but the newly assigned value can be accessed from any method.
e.data="http://myurl";
alert(e.data);
ie:
function doThis() {
var data = document.getElementById("myobj");
alert('retrieved from a method ' + data.data);
}
In jQuery, to call something on page load, all you have to do is use:
$(document).ready(function()
{
//your code here to populate your object's data attributes
});
This will work in all browsers.
I am having problems passing javascript values between frames in chrome. In other browsers (Opera and Firefox) it works. The first frame contains the following html:
<script> variable="frame 1 value";</script>
click here
and test.html is:
<html>
<head>
<script>window.onload = function() {
div = document.getElementById("fred");
div.innerHTML="<b>" + top.frames[0].variable + "</b>";
}
</script>
</head>
<body>
<div id="fred">
hi there</div>
</body>
</html>
I have looked on this site and others, and the have seen a suggestion that because chrome pages run in different processes they cannot pass values. Is this true, and if so is there a way around it (cookies?)
Thanks,
russell
(edited) I just found another answer which says this happens only on file protocol. Like the writer of the other question, I am writing an applicaiton meant to be run off a cd, so I need to use file protocol. The version of Chrome I am using is 9.0.
ry
This has something to do with cross-site scripting which may be a security issue. Since Chrome has a very strict behavior on this, it should be impossible to achieve what you want.
Fortunately, there may be a nifty trick that you can use (if your variable is only a string):
Change the link in the first frame to test.html?foo=bar
Read window.location.href in the second frame. This will yield something like "Z:\folder\test.html?foo=bar". Now you can use string manipulation functions to extract the value of foo (in case: bar) from the href.
HTML5 Storage to the rescue! For the first frame:
<script>localStorage.setItem('variable', 'frame 1 value');</script>
click here
And for test.html:
<html><head>
<script>
window.onload = function() {
div = document.getElementById("fred");
div.innerHTML="<b>" + localStorage.getItem('variable') + "</b>";
}
</script>
</head><body>
<div id="fred">hi there</div>
</body></html>
A note of caution: IE7 and some older browsers do not support localStorage. However, you should be able to use if (typeof(localStorage) == 'undefined') {} to detect which method you need to use.
Frames are deprecated since 1997 (HTML 4.0 specification) for many reasons - so the best recommendation is do not use them.
You can also run Chrome with command line argument --disable-web-security, but it is also bad recommendation.
I try get the mp3 flash player to work with my javascript on all browsers. All went well for first, but fast realized that my code doesn't work on MSIE.
After trying to find out I found this in the reference code:
<!--[if IE]>
<script type="text/javascript" event="FSCommand(command,args)" for="myFlash">
eval(args);
</script>
<![endif]-->
How to turn this into a javascript or jquery clause that I could stuff it where it belongs to (in audio.js)?
That syntax, with the <script> tag with the "event" and "for" attributes is an Internet Explorer-only way of setting up an event handler on an DOM object. Here, it adds a FSCommand event handler to the myFlash object. This is needed because code running inside the Flash object may want to run JavaScript in the browser. To do this, the Flash object will invoke the FSCommand event handler, passing the JavaScript to run as the arguments to the event.
With this player, the name of a JS listener object is passed in the FlashVars param to the player. It then uses FSCommands from ActionScript to modify that listener object, with an occasional call to a method on that listener when it's other properties have been modified. I suppose that IE isn't able to run the JS code using this method until the FSCommand handler has been added to the Flash player object, which is why that code exists. Modify it to use the ID of your Flash object and you should be in good shape.
Maybe this is more about embedding flash dynamically.
I got stuck on exactly the same thing with mp3 flash player. The thing is that IE doesn't care about the special script tag with 'event' and 'for' attribute, if it is added AFTER the page has loaded. My IE wouldn't event eat jquery's .html() when the page loaded, only document.write worked. But document.write can't really be used after the page has loaded, unless it is targeted in an iframe or some other devil worship mechanism.
What's good tho, is that IE doesn't distinguish between assigning an event handler in this bastard script tag or programatically. This means that:
<script type="text/javascript" event="FSCommand(command,args)" for="myFlash">
eval(args);
</script>
in IE directly translates to:
function foo(command, args){
eval(args);
}
var ie_sucks = document.getElementById('myFlash');
ie_sucks.attachEvent("FSCommand", foo);
And... in the end we have that:
var ie_sucks = document.getElementById('comebacker_audio');
ie_sucks.attachEvent("FSCommand", function(command, args) {eval(args);});
and if that not work for you, try to check your html for inserting object. Example here:
http://kb2.adobe.com/cps/415/tn_4150.html
;)
Thanks everyone for the above. I'll just drop a few lines that were handy for me.
To re-use code across browsers, do:
<script type="text/javascript">
function mySwf_DoFSCommand(command, args) {
// do stuff
}
</script>
<!--[if IE]>
<script type="text/javascript" event="FSCommand(command,args)" for="mySwf">
mySwf_DoFSCommand(command, args);
</script>
<![endif]-->