Accessing an element inside the hmcontent iframe

Please post all questions and comments regarding Help & Manual 7 here.

Moderators: Alexander Halser, Tim Green

Post Reply
User avatar
julio
Posts: 118
Joined: Wed May 28, 2008 12:06 am
Location: Porto Alegre, RS - Brasil
Contact:

Accessing an element inside the hmcontent iframe

Unread post by julio »

Hello,

I am having a lot of trouble trying to access elements inside the 'hmcontent' iframe used by H&M templates to build HTML pages. Currently I am using the 'WebHelp, iFrames Responsive Blue.hmskin' template on v7.5.4.4760.

The problem is that I created a simple feedback form for each page and I want to use some javascript code to control that form. To do so, I created a javascript file that is loaded with the pages and it succeeds to get a reference to the 'hmcontent' iframe, but when I try to get a reference to the elements inside that iframe, these references always return null :frustration:. The next example code shows how this is working now:

Code: Select all

var content_frame = document.getElementById("hmcontent").contentDocument? document.getElementById("hmcontent").contentDocument: document.getElementById("hmcontent").contentWindow.document;

if (content_frame === null) {
  console.log("Content frame is null");
} else {
  console.log("Content frame is not null"); // This message always show, so I am OK here
}

// The element inside hmcontent is <a id="link-good"></a>
// So I try to get a reference to this element
var btn_good = content_frame.getElementById("link-good");

// And here I try to add a listener to the element
// But I always receive a message
// Cannot read property 'addEventListener' of null
btn_good.addEventListener("click", function(){
  console.log("Clicked good");
});
I know this is not exactly an H&M question but I would like to know if there is something I am missing here, because no matter how I search this problem, it always end up on a discussion about cross-site references, and yes, I am fully aware of that problem and I really think this is not the real problem because I actually can retrieve a reference to that iframe. So, be kind and do not start a war on pointless cross-site explanations.

Thank you.
User avatar
Tim Green
Site Admin
Posts: 23156
Joined: Mon Jun 24, 2002 9:11 am
Location: Bruehl, Germany
Contact:

Re: Accessing an element inside the hmcontent iframe

Unread post by Tim Green »

Hi Julio,

Your problem here is most likely timing. If you're not careful you will be executing your code before the topic has fully finished loading in the iframe and then nothing can be found. Try polling for it like this:

Code: Select all

var topicframe = document.getElementById("hmcontent"), buttoncounter = 0,topicbutton;

var getbutton= setInterval(function() {
    if (buttoncounter > 100) {
        topicbutton = false;
        clearInterval(getbutton);
        } else {
            buttoncounter++;
            topicbutton = topicframe.contentWindow.document.getElementById("link-good");
            if (topicbutton != null)
              clearInterval(getbutton);
        }

    },50);
This polls for the button in the topic file up to 100 times at 50ms intervals. After that it gives up and sets the value of topicbutton to false, which you can then check for.
Regards,
Tim (EC Software Documentation & User Support)

Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
User avatar
julio
Posts: 118
Joined: Wed May 28, 2008 12:06 am
Location: Porto Alegre, RS - Brasil
Contact:

Re: Accessing an element inside the hmcontent iframe

Unread post by julio »

Thank you for your reply, Tim, but I am still getting an undefined object after that interval. Just to be sure, I am placing this code on section Configuration - Publishing Options - WebHelp - Layout, at the following location:

Code: Select all

<div id="hmcontentbox">
  <script type="text/javascript">
    var defaulttopic="<%HREF_DEFAULT_PAGE%>";
  </script>
  <script type="text/javascript" src="layout_contentbox.js"></script>
  <noscript>
    <iframe name="hmcontent" id="hmcontent" src="<%HREF_DEFAULT_PAGE%>" seamless="seamless" title="Content Page" frameborder="0"></iframe>
  </noscript>
  <script type="text/javascript" src="feedback.js"></script> //<---- Here is my code
</div>
I think this could be a better place than on section Configuration - HTML Page Templates - Feedback, which is the name of the page template that contains the form. But now I am not so sure, maybe the template is the correct location to place it, right before the closing </body> tag.

Thank you for your help.
User avatar
Tim Green
Site Admin
Posts: 23156
Joined: Mon Jun 24, 2002 9:11 am
Location: Bruehl, Germany
Contact:

Re: Accessing an element inside the hmcontent iframe

Unread post by Tim Green »

Hi Julio,

Your script should either be in the head section along with all the other JS references, or all the way down at the bottom, directly before the closing </body> tag. Also put the defer attribute in it like this to make sure that it is not executed until all page assets have loaded:

Code: Select all

<script type="text/javascript" src="feedback.js" defer></script>
Also, what is this:

Code: Select all

<script type="text/javascript" src="layout_contentbox.js"></script>
?? Did you replace the inline code with an external file here? That creates an unnecessary http request in a file that is only loaded once. Please put it back. Similarly, it would make much more sense for your little snippet of code to be inline instead of in an external file. Just put it between script tags down at the bottom of the file, before the closing </body> tag. That eliminates another unnecessary http request.

Also note that anything in the layout page is only going to be loaded and executed ONCE, the first time the WebHelp is accessed by the user. So any binding you put on the button in the topic is going to disappear as soon as the user loads a new topic. What that means is even if you are successful your button will only work in the first topic the user views and then never again, unless you install a complex polling mechanism in the layout page that updates the binding every couple of seconds or whenever a new page is loaded. Instead of trying to manage cross-frame communication like this it would make much more sense to attach your code directly to the button in the topic itself. When your script is inline in the topic page template you can get the address of the current page with:

Code: Select all

<%HREF_TOP_PAGE%>?<%HREF_CURRENT_PAGE%>
That will give you index.html?topic_id.htm.
Regards,
Tim (EC Software Documentation & User Support)

Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
User avatar
julio
Posts: 118
Joined: Wed May 28, 2008 12:06 am
Location: Porto Alegre, RS - Brasil
Contact:

Re: Accessing an element inside the hmcontent iframe

Unread post by julio »

Now I got that, I put the script right after the form and everything is working perfectly fine. Thank you for all your replies!
Post Reply