SitePoint Sponsor

User Tag List

Results 1 to 18 of 18
  1. #1
    SitePoint Member
    Join Date
    May 2011
    Posts
    18
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Changing and loading an iframe 'src' attribute with jQuery

    Hi everyone,

    I'm very new to jQuery and quite rusty with my web design in general. I have a page on my site with 5 buttons alongside an iframe which is embedded from Youtube showing a video. All I want is for each of the buttons to load a different video from Youtube into the iframe without simply reloading the whole page. I've searched and seen some examples of jQuery interaction with iframes, but all too complex for me to fully follow. Could someone please provide a simple example of what I need to do? I just need jQueary to change the src value and reload the iframe when the user clicks on one of the buttons.

    Any help would be greatly appreciated.

    Thanks.

  2. #2
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    You could use the target attribute on the link to target the iFrame.

    If you have the embed links to the youtube videos, you can do something like this:

    Code html4strict:
    <p><a href="http://www.youtube.com/embed/Q5im0Ssyyus" target="someFrame">Charlie 1</a></p>
    <p><a href="http://www.youtube.com/embed/QFCSXr6qnv4" target="someFrame">Charlie 2</a></p>
    <p><a href="http://www.youtube.com/embed/eaCCkfjPm0o" target="someFrame">Charlie 3</a></p>
     
    <iframe name="someFrame" id="someFrame" width="560" height="315"></iframe>

    Live demo: http://jsfiddle.net/GeekyJohn/GH5QG/

    Of course if for some reason you need to use JavaScript, then you could simply change the source of the iframe.

    in jQuery parlance this would only be a few lines:

    Code javascript:
    $(document).ready(function(){
        $("a").click(function(e) {
            e.preventDefault();
     
            $("#someFrame").attr("src", $(this).attr("href"));
        })
    });
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  3. #3
    SitePoint Member
    Join Date
    May 2011
    Posts
    18
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's exactly what I needed. Thank you very much. I thought of using jQuery because I'd also like to be able to add a class to the button as it's clicked to enable the active link to be styled differently.

    Any chance you could provide an example of this behaviour also?

    Thanks.

  4. #4
    SitePoint Zealot
    Join Date
    Oct 2007
    Location
    Bilthoven, Netherlands
    Posts
    120
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I reckon that this would work:
    Code:
    $("a").click(function(e) {
      e.preventDefault();
      $("#someFrame").attr("src", $(this).attr("href"));
      $("a").removeClass("active");
      $(this).addClass("active");
    })
    First removing the "active" class from all links, then adding that class to the clicked link.

    May I suggest that you give your links e.g. a class name to identify them:
    HTML Code:
    <p><a href="http://www.youtube.com/embed/Q5im0Ssyyus" class="myButtons">Charlie 1</a></p>
    And get them e.g. like this:
    Code:
    $("a.myButtons")
    That gives you the freedom to add more <a> tags to the page without affecting them too.

  5. #5
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jonas-e View Post
    Code:
      $("a").removeClass("active");
    First removing the "active" class from all links, then adding that class to the clicked link.
    That would be rather bad for performance, it would be better to reference only the already active links like so:

    Code:
      $("a.active").removeClass("active");

    Quote Originally Posted by jonas-e View Post
    May I suggest that you give your links e.g. a class name to identify them:
    Most certainly an excellent idea. The other option would be to have an ID or class on the parent of the links.

    Code javascript:
    $("#theButtons a.active").removeClass("active");
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  6. #6
    SitePoint Zealot
    Join Date
    Oct 2007
    Location
    Bilthoven, Netherlands
    Posts
    120
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
     $("a.active").removeClass("active");
    Good point

    BTW, do you think jQuery keeps a chached list over all a tags?
    Or does it perhaps do the following when parsing "a.active":
    1. First get all a tags on the page.
    2. Then look through them all to find those with the className attribute containing the string "active".
    3. Then remove the "active" string from their className attribute.

    If so, it may not improve performance ..

  7. #7
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jonas-e View Post
    Code:
     $("a.active").removeClass("active");
    Good point

    BTW, do you think jQuery keeps a chached list over all a tags?
    Or does it perhaps do the following when parsing "a.active":
    1. First get all a tags on the page.
    2. Then look through them all to find those with the className attribute containing the string "active".
    3. Then remove the "active" string from their className attribute.
    If so, it may not improve performance ..
    It depends on how the selector is constructed

    You can always cache your jQuery results yourself by storing a result set in a variable. So for example if you would loop over something, you wouldn't want to get jQuery to perform a lookup and instantiate a new instance of itself.
    e.g.
    Code javascript:
    //This is *bad*
     
    for( var i = 0; i < aLongDataSet.length; i++ ) {
      $("a.someLink"); // ouch, jQuery needs to look this up *every* time.
      //do stuff
    }
     
    // This is *much* better
     
    var i = 0;
     
    // we're also caching the length of the data set so it doesn't have to be requested each time
    // it's a micro optimization, but a good habit to get in to nonetheless.
    var len = aLongDataSet.length; 
     
    // I prefix my jQuery objects with a '$' so I instantly know that var contains a jQuery object
    var $links = $("a.someLink"); 
     
    for ( i = 0; i < len; i++ ) {
     //you can now do something with $links
    }

    Ok, back to how jQuery performs a selection on an item with a class.

    The selector engine, called "Sizzle", will attempt to use the browser's native methods that are fastest first: document.getElementsByTagName(), document.getElementsByClassName(), document.getElementById(), and document.querySelectorAll() (and not necessarily in that order, if you want to see what selectors are fast/slow take a look at http://mootools.net/slickspeed/ of course results will vary depending on which browser you use).

    To performance enhance our selectors, you can give them a context. You can do this in several ways.

    You can put all your elements in a container <div> with an ID on it as that will be quite fast to select and will reduce the amount of data subqueries have to go through.
    e.g.
    HTML Code:
    <div id="myLinks">
      <h3>My links</h3>
      <a href="#" class="myClass">Link</a>
      <a href="#" class="myClass">Link</a>
      <a href="#" class="myClass">Link</a>
    </div>
    To then select them with jQuery we can do this in the following manners.

    Code javascript:
    // use #myLinks before the class selector, jQuery will find "#myLinks" first 
    // and search for the remaining selector in its contents
    $("#myLinks a.myClass");
     
    // use a context parameter, the jQuery selector can take a context (Selector, DOM node, Document or jQuery)
    var domNode = document.getElementById("myLinks");
    var $jqObj = $("#myLinks");
     
    // select with Selector
    $("a.myClass", "#myLinks");
     
    // select with DOM node
    $("a.myClass", domNode);
     
    // select with jQuery Object
    $("a.myClass", $jqObj);

    It's not always necessary to do this, it depends on how many items you have across the page and if you're trying to narrow them down to a particular part of the page.

    For example, let's say you wanted to only select links with a class in the sidebar of your page, you would use $("#sidebar a.someClass") or $("a.someClass", document.getElementById("sidebar")) as it would be a lot faster to only search the DOM of the sidebar than it would to search the DOM of the entire page.

    Read more about jQuery Context: http://api.jquery.com/jQuery/

    Hope this helped
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  8. #8
    SitePoint Zealot
    Join Date
    Oct 2007
    Location
    Bilthoven, Netherlands
    Posts
    120
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Interesting. I never heard of document.querySelectorAll() before. Generally, I'm a bit hesitant to use an element's id as in document.getElementById() because I imagine, that the browser has to run through ALL elements until it finds a match - but perhaps it keeps an index.

    Anyway, I only ever get an element once and then I store a reference to that element in e.g. a property of an object for later use.

  9. #9
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jonas-e View Post
    Interesting. I never heard of document.querySelectorAll() before. Generally, I'm a bit hesitant to use an element's id as in document.getElementById() because I imagine, that the browser has to run through ALL elements until it finds a match - but perhaps it keeps an index.
    document.querySelector/querySelectorAll is still a bit on the new and shiny side, and unfortunately doesn't work in some older browsers. (See caniuse.com/queryselector.) Of course a fallback "polyfill" method could be used that falls back to a selector engine like qwery or sizzle (or if you're doing a lot of selecting, it might be worth just using one of these selector engines )

    document.getElementById() is usually the better and faster method for selecting a single element as browser vendors have heavily optimized it.
    (Check out this jsperf test that compares querySelector, querySelectorAll, getElementById, getElementsByClassName, and getElementsByTagName)

    Quote Originally Posted by jonas-e View Post
    Anyway, I only ever get an element once and then I store a reference to that element in e.g. a property of an object for later use.
    That's a good practice to stick with . While often it's a bit of a micro-optimization, it can lead to massive performance gains, especially if you're looping through a particularly long data set.
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  10. #10
    SitePoint Member
    Join Date
    Jan 2007
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is what I was looking.
    Is there any way to start on page load, with first link video within iframe?

  11. #11
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jaggu25 View Post
    This is what I was looking.
    Is there any way to start on page load, with first link video within iframe?
    You could do something like this:
    Code javascript:
    links = document.getElementById("myLinks").getElementsByTagName("a");
    if (links.length > 0) {
      firstAnchor = links[0];
    }
     
    document.getElementById("someFrame").src = firstAnchor.href;

    If you're using jQuery you could do it like this:
    Code javascript:
    $("#someFrame").attr("src", $("#myLinks a:first").attr("href"));

    You just put that at the bottom of the page (or below the iFrame and links in any case) and it will set the href of the first link as the src of the iFrame
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  12. #12
    SitePoint Member
    Join Date
    Jan 2007
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Awesome!!!! Perfect output. Thanks a lot!!!

    I'm debugging another task, I really appreciate if you can share your inputs;
    within Lightbox am using iframe to load external html file. However, some user has noticed that iframe is taking time to load static html file. I have two blocks in lightbox one is with youtube link and another with html page. Any suggestions to load faster iframe src file?

    Thanks a lot!

  13. #13
    SitePoint Zealot
    Join Date
    Oct 2007
    Location
    Bilthoven, Netherlands
    Posts
    120
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AussieJohn View Post
    You just put that at the bottom of the page (or below the iFrame and links in any case) and it will set the href of the first link as the src of the iFrame
    If you want stuff to execute on pageload it is a good idea to use this method:
    Code javascript:
    $(document).ready( function(){
      $("#someFrame").attr("src", $("#myLinks a:first").attr("href"));
    });
    Thus you don't have to worry about putting the script tags at a specific place on the page. You can put it wherever you like - even in a separate js file.

  14. #14
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jonas-e View Post
    If you want stuff to execute on pageload it is a good idea to use this method:*
    * If you're using jQuery

    Depending on what the application is, I tend to often put some JavaScript that is absolutely required for my application to work in the header, and most everything else can go in the footer. This way any time you write non-jQuery code you won't have to worry about sticking things in an onLoad handler.

    This will ensure your markup and CSS load and execute quicker as they don't have to wait for scripts to load & execute.
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  15. #15
    SitePoint Zealot
    Join Date
    Oct 2007
    Location
    Bilthoven, Netherlands
    Posts
    120
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AussieJohn View Post
    * If you're using jQuery
    The user who created this thread specifically wrote above that he DOES use jQuery ...

  16. #16
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jonas-e View Post
    The user who created this thread specifically wrote above that he DOES use jQuery ...
    Whoops yup!

    Though this functionality can be written with just a few lines of regular JavaScript without requiring the jQuery overhead
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  17. #17
    SitePoint Member
    Join Date
    May 2011
    Posts
    18
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for a very late reply.

    Thank you again guys for the terrific help. I've taken in what you've recommended and have it working just as I wanted. Great performance advice too!

    Much appreciated!

  18. #18
    SitePoint Member
    Join Date
    Sep 2005
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Unhappy

    My situation is much the same as Duckie's. I have a page with an iFrame and four links to native files that each will appear within the iFrame when summoned. I've done this with straight HTML. The problem is that when I land on the page I have an empty iFrame until I click one of the links.

    Not only would it be nice to have the iFrame populated with the first link upon arrival, but it would be a real bonus if there was a way to arrive at this page with any other of the remaining links appearing, if in fact that's the content someone came looking for. For example, if I place anchors for my four links on another page, it would be ideal if someone could select the second item and find it populating the iFrame upon arrival at my-iFrame-page.php.

    I'm not opposed to using jQuery nor javascripting of any kind, but I'm afraid that for a newbie, there's a lot that I don't grasp when I try to sort through everything above. I'd be over the moon if someone could post a working example that achieves what I'm after.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •