views:

104

answers:

4

I am trying to solve a problem for a client where they want to dynamically inject an image into the page and have it call their js function when clicked. The script is included from our base js class to their site, so it's my code on their site essentially.

I am very close to getting there, but I've found a strange issue in IE of all places, lol.

Using jQuery,

$('#sas-window-header').append("<img src='sandwich.jpg' id='gif' alt='Sandwich' />");

This is throwing an error in IE7,8

Object expected attachevent, line 42 character 20

(attachevent is the name of my page)

I was trying to write my function using vanilla js, but it seems that there are too many issues between attachEvent() and addEventListener() to make it viable, hence injecting jQuery to help me out.

Can anyone tell me why IE thinks that a cross browser frameworks function methods should be expecting an object?

I am getting expected behaviour in Firefox, Safari and Chrome. Two images in Opera for some reason, and IE7,8 with this object error. I'll come to ie6 later! ;)

Here is what I have so far,

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Attach event test page</title>

        <script type="text/javascript">
        window.onload = (function() {

            if(typeof jQuery == 'undefined'){
                var script = document.createElement("script");
                script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js";
                script.type = "text/javascript";
                script.onload = script.onreadystatechange = function(){
                    injectImg();
                };
                document.body.appendChild( script );
            }else{
                injectImg();
            }

        });

        function injectImg(){
           $('#sas-window-header').append("<img src='sandwich.jpg' id='gif' alt='Sandwich' />");

           $('#gif').click(function(){
               alert('Clicked');
           })
        }

        </script>
    </head>
    <body>
        <p>The header</p>
        <div id="sas-window-header"></div>
    </body>
</html>
+1  A: 

You're appending a new image in each readystatechange and load of the script. Differences in how these events are fired are probably what determines the number of images being inserted. You probably want to do $('#sas-window-header').empty() before your append...

Do you have to inject jQuery? Can't you include it? The above seems really messy, and could be condensed to

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Attach event test page</title>

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
        <script type="text/javascript">
        $(document).ready(function() {
           $('#sas-window-header').append("<img src='sandwich.jpg' id='gif' alt='Sandwich' />");

           $('#gif').click(function(){
               alert('Clicked');
           });
        });
        </script>
    </head>
    <body>
        <p>The header</p>
        <div id="sas-window-header"></div>
    </body>
</html>
David Hedlund
It's not my page, I don't have access to the HTML. All I have is JS :)
DavidYell
A: 

If I were you, I would create the image as a dom element:

var theImage = document.createElement("img");

And set properties accordingly:

theImg.src = 'sandwich.gif';
theImg.alt = 'Sandwich';
theImg.id  = 'gif';

Set the handler:

$(theImg).click(function(){
    alert('Clicked');
});

Then place the object somewhere in the dom tree:

$('#sas-window-header').append(theImg);

That should work... Let us know.

Symen Timmermans
Yes, I have tried this and it does work, but again throws an error for me in my IE8 Developer Tools
DavidYell
A: 

Hey after adding semicolon in injectImg function at end of click event of image, it is working.

function injectImg(){
   $('#sas-window-header').append("<img src='sandwich.jpg' id='gif' alt='Sandwich' />");

   $('#gif').click(function(){
       alert('Clicked');
   });

  }

Checkout here: http://jsbin.com/aduyu3/edit (tested in IE 7)

Krunal
Thanks, I added the `;` but am still seeing an error with `append()` expecting an object.
DavidYell
A: 

You called injectImg() before the script tag is inserted,that means, jQuery libary have not loaded yet.
And ,In injectImg() function, jquery selector is used.
That is why, the error has been encountered.

Try this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Attach event test page</title>

        <script type="text/javascript">
        window.onload = (function() {

            if(typeof jQuery == 'undefined'){
                var script = document.createElement("script");
                script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js";
                script.type = "text/javascript";
                script.onload = script.onreadystatechange = function(){
                document.body.appendChild( script );                    
                 injectImg();
                };

            }else{
                injectImg();
            }

        });

        function injectImg(){
           $('#sas-window-header').append("<img src='sandwich.jpg' id='gif' alt='Sandwich' />");


        }

        </script>
    </head>
    <body>
        <p>The header</p>
        <div id="sas-window-header"></div>
    </body>
</html>

Edit: Yes,You are right. If that so, you can call the injectImg() using setTimeout though it may NOT be a decent solution.

 window.onload = (function() {

            if(typeof jQuery == 'undefined'){
                var script = document.createElement("script");  
                script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js";
                script.type = "text/javascript";

                script.onload = script.onreadystatechange = function(){
                    setTimeout('injectImg()',1000);
                };
                document.body.appendChild( script );
            }else{
                injectImg();
            }

        });
Kai
Yes, I thought the same, although this produces a workable result in IE but not in Firefox, Chrome, Safari or Opera.
DavidYell
Yes.U r right.How abt calling that statement using setTimeOut()?It may NOT be a decent solution,but it will work on X-Browsers.Plz check my edited anwser
Kai
`Object expected attachevent, line 12 character 20``Invalid argument. attachevent, line 24 character 21`Doesn't look like it likes `setTimeout()` either. I will find a workaround by speaking with the client.
DavidYell