5

I am using jquery address plugin for loading pages, but without hash(#).

index.html:

<a href="page.html">Link</a>
<div id="content">

    <script>

        $(document).ready(function() {

            $.address.init(function(event) {

                $('a').address();

            }).change(function(event) {
                // do something depending on the event.value property, e.g.
                console.log(event.value);

                $.ajax({
                    type: "POST",
                    url: event.value,
                    success: function(msg){
                        $('#content').html( $(msg).find("#content").html() );
                    }
                });
            });
            $('a').click(function(e) {
                $.address.value($(this).attr('href'));

            });
        });

    </script>


</div>

page.html:

<div id="content">
    <p>text</p>
    <script>
        $(document).ready(function() {
            alert('loaded');
        });
    </script>

</div>

In #content div will be loaded #content html from page.html(maybe i should use other function, not .html(), correct me please), in that div is script tag, but i dont get alert when that page is loaded from ajax, it works on without ajax loading. Can someone help me ?

EDIT: I am getting this error when i'm trying to click on link with js function:

XMLHttpRequest cannot load javascript:;. Cross origin requests are only supported for HTTP.

DEMO: http://fbstatusi.com/desavanja/kalendar/mesecna_lista

click on link Zurka 123

Mirza Delic
  • 3,591
  • 12
  • 46
  • 79

2 Answers2

1

document.ready happens only once, when document is loaded. AJAX request does not cause it.

<div id="content">
    <p>text</p>
    <script type="text/javascript">
            alert('loaded');
    </script>
</div>

This should work. Also try to change $(msg).find("#content").html() to $(msg).find("#content")[0].innerHTML, as jquery html strips out tags.

EDIT

Take a look at this thread there is a long discussion about why that happens. In case like this $(msg) jquery will always remove script tags. But at the same time $(msg).filter("script") returns scripts, so you can find those scripts first and then insert them all after $('#content').html( $(msg).find("#content").html() );

Viktor S.
  • 12,342
  • 1
  • 23
  • 49
  • Doesn't work. I think that problem is with .html() becouse when i inspect element, i don't see script tag in #content div. – Mirza Delic Sep 10 '12 at 22:10
  • I am getting this error: `XMLHttpRequest cannot load javascript:;. Cross origin requests are only supported for HTTP.` when i try to click on js function link. – Mirza Delic Sep 10 '12 at 22:13
  • Sorry. I've missed that you have $(msg). Here is a working JS [fiddle](http://jsfiddle.net/6pYsm/2/), but it does not load code with ajax – Viktor S. Sep 10 '12 at 22:15
  • try demo: http://fbstatusi.com/desavanja/kalendar/mesecna_lista click on `zurka 123` link – Mirza Delic Sep 10 '12 at 22:28
  • I have tried your demo and unfortunately even innerHTML does not work there, but I was able to get all scripts with this: myhtml.filter("script"). After you have those scripts - you can append them into your document. That will work for sure) Only problem - if there will be some scripts oustide #main_content that should not be executed. – Viktor S. Sep 10 '12 at 22:50
  • There will be only function to load jquery address, it will be global, so it will load on all pages, will that be a problem ? – Mirza Delic Sep 10 '12 at 23:06
  • It may be a problem. As I can see you are assigning click handlers outside $(document).ready(...), so it will be assigned each time script is executed. And you may get multiple handlers. But.. if html page is created dynamically - why can't you just check on server if it is ajax request or not? And if it is ajax - return only what you need. In that case you can return only #main_content and required scripts and insert it directly: `$('#content').html(msg)` with no missing scripts issue. – Viktor S. Sep 10 '12 at 23:13
  • I can do that, but still i cant insert script tag on ajax call.. how can i use this object with filtered scripts to append it on page? – Mirza Delic Sep 10 '12 at 23:18
  • 1
    can't test if it really works, but suppose this should work: `$('#main_content').html( $('#main_content', myhtml).contents() ); var scripts = myhtml.filter("script"); for(var i = 0; i < scripts.length; i++) {$("body").append(scripts[i]);}` – Viktor S. Sep 10 '12 at 23:24
  • But I would recommend to check if it is ajax request on server side. Right now you have no benefit. Same traffic amount, same speed plus problems with script insert). But if you will return only #main_content and related scripts - you will have no problems with scripts. Just skip `var myhtml = $(data);` and do `$('#main_content').html(data)` immediately. Uh. And do not return #main_content div itself or you will get duplicates. – Viktor S. Sep 10 '12 at 23:30
  • This is working, but it loads this functions twice, and i get error for that, i think this is jquery address error. – Mirza Delic Sep 10 '12 at 23:31
  • Just as I told you - check if that is ajax on server and do not output scripts that you already have on page. Like one linked to jquery or maps. Leave only REQUIRED scripts. Or mark page related scripts with some custom attribute and check if it exists in for loop. I see no reason why address should check if loaded script is already on page when the only thing it does, as I can see, is firing event when URL is changed. – Viktor S. Sep 10 '12 at 23:37
  • Look at demo now, it works fine, but when i click at `zurka 123` it loads twice that script, look at js code on `mesecna_lista` page, i think that jquery address loads it twice. and i did set to only get title, div, and scripts, without header and footer, like you said. – Mirza Delic Sep 10 '12 at 23:52
  • First time page is loaded(I click on a link in question) it is loaded twice. Any further navigation loads it only once, as I can see. Suppose it is loaded twice at first time because address is designed for app which on first request loads content which will not be changed later and than loads page specific content. I would simply put some variable in first load scripts and than if it is true - do not load with ajax, but change it to false. Next load caused by click will do ajax request and will not change that variable – Viktor S. Sep 11 '12 at 06:37
  • jquery address does this with `.change` event, tried to contact their support, but still nothing. thanks for help. – Mirza Delic Sep 11 '12 at 10:04
0

I've encountered a case when an ajax call would return new HTML that includes the script that needs to execute. The code looked like this:

$.ajax('/url', {
  method: 'get',
  success: function(response) {
    document.getElementById("my-body").innerHTML = response;
  }
});

In that code above, response would contain the script that needs to be executed, but it would not execute. Changing the success callback to the following fixed it:

$("#my-body").html(response);

I'm not sure why that was the case (obviously it has to do with the implementation of .html() method). Perhaps someone could comment with an explanation

Dmitry Efimenko
  • 10,224
  • 7
  • 60
  • 73