gpt4 book ai didi

javascript - 如何让听者在手机屏幕上拉下或拉下时始终工作?

转载 作者:行者123 更新时间:2023-12-04 13:28:02 26 4
gpt4 key购买 nike

我正在开发一个小图书馆来进行心理实验。您可以现场试用here并尝试以下代码段中的代码。

var selfConcept = (function() {
//privates
var activeListenerStepNames = [];
var accuracyFeedbackDuration = 400;
var blankInterval = 1500;
var clickListenerHandler = function(e) {
buttonTouched = '';

switch (e.target.id) {
case 'd-button':
buttonTouched = 'D';
break;
case 'k-button':
buttonTouched = 'K';
break;
}

e.data = buttonTouched;

window.performance.mark(markName);
window.performance.measure(measureId, generateMarkName('start'), markName);

responseTimes.push({
'stepId': currentStep,
'stimulus': steps[currentStep]['stimulus'],
'responseTime': window.performance.getEntriesByName(measureId)[0]["duration"],
'key': e.data
});

//fix for Android
document.getElementById("hidden-input").value = '';

drawSetting();
nextStep();
};
var currentStep = 0;
var fixationCrossDuration = 1000;
var frameId;
var keyListenerHandler = function(e) {

if (String.fromCharCode(e.keyCode) == 'D' || String.fromCharCode(e.keyCode) == 'K') {
window.performance.mark(markName);
window.performance.measure(measureId, generateMarkName('start'), markName);

responseTimes.push({
'stepId': currentStep,
'stimulus': steps[currentStep]['stimulus'],
'responseTime': window.performance.getEntriesByName(measureId)[0]["duration"],
'key': String.fromCharCode(e.keyCode),
});

isAccuracyFeedbackDisplayed = false;
removeListener(window, 'input', markName, keyListenerHandler);

nextStep();
}
};
var spaceListenerHandler = function(e) {
if (String.fromCharCode(e.keyCode) == ' ') {
e.preventDefault();
removeListener(document, "keydown", markName, spaceListenerHandler);
drawSetting();
nextStep();
}
}
var isAccuracyFeedbackDisplayed = false;
var measureId;
var responseTimes = [];
var steps = [];
var groupInstruction;

function addListener(element, event, name, eventFunction) {
element.addEventListener(event, eventFunction);
activeListenerStepNames.push(name);

//console.log(activeListenerStepNames);
}

function drawSetting(text, color, background) {
text = (text === undefined) ? '' : text;
color = (color === undefined) ? 'black' : color;
background = (background === undefined) ? 'white' : background;

workAreaDiv = document.getElementById("work-area");
workAreaDiv.innerHTML = "";

div = document.createElement('div');

div.id = 'stimulus';
div.style.color = color;
div.innerHTML = text;
div.style.fontSize = '280%';

div.style.class = 'col';

workAreaDiv.appendChild(div);
}

function fixForMobilePhones() {
$('#work-area-container').removeClass('h-100').addClass('h-75');
$('#container').append('<div class="row h-25"><div id="d-button" style="background-color: black; color: white; border-right: 1px solid white;" class="col-6 text-center"><h1>NO</h1></div><div id="k-button" style="background-color: black; color: white;" class="col-6 text-center"><h1>YES</h1></div></div>');

addListener(document.getElementById("d-button"), 'click', markName, clickListenerHandler);
addListener(document.getElementById("k-button"), 'click', markName, clickListenerHandler);
}

function generateMarkName(name) {
return name + '-' + steps[currentStep]["type"] + '-' + currentStep;
}

function isMobile() {
if (navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPad/i) ||
navigator.userAgent.match(/iPod/i) ||
navigator.userAgent.match(/BlackBerry/i) ||
navigator.userAgent.match(/Windows Phone/i)
) {
return true;
}

return false;
}

function nextStep() {
var nextStep = currentStep + 1;

if (nextStep in steps) {
currentStep = nextStep;
markName = generateMarkName('start');
window.performance.mark(markName);
//console.log("mark - markName:"+markName);
} else {
window.cancelAnimationFrame(frameId);
frameId = undefined;

alert('end');
}
}

function randomizeSteps() {
words = ["word1", "word2", "word3", "word4", "word5", "word6", "word7", "word8", "word9", "word10"];
trials = [];

index = 0;
for (index = 0; index < words.length; index++) {
trials.push({
'id': index,
'type': 'trial',
'stimulus': words[index]
});
}

instructions = [

{
'type': 'duration',
'stimulus': '',
'duration': blankInterval
},
{
'type': 'duration',
'stimulus': '+',
'color': 'black',
'duration': fixationCrossDuration
},
{
'type': 'duration',
'stimulus': '',
'duration': blankInterval
}
];

trials = shuffleArray(trials);

trialsWithBlankInterval = [];

for (itemIndex = 1; itemIndex < trials.length; itemIndex++) {
trialsWithBlankInterval.push(trials[itemIndex]);
trialsWithBlankInterval.push({
'type': 'duration',
'stimulus': '',
'duration': fixationCrossDuration
});
}

steps = instructions.concat(trialsWithBlankInterval);
}

function removeListener(element, event, name, eventFunction) {
element.removeEventListener(event, eventFunction);
activeListenerStepNames.splice(activeListenerStepNames.indexOf(name), 1);
}

/* function copied from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array */
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}

return array;
}

function startTimer() {
frameId = requestAnimationFrame(startTimer);
window.performance.mark('frame');
measureId = 'measure-' + currentStep;

// console.log("TYPE:"+steps[currentStep]["type"]);

if (isMobile() == true && $('#work-area-container').hasClass('h-100')) {
fixForMobilePhones();
}

switch (steps[currentStep]["type"]) {
case 'instructions':
document.getElementById("work-area").classList.remove('text-center');
document.getElementById("work-area").classList.add('text-justify');

document.getElementById("work-area").innerHTML = steps[currentStep]["html"];

if (activeListenerStepNames.indexOf(markName) == -1) {
addListener(document, 'keydown', markName, spaceListenerHandler);
}

break;

case 'duration':
document.getElementById("work-area").classList.remove('text-justify');
document.getElementById("work-area").classList.add('text-center');
drawSetting(steps[currentStep]["stimulus"]);

window.performance.measure(measureId, generateMarkName('start'), 'frame');
performanceEntries = window.performance.getEntriesByName(measureId);

var max = 0;
for (var i = 0; i < performanceEntries.length; i++) {
if (parseInt(performanceEntries[i]["duration"]) > max)
max = performanceEntries[i]["duration"];
}

if (max >= steps[currentStep]["duration"]) {
//console.log('step: ' + currentStep);
//console.log(performanceEntries[performanceEntries.length - 1]["duration"]);
nextStep();
}

break;

case 'trial':
document.getElementById("work-area").classList.remove('text-justify');
document.getElementById("work-area").classList.add('text-center');
drawSetting(steps[currentStep]["stimulus"], steps[currentStep]["color"], steps[currentStep]["background"]);

markName = generateMarkName('response');

if (activeListenerStepNames.indexOf(markName) == -1) {
//console.log(activeListenerStepNames);
addListener(document, 'keydown', markName, keyListenerHandler);
}

break;
}
}

//public
return {
init: function() {
randomizeSteps();

markName = generateMarkName('start');
window.performance.mark(markName);
console.log("INIT");
startTimer();
}
}
})();

selfConcept.init();
html,
body {
height: 100%;
font-size: 100%;
}

.container {
height: 100%;
}

input.transparent {
opacity: 0;
filter: alpha(opacity=0);
}

.text-overflow {
overflow: auto;
-webkit-overflow-scrolling: touch;
}

.likert .row>.col,
.likert .row>[class^="col-"] {
padding-top: .75rem;
padding-bottom: .75rem;
background-color: rgba(86, 61, 124, .15);
border: 1px solid rgba(86, 61, 124, .2);
}
<div id="container" class="container">

<div id="work-area-container" class="row h-100 text-overflow">
<div class="col my-auto">
<div id="work-area" class="w-100 mx-auto text-justify"></div>
<input id="hidden-input" class="transparent" type="text" readonly="readonly">
</div>
</div>

</div>

用户必须根据两个或多个选项(在示例中:“否”和"is")对出现在屏幕中间的刺激进行分类。我必须以毫秒为单位测量从刺激出现的那一刻到用户键盘(或点击手机)上的按键的延迟。
为了实现这个目标,我使用了 Web API,特别是 Performance目的。此外,我使用 Bootstrap4 使其响应。台式机或笔记本电脑上的浏览器一切正常:用户可以使用键 D(意思是“否”)和 K("is")对刺激使用react。
我向您求助的问题只发生在手机上,手机的应答模式基于两个可见按钮:“否”和"is"。我注意到,当我无意中向上或向下滑动屏幕(尤其是多次这样做)时,听众不再起作用。就像窗口失去焦点一样,所以我必须在按钮上点击两次才能使它们工作(我想第一次再次获得焦点,第二次触发事件)破坏了延迟时间的测量。
我试图通过以下方式解决这个问题,但它不起作用:
document.addEventListener('touchstart', this.touchstart);
document.addEventListener('touchmove', this.touchmove);

function touchstart(e) {
e.preventDefault();
}

function touchmove(e) {
e.preventDefault();
}
编辑:
我还尝试了以下受 TheMindVirus's suggestion 启发的修复程序
var lastScrollPosition = 0;
window.onscroll = function(event)
{
if((document.body.scrollTop >= 0) && (lastScrollPosition < 0))
{
// first try
window.focus();

// second try after having assigned tabindex='1' to the div "work-area-container"
$('#work-area-container').focus();
}

lastScrollPosition = document.body.scrollTop;
}
我该如何解决问题?非常感谢。

最佳答案

selfconcept.js 中的事件监听器和处理程序看起来不错,但是代码片段中的两个是错误的。必须有普通的函数调用:

document.addEventListener('touchstart', touchstart);
document.addEventListener('touchmove', touchmove);
您可以在浏览器控制台中看到文件名和行号的错误:
test.html:51
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.
这意味着“这个”在这里不起作用......
我测试了你的测试页:
Galaxy S4 (Android 5):
  • 歌剧迷你(作品)
  • firefox(作品)
  • Chrome (白屏)
  • 三星浏览器(白屏)

  • Galaxy S7 (Android 7):
  • firefox(作品)
  • Chrome (作品)
  • 三星浏览器(作品)

  • iPhone 4s (IOS 9.3.5)
  • safari(白屏)

  • 我认为问题很可能不是您的代码,而是您的手机或浏览器...

    关于javascript - 如何让听者在手机屏幕上拉下或拉下时始终工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66934246/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com