0 votes
in SoSci Survey (English) by s057462 (330 points)

Hello!
We would like to show a series of pictures in random order, with presenting the picture for 50ms, then hiding the picture and displaying a question, when the participant answered, it should move on to the next picture.
So far we implemented that using the random generator function and combining that with a timer (java script).
The is the php code:

   // loopPage(48) provides a number between 0 and 48 (plus one at every repetition)
$i = loopPage(48);  // Here you can enter the number of images you want to show

// Show the chosen picture
$varID = 'FP01x'.sprintf('%02d', $i + 1);  // Variable IDs are FP01x01 to FP01x20
$img = value($varID, 'label');

// The HTML-Tag <img> shows one image, the filename will be shown with src 
html('
  <div style="margin: 3em; text-align: center">
    <img src="'.$img.'" alt="" />
  </div>
');


// Create the fitting question ID and show the question using question()
question('EM'.sprintf('%02d', $i + 1))

This is the java script code:

   <script type="text/javascript">
<!--
  SoSciTools.submitButtonsHide();
  SoSciTools.attachEvent(window, "load", function(evt) {
  // don't show question and next button
  document.getElementById("EM01").style.display = "none";

  // Start Timer 
  window.setTimeout(next, 50);

  // Hide picture and show question
  document.getElementById("FP01").style.display = "none";
  document.getElementById("EM01").style.display

});
</script>

I'm not sure why the time function does not work in terms of displaying/hiding the picture/question? Any help with this would be much appreciated!
Thank you!
All the best,
Hedwig

2 Answers

+1 vote
by SoSci Survey (304k points)

When working with short presentation times (50 ms = 3 frames on the screen), you should be aware of a few things:

  • The browser requires a fw ms to create the page - depending on the computer this is usually <10 ms.
  • The screen does only refesh 50 or 100 times per second, giving you an inaccuracy of about 16ms.
  • It may require quite some time for the browser to retrieve the image from the server. You shall preload all images to the browser cache before displaying them.
  • If requires longer to display an image for the first time, then to display it, after it has been hidden. If you're working with large images, you may have to display and hide the image, to display them later in the experiment (but on the same page). This is, what the AMP module in SoSci Survey does (only available when bought separately).

So my first suggestion would be to preload the images (Googel will tell you how). Any my second suggestion is that you start with the image hidden (display="none"), and then start you JavaScript not before the page has been loaded (completely, see window.onload). Then let your JavaScript display the image, and hide it after 50 (or 60) ms. Then display the question.

If you use Firefox, you can track the processing times very accurate, using the developer tools.

0 votes
by s057462 (330 points)

Okay, I get the timing issue.
Regarding how to combine the PHO code and the java script, I still seem to do something wrong as the picture is presented with the question at the same time and does not disappear.

On the same page I included first the random generator question (FP01),
then this PHP code that includes the preload now:

// loopPage(48) provides a number between 0 and 48 (plus one at every repetition)
$i = loopPage(48);  // Here you can enter the number of images you want to show

// Show the chosen picture
$varID = 'FP01x'.sprintf('%02d', $i + 1);  // Variable IDs are FP01x01 to FP01x20
$img = value($varID, 'label');

// The HTML-Tag <img> shows one image, the filename will be shown with src 
html('
  <div id="preload">
  <div style="margin: 3em; text-align: center">
    <img src="'.$img.'" alt="" />
  </div>
');

// Create the fitting question ID and show the question using question()
question('EM'.sprintf('%02d', $i + 1));

And then this java script, that now includes hiding the picture first and loading the page thereafter:

<script type="text/javascript">
<!--
  //hide next button
  SoSciTools.submitButtonsHide();

  //hide picture initially
  document.getElementById("FP01").style.display = "none";
  //load page
  SoSciTools.attachEvent(window, "load", function(evt) {
  // don't show question and next button
  document.getElementById("EM01").style.display = "none";
  SoSciTools.submitButtonsHide();

  // Start Timer 
  window.setTimeout(next, 60);

  // Hide picture and show question
  document.getElementById("FP01").style.display = "none";
  document.getElementById("EM01").style.display

});
</script>
by SoSci Survey (304k points)
Please do not ask follow-up questions as responses - I miss those quickly when going throuhg the questions. Better ask a new "related question" - or write a comment. Thanks.

If the JavaScript does not work, always start with cour browser's error console: https://www.soscisurvey.de/help/doku.php/en:create:javascript#troubleshooting - often it's only a misplaced bracket or a missing semicolon that prevents the code from working.

My guess why hiding the picture does not work: Your JavaScript code does not reference the image at all. Give it an ID in the HTML code and use that ID instead of FP01 (currently used in the JavaScript code).

And btw.: The <div id="preload"> in your HTML code is not closed properly. However, I don't think that this line will be of any use, anyway.
by s057462 (330 points)
Yes, sorry, will use the reply function!

I tried to follow those guides and changed the PHP code to this:
//defining the imagine
$img = value($varID, 'label');

// html tag to preload and then show the picture
html('
  <link rel="stylesheet" href="'.$img.'" />
  <div style="margin: 3em; text-align: center">
    <img src="'.$img.'" alt="" />
  </div>
');

// defining the question
$emquestion =('EM'.sprintf('%02d', $i + 1));

// calling the question
question($emquestion);


and I amended the java script as follows:

<script type="text/javascript">
<!--
  //hide next button
  //SoSciTools.submitButtonsHide();
  function showPicture() {
    var picture = document.getElementById($varID);
    picture.style.display = "";
  }

  function showQuestion() {
    var question = document.getElementById($emquestion);
    question.style.display = "";
  }
 
// Start the script after the page is loaded
SoSciTools.attachEvent(window, "load",
  SoSciTools.submitButtonsHide(),
   function() {
    var question = document.getElementById($emquestion);
    // Hide the question
    question.style.display = "none";
    // Start the timer
    window.setTimeout(showQuestion, 4000); // after 4 s
  }
);
</script>

There is still no time delay in picture or question presentation

The console tells me this error:
Did not parse stylesheet at 'https://www.soscisurvey.de/PersonalityRWAemotion/Pic_22.jpg' because non CSS MIME types are not allowed in strict mode.

Do you have a hint, what I need to change to make it work?
Thank you and all the best,
Hedwig
by SoSci Survey (304k points)
> Did not parse stylesheet at 'https://www.soscisurvey.de/PersonalityRWAemotion/Pic_22.jpg' because non CSS

That's causes by your (ruther unusual and not very clean) way of preloading the image. Better try this one: https://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

>  var picture = document.getElementById($varID);

The $varID in this line will not work, because JavaScript does not know about the PHP variables. You could work with placeholders, but in your case, it's even easier. First: Give your image an ID (in the HTML code):

<img src="'.$img.'" alt="" id="imgStim">

Then write this in you JavaScript:

var picture = document.getElementById("imgStim");

For your question, you have to work with a placeholder. In your PHP code write:

replace('%questionID%', $emquestion);

And in your JS code:

var question = document.getElementById("%questionID%");

Then give the error console a new try...
by s057462 (330 points)
Okay, thank you!
I now try to preload the picture in the java script and amended the PHP code as follows:
// html tag
html('
  <div style="margin: 3em; text-align: center">
    <img src="'.$img.'" alt="" id="imgStim"/>
  </div>
');

// Create the fitting question ID and show the question using question()
$emquestion = ('EM'.sprintf('%02d', $i + 1));
replace('%questionID%', $emquestion);
question($emquestion);

This is the new java script:
<script type="text/javascript">
<!--
  //hide next button
  //SoSciTools.submitButtonsHide();

  var images = new Array()
    function preload() {
        for (i = 0; i < preload.arguments.length; i++) {
            images[i] = new Image()
            images[i].src = preload.arguments[i]
        }
    }
    preload(
        "%.img%"
    )


  function showPicture() {
    var picture = document.getElementById("imgStim");
    picture.style.display = "";
  }

  function showQuestion() {
    var question = document.getElementById("%questionID%");
    question.style.display = "";
  }
 
// Start the script after the page is loaded
SoSciTools.attachEvent(window, "load",
  SoSciTools.submitButtonsHide(),
   function() {
    var question = document.getElementById("%questionID%");
    // Hide the question
    question.style.display = "none";
    // Start the timer
    window.setTimeout(showQuestion, 4000); // after 4 s
  }
);

</script>


Now the console error explains that it does not find the image (referring to [Error] Failed to load resource: the server responded with a status of 400 (Bad Request) (%.img%, line 0))
And the timing is still not right.
Sorry, but I have trouble putting all the pieces correctly together.
Thanks for any help!
Best,
Hedwig
by SoSci Survey (304k points)
You have not prepared a placeholder %img% in your PHP code, if I see it correctly. Also, there's a dot after the %. But that's no problem, as you won't need the image name to preload:

var picture = document.getElementById("imgStim");
preload(picture.src);
by s057462 (330 points)
Okay, unfortunately I still don't get the timer to work: the picture and the question both show up from the beginning and the picture does not disappear.
The PHP code I use now is this:

$varID = 'FP01x'.sprintf('%02d', $i + 1);  // Variable IDs are FP01x01 to FP01x20
$img = value($varID, 'label');


// HTML-Tag
html('
  <div style="margin: 3em; text-align: center">
    <img src="'.$img.'" alt="" id="imgStim"/>
  </div>
');

// Create the fitting question ID and show the question using question()
$emquestion = ('EM'.sprintf('%02d', $i + 1));
replace('%questionID%', $emquestion);
question($emquestion);


The java script is as follows:
<script type="text/javascript">
<!--
  //hide next button
  SoSciTools.submitButtonsHide();

   function showPicture() {
    var picture = document.getElementById("imgStim");
    preload(picture.src);
    picture.style.display = "";
  }

  function hidePicture() {
    var picture = document.getElementById("imgStim");
    picture.style.display = "none";
  }

  function showQuestion() {
    var question = document.getElementById("%questionID%");
    question.style.display = "";
  }
 
//SoSciTools.submitButtonsHide(),
// Start the script after the page is loaded
SoSciTools.attachEvent(window, "load",
   function() {
    showImage;
    var question = document.getElementById("%questionID%");
    // Hide the question
    question.style.display = "none";
    // Start the timer
    window.setTimeout(showQuestion, 4000); // after 4 s
    hideImage;
  }
);

</script>


Any help is very much appreciated!
Best,
Hedwig
by SoSci Survey (304k points)
What does the JavaScript console in the browser say?

If it's silent, please post a pretest-link (directly) to the page with the question/code.
by s057462 (330 points)
edited by s057462
The java console says:
[Error] ReferenceError: Can't find variable: showImage
    (anonymous function) (PersonalityRWAemotion:489)

and:
[Error] Failed to load resource: The file “messages.json” couldn’t be opened because there is no such file. (messages.json, line 0)

if I delete the showImage line (that's the function I defined above)
this error comes up:
[Error] TypeError: null is not an object (evaluating 'question.style')
    (anonymous function) (PersonalityRWAemotion:492)
referring to the line
question.style.display="none";

This is the pretest link:
https://www.soscisurvey.de/PersonalityRWAemotion/?act=bcFk4scEUGUfeYSUGXxnW6Dx

Thank you!
by SoSci Survey (304k points)
The error makes sense, as you did not define a funcion shomimage; Replace this line by showPicture();
by s057462 (330 points)
Yes, indeed, I corrected that and the javascript now reads:

   function showPicture() {
    var picture = document.getElementById("imgStim");
    preload(picture.src);
    picture.style.display = "";
  }

  function hidePicture() {
    var picture = document.getElementById("imgStim");
    picture.style.display = "none";
  }

  function showQuestion() {
    var question = document.getElementById("%questionID%");
    question.style.display = "";
  }
 
//SoSciTools.submitButtonsHide(),
// Start the script after the page is loaded
SoSciTools.attachEvent(window, "load",
   function() {
    showPicture;
    var question = document.getElementById("%questionID%");
    // Hide the question
    question.style.display = "none";
    // Start the timer
    window.setTimeout(showQuestion, 4000); // after 4 s
    hidePicture;
  }
);



But I still get an error message:
[Error] TypeError: null is not an object (evaluating 'question.style')
    (anonymous function) (PersonalityRWAemotion:492)
for the line:
    question.style.display = "none";


As well as:
[Error] Failed to load resource: The file “messages.json” couldn’t be opened because there is no such file. (messages.json, line 0)

Why does it not recognise the "question.style,display = "none"; line?
Thank you again for your help.
Hedwig
by SoSci Survey (304k points)
Please note, that it must be showPicture(); instead of showPicture; - the brackets are important, or the function will not be run.

I have only now checked the pretest link. Two things:

(1) The question I get on page 2 (that's the page, we're talking about, is it?) is "TypeError: showQuestion.style is undefined". This relates to a JavaScript code that's a bit different from what you posted:

var question = document.getElementById("EM20");
// Hide the question
showQuestion.style.display = "none";

First change showQuestion to question. And then change "document.getElementById("%questionID%");" to "document.getElementById("%questionID%_qst");", as the HTML element is not named EMxx, but EMxx_qst (see https://www.soscisurvey.de/help/doku.php/en:create:dynamic).

(2) Have you considered a "assignment task" question? This allows for a prime (image) before each selection by default and takes care for the JavaScript itself. Just a thought.
by s057462 (330 points)
I don't get the java script to work, so I try the assignment question with primes.
I did not find any documentation of how to implement the primes, did I miss it in the help / manual pages?
Do I put in the pictures as stimuli or somewhere else?
Thanks for some hints.
Hedwig
by SoSci Survey (304k points)
If you select an item from the assignment task in the navigation on the left, you can specify a priming. Either a text (simply type) or an image, using <img src="image.png">. In the question itself you can set the display duration for the priming.
by s057462 (330 points)
Great, and then I assume that I can use php to add randomised prime pictures? (replacing the img that I now put into the "prime" field?)
by SoSci Survey (304k points)
It should work to use a series of placeholders, i.e., <img src="%image1%" alt="">, and prepare these placeholders with PHP, yes.
by s057462 (330 points)
Brilliant, thank you!
Just one more question: when that question “starts” one of the images flickers on the screen, where could that come from?
See this pretest view:
https://www.soscisurvey.de/PersonalityRWAemotion/?act=YVlzGYR56L8eodod8OAFlPft

Thanks!
by SoSci Survey (304k points)
That's actually not a but, it's a feature: It is not one image that flickers, but all off them (overlayed - reload the page a few times, to see that). This ensures that the images are not only preloaded, but also pre-rendered by the browser when they are needed. It was a learning from out AMP implementations, that the first rendering of an image could take e.g. 20 ms. If your display time is only 50 ms overall, the effective time shrinks to 30 ms.

Pre-rendering unfortunately requires the image to actually appear on the screen. This is why there's a "flicker" before the first item.
by s057462 (330 points)
Okay, got it, thank you!

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...