Skip to main content
Inspiring
October 11, 2018
Answered

Accessing images by ID containing a specific word via external javascript

  • October 11, 2018
  • 3 replies
  • 1443 views

Hi everyone, I'm working in Captivate 2017 on a responsive project. What I'm trying to accomplish is take a piece of code which 'zooms' (translates position and scale via GSAP API) images via one function that targets all images by whether or not their id contains the word 'image'. I've created something that 'zooms' images using GSAP already, but the difference is I made each image page a .zip file containing an html, css, and js page. This was nice as I could control the css and html of the images, however, loading a .zip file on each slide with an image can take a minute and sometimes images don't load right away.

I'm wondering if I can do the same effect, however with one external JS file that I'll load into my index.html file after publish. I'm having a hard time calling/accessing images with an id that contains the word 'image' however. I'm not an expert coder by any means and I've had a lot of help from forums to get as far as I am, but essentially the code I'm using looks like this:

var targets = document.querySelectorAll('[id^="image"]');

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

  var tl = new TimelineMax({ paused: true, reversed: true });

  tl.to(targets, 0.6, { x: 100, y: 100 }, 0);

  targets.anim = tl;

  targets.addEventListener("click", function() {

    this.anim.reversed() ? this.anim.play() : this.anim.reverse();

  });

}

This method using document.querySelectorAll returns the variable 'target' in the console log as a node list with the length of 0 (even when on a slide that has an image on it). So I've tried another method:

var targets = $("img[id*=\"image\"]");

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

  var tl = new TimelineMax({ paused: true, reversed: true });

  tl.to(targets, 0.6, { x: 100, y: 100 }, 0);

  targets.anim = tl;

  targets.addEventListener("click", function() {

    this.anim.reversed() ? this.anim.play() : this.anim.reverse();

  });

}

I've tried this using $("img .... and $("div .... as I'm not sure what HTML tag captivate assigns to images? Neither of them seem to pick up my image with the id of "image43"  however. In the console log it returns as "m.fn.init [prevObject: m.fn.init(1), context: document, selector: "img[id*="image"]"]" with a length of 0.

Anyone have an idea as to how I can call my images based off of their id and if it contains the word image? Or if I could do the same thing by calling whatever class name captivate assigns to images (how would I figure out what that is)? Thanks!

This topic has been closed for replies.
Correct answer TLCMediaDesign

I'm sorry to be so helpless, but I've added this into my external JS file (and add the js file in via the index.html), I'm still not having my images animate - are there any errors you see here? 

 

var interfaceObj;

var eventEmitterObj;

window.addEventListener("moduleReadyEvent", function(evt){

interfaceObj = evt.Data;

eventEmitterObj = interfaceObj.getEventEmitter();

});

 

if(interfaceObj){

if(eventEmitterObj){

eventEmitterObj.addEventListener("CPAPI_SLIDEENTER", function(){

var targets = $("div[id*=\"image\"]");

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

var tl = new TimelineMax({ paused: true, reversed: true });

tl.to(targets, 0.6, { x: 100, y: 100 }, 0);

targets.anim = tl;

  targets.addEventListener("click", function() {

  this.anim.reversed() ? this.anim.play() : this.anim.reverse();

   });

}

})

}

}


Yes, in the window.addEventListener( 'moduleReadyEvent...

You need to add a function call at the end:

initializeEventListeners();

and then wrap the:

if ( interfaceObj.. in the function:

function initializeEventListeners() {

id ( interfaceObj

So what happens is that when Captivate fires the moduleReadyEvent, it then calls the function to set up the slide enter listener.

You code is setting up that listener before it's available.

3 replies

KeelyMAuthor
Inspiring
October 12, 2018

Adding to this in case anyone runs into doing the same thing - once I got the SLIDEENTER listener working (big thanks to TLCMediaDesign), I was having some issues with my GSAP timeline not targeting the right images. When I was using "targets" as my object in my GSAP timeline (please reference code I've pasted in above), no images were tweening. I then tried changing it to simply "targets" and that worked, but if there were multiple images on the slide it would tween ALL of them. I think this has something to do with captivate giving each image multiple ids (i.e. the whole "image43" and "image34c" thing), so when calling just one of them with "targets" it wasn't doing anything, because the image has two id's???? I'm not really sure about that part, but I looked at my console.log list for "targets" and after some guessing, figured out that it splits the output up, so if you have two images on the screen it will have both image's 'normal' ID first then both images 'c' appended ID. So I changed my GSAP target to be multiple targets which are "targets, targets[i-2]" and so far, with only TWO images on the page that is working - haven't tested with more than two images. But anyways, hope this helps someone out. It's pretty specific to GSAP, but in case anyone else out there is using it in their CP projects.

UPDATE: realized that since each image has 2 id's and they separated based on id type, it should always(?) be an even number, so I added this to my code:

var num = targets.length/2;

then changed my gsap targets to

[targets[i-num], targets]

and so far so good! Have tested with only up to 3 images on one slide though.

TLCMediaDesign
Inspiring
October 12, 2018

Where is this JS being run from?

Is it in an external JS file?

If I get what you are saying, the images are in an iFrame if they are in the zip package.

You need to wrap the script iin a timer, setInterval to see when the iFrame is loaded, then access the iFrame content.

KeelyMAuthor
Inspiring
October 12, 2018

What I'm trying to do currently is run the JS from an external file (then load that js file in via the published index.html file). The images I just added as you would normally add into Captivate, are they still in an iFrame then? 

 

The method I used before was to add the images in via a zip file that contained an html, css, and js file. I'm trying to see if I can do the same effect without adding a .zip file and just controlling the images added in via the Captivate library through an external JS file. 

TLCMediaDesign
Inspiring
October 12, 2018

Did you keep it in an external JS file or modify the published index.html file? 


It's in an external US file. I have them in the templates directory in the CP source files so every time I publish it's already there. I also edit the index to have the include statement.

Lilybiri
Brainiac
October 12, 2018

Since you insist on JS, did not want to answer. But I use one of the

features of CpExtra widget in that case.