Use JavaScript to set onclick event
Copy link to clipboard
Copied
I'm trying to set an onclick event using JavaScript to a Cp smart shape called "item_01".
When I look at the HTML that is generated the shape does indeed have an onclick event attached but Cp "covers" it with at least two other shape-related elements making it impossible for "item_01" to get clicked by the user.
How can I use JavaScript to attach an onclick event to a smart shape that gets triggered by the user clicking the smart shape?
Copy link to clipboard
Copied
Do you have the smartshape "use as button" option selected?
Copy link to clipboard
Copied
Yes, the smart shape is marked as 'use as button'.
Copy link to clipboard
Copied
So basically you have a smartshape, used as a button, and you don't have any objects covering it and you cannot click it?
I've found in a few instances, that other elements on the screen can cover other objects, like the div is actually much bigger than the object inside the div.
You can try putting the smartshape at the top of the timeline to see if the stacking order changes.
You can attach event listeners to any object with JS just as you would with a normal HTML page using:
document.getElementById("instancename").addEventListener("click", function(){
doSomething;
});
But I imagine it still wouldn't be clickable since CP is covering it somehow. I use smartshapes all the time and I've only had issues when it is the last object in the slide array of elements or if I've cloned and object.
You could also use the interactiveItemSubmit listener. e.Data will have the name of the element you clicked.
Copy link to clipboard
Copied
I tried it at the top of the timeline and it made no difference.
Interestingly the event "onmouseover" triggers.
You write "interactiveItemSubmit listener e.Data" like I should know what it is 😉 Can you tell me how to use it or at least find out about it?
Copy link to clipboard
Copied
All of the available events available in the Common JS Interface are listed here:
Learn about the Common JavaScript interface for Adobe Captivate
You can add the listener like the example below:
eventEmitterObj.addEventListener( 'CPAPI_INTERACTIVEITEMSUBMIT', interactionFunction, false )
function interactionFunction( e )
{
console.log( e.Data );
}
Copy link to clipboard
Copied
Thanks for the info and pointers but still I can't get it to respond to a click. I have this code:
if (window.cpAPIInterface && window.cpAPIEventEmitter) {
window.cpAPIEventEmitter.addEventListener("CPAPI_SLIDEENTER", initClick, false);
window.cpAPIEventEmitter.addEventListener('CPAPI_INTERACTIVEITEMSUBMIT', initFunc, false);
}
function initFunc(e) {
console.log(e.Data);
}
function initClick() {
console.log("try to set click");
document.getElementById("item_1").addEventListener("click", function() {
console.log("item has been clicked");
}, false);
}
And in the console I get no errors and "try to set click" appearing.
And when I click item_1 the console gives me
Object {itemname: "item_1", frameNumber: 31, objecttype: 612, issuccess: true, slideNumber: 1…}
but "item has been clicked" never appears.
console.log ( document.getElementById("item_1") ) gives
<div id="item_1" class="cp-frameset" tabindex="2500" style="outline-style: none; z-index: 0; -webkit-tap-highlight-color: rgba(0, 0, 0, 0.298039); display: block; left: 191px; top: 85px; width: 137px; height: 63px; visibility: visible; cursor: pointer;"><div id="item_1accStr" class="cp-accessibility"><p>Test</p></div></div>
so I know it can see it but I can't seem to be able to click on it despite e.Data saying that I am.
Copy link to clipboard
Copied
So the interactive item submit is working and that is what you want.
Copy link to clipboard
Copied
No. While e.Data is showing that "item_1" is being clicked, doing so never triggers
document.getElementById("item_1").addEventListener("click"...
Copy link to clipboard
Copied
I works for me. I added the eventlistener in the slideenter event.
I don't know where you have the initial code to check the interface but it could be that the element isn't in the DOM yet.
I always use the slideenter event ot attach all event listeners. Even them some elements may not be in the DOM, iFrames seem to lag. I use a timeout for those.
Copy link to clipboard
Copied
Hmm, I have the slideenter event calling initClick which then sets the click event for "item_1". So it should work???
I'll try setting with a timeout.
Copy link to clipboard
Copied
This is the code is used, all logs were in the console:
var interfaceObj, eventEmitterObj;
window.addEventListener( 'moduleReadyEvent', function ( e )
{
interfaceObj = e.Data;
eventEmitterObj = interfaceObj.getEventEmitter();
initializeEventListeners();
});
function initializeEventListeners()
{
if ( interfaceObj )
{
if ( eventEmitterObj )
{
eventEmitterObj.addEventListener( 'CPAPI_SLIDEENTER', function ( e )
{
window.cpAPIEventEmitter.addEventListener("CPAPI_SLIDEENTER", initClick, false);
window.cpAPIEventEmitter.addEventListener('CPAPI_INTERACTIVEITEMSUBMIT', initFunc, false);
function initFunc(e)
{
console.log(e.Data);
}
function initClick()
{
console.log("try to set click");
document.getElementById("item_1").addEventListener("click", function()
{
console.log("item has been clicked");
}, false);
}
});
}
}
}
Copy link to clipboard
Copied
It still doesn't work!
Is it because I'm entering the code into Cp's javascript window and not as an external file?
Copy link to clipboard
Copied
I would imagine that's the reason. Your best bet is not to use the JS window except to call functions in an external script file. Everything in the JS Window is converted to a string in the CPM.js. It doesn't always work correctly with all of the escapes. It also doesn't recognize spaces in a functions arguments.
Copy link to clipboard
Copied
I'm now using an external js file and 'click' is still not triggering but when I changed the event to 'mousedown' it did, sort of, trigger.
With a bit more testing I discovered that:
- a smart shape that's used as a button does not trigger onclick, even though it shows up in e.Data
- a smart shape that's not used as a button does trigger onclick
- a smart shape that's used as a button does trigger onmousedown but not on first click???
- a smart shape that's not used as a button does trigger onmousedown
It seems weird but I guess that's just a Fact Of Life (FOL) with Cp.
Thanks for all the help. I'm now going to look at tracking pixel coordinates to capture a click event on (rectangular) smart shapes used as buttons.
Copy link to clipboard
Copied
If the interactiveitemsubmit is triggering, the all you need to do is ask what item was clicked and execute your action.
if ( e.Data.itemname == 'item_1' )
{
doSomething;
}
else
{
return false;
}
Copy link to clipboard
Copied
In my testing on Chrome the problem with that is that if I click on a non interactive element then the interactive element at the bottom of the timelime triggers e.Data irrespective of whether it was clicked or not.
Copy link to clipboard
Copied
I have noticed that also. You can try putting an clickbox or smartshape used as a button with no action named "dummy" at the bottom of the timeline then check if dummy is clicked.
if ( e.Data.itemname != 'dummy' )
{
if ( e.Data.itemname == 'item_1' )
{
doSomething;
}
}
else
{
return false;
}
Copy link to clipboard
Copied
Should a smart shape at the "bottom" of the timeline trigger an click event when it has not been clicked??? I've no doubt that you're workaround will work but what a silly way for Cp to work. My guess (without working through the JSON) is that Cp is capturing the click on the document and then checking what elements are under the clicked and then if there's no element to accept it erroneously passing it to the last/bottom interactive element.
I'm close to having the tracking of pixel coordinates to capture a click event on (orthogonal aligned and rectangular) smart shapes used as buttons working reliably. I've just got to sort out a layering issue I'm having and then adding a check for whether the element is enabled or not.
Thanks for verifying what I'm seeing.

