cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
matt5834
Community Participant

Targeting the iFrame using Javascript in the new UI

Jump to solution

Hi-

I've been using this very important piece of javascript in my custom javascript file:

var iFrame = window.top.document.getElementById('window_content');

iFrame.setAttribute("scrolling","no");

It is not working when the new UI is enacted. I'm guessing it might have something to do with the ID of the iFrame in the new UI but I cannot figure it out.

I have uploaded the Javascript file via the Theme Editor

Please help!

Best ,

Matt

Tags (2)
1 Solution

Accepted Solutions

That is very helpful. I found a .tool_content_wrapper class that should be pretty unique to this application and added it to the file. Give it a try, if it still doesn't work, I will try again.

View solution in original post

39 Replies
Stef_retired
Community Team
Community Team

matt5834​, I don't have an answer for you, but I've added some tags to your question and have shared it with the Canvas Admins​ and Canvas Developers​ groups to get some expert focus on your javascript.

jordan
Community Champion

Thanks for sharing Matt's question to those groups. I'm also wondering if  @MattHanes ​,  @kenneth_larsen ​ or  @James  might have any insight here...

kenneth_larsen
Community Champion

matt5834​​, where is the iframe located that you are trying to target?

matt5834
Community Participant

They are located in regular pages (Wiki Pages) as well as in the direction section of assignments.

Thank you!

Matt

James
Community Champion

matt5834​​,  I'm going to throw a bunch of stuff out. Maybe something will resonate.

Is 'window_content' an id that you added? I went to Wiki pages in the old UI and couldn't find it, even when I viewed the generated source. There are 'content-wrapper' and 'content' ids.

Another thing to do is to make sure that it still works in the old UI. Perhaps go into Beta, turn off the new UI, and test it. Sometimes we think changes are related to one thing, but maybe there have been other changes besides the UI.

I don't think this is the issue, but since I'm slinging things hoping one will stick, have you tried changing the name of the variable iFrame to make sure it's not conflicting with something Canvas might be using in some of their Javascript? Perhaps it isn't scoped and conflicted.

Have you verified that it is finding the id. Maybe a console.log(iFrame); after you get it to make sure it is finding it.

If the window_content is there, are you sure it's in the window.top instead of window.parent? Maybe there are multiple iframes in the new UI and you just want the parent instead of the top.

I have no confidence in any of those suggestions, but that's where I would start looking.

I apologize if I am not understanding correctly. Are you trying to access the iframe for the rich content editor, or are these custom iframes that you are putting into your content? I can help in either case, I just need to know what answer to give you.

matt5834
Community Participant

Kenneth-

The iframe is one that I placed in the Rich Content editor, yes custom iframes. For example:

<iframe id="window_content" style="position: absolute; top: 0; left: 0; width: 1px; min-width: 100%;" src="https://www.yciw.net/_1aiPad/" width="300" height="100%" name="window_content"></iframe>

... is being placed in the HTML Editor.

BTW, the javascript is necessary because  scrolling: no;  is being stripped out. (overflow: hidden;  was not working)  I need to set the scrolling to "no" so that it functions proper on iOS.

Let me know if that helps.

Matt

matt5834​, that actually helps a lot. If you are trying to target an iframe in user created content, the biggest issue is that a page in Canvas loads and then Canvas inserts the user content. The problem with this approach and JavaScript is that the content you are targeting may not exist until after your JavaScript runs (hence the code appears to not be working). I am actually surprised that you didn't notice this issue before since this issue has been around since Canvas introduced draft state.

The first thing we will do is simplify your code. Because Canvas uses jQuery, you can use the following:

$('#window_content').attr('scrolling', 'no');

To be sure it is timing and not your code, you can run your code in the developer console of Chrome, Firefox, or Safari and see if the attribute changes. (You can Google "console" and your preferred browser if you are not sure how to do this).

If you want to make sure that all of the content loads before you execute your code, it gets a lot more complex. Fortunately for you, I have developed a script to do this for you that I am happy to share. I will note that the final version takes requires 70 lines of code just to make sure the simple one line triggers at the right time. I have attached the file, all you will need to do is add the code you want to run into line 21.

If you want to better understand what is going on, here you go:

The first portion is a collection of id's of containers in Canvas that house user created content

// If any of these elements exist, we will watch for page content in them to load

var klContentWrappersArray2 = [

        '#course_home_content', // Course Front Page

        '#wiki_page_show', // Content page

        '#discussion_topic', // Discussions page

        '#course_syllabus', // Syllabus page

        '#assignment_show', // Assignments page

        '#wiki_page_revisions'

    ],

    i;

Then we have the function that will contain the code you would like to run

// This file triggers and launches all of the code required to run the tools

// Commands to run after the page content has loaded

function klAfterContentLoaded2() {

    'use strict';

    // Include the code you want to run in this function

     $('#window_content').attr('scrolling', 'no');

}

The next function is run on pages containing the wrappers mentioned above to identify when the content is loaded and then run your code (or die if it runs 50 times without finding anything)

// Check to see if the page content has loaded yet

function klPageContentCheck2(klContentWrapperElement2, checkCount) {

    'use strict';

    var contentLoaded = false;

    // Content Pages

    if ($('.show-content').length > 0 && $('.show-content').children().length > 0) {

        contentLoaded = true;

    // Discussions

    } else if ($('#discussion_topic').length > 0 && $('.user_content').text().length > 0) {

        contentLoaded = true;

    // Assignment (Teacher View)

    } else if ($('#assignment_show .teacher-version').length > 0) {

        contentLoaded = true;

    } else if ($('#assignment_show .student-version').length > 0) {

        contentLoaded = true;

    } else if ($('#course_syllabus').length > 0) {

        contentLoaded = true;

    }

    if (contentLoaded) {

        console.log('Content has loaded');

        klAfterContentLoaded2();

    } else {

        if (checkCount < 50) {

            checkCount++;

            setTimeout(function () {

                console.log('Still no content, check again (' + klContentWrapperElement2 + ')');

                klPageContentCheck2(klContentWrapperElement2, checkCount);

            }, 100);

        }

    }

}

Then the last part will loop through each of the container id's to see if there is a match on the page and then trigger the function that looks for content if that ID exists

$(document).ready(function () {

    'use strict';

    var task,

        i;

    // Identify which page we are on and when the content has loaded

    for (i = 0; i <= klContentWrappersArray2.length; i++) {

        if ($(klContentWrappersArray2[i]).length > 0) {

            // console.log(klContentWrappersArray2[i] + ' Found');

            klPageContentCheck2(klContentWrappersArray2[i], 0);

            break;

        }

    }

});

You can copy and paste the attached code into your Global JS file. Hopefully that helps. It is probably a lot more complex than you were hoping. Let me know if you have any additional questions.

matt5834
Community Participant

Kenneth-

Thanks so much for this. Before trying to implement this do you know if there is a way for me to simply include the styling - scrolling: no;  directly into the iframe code that I am using?  As I mentioned above this is getting stripped out.

Thank you!

Matt