.focus 没有原地踏步

Posted

技术标签:

【中文标题】.focus 没有原地踏步【英文标题】:.focus not staying put 【发布时间】:2015-07-08 14:00:24 【问题描述】:

我在我的 SSJS 脚本库中保存了一个验证例程。当我点击保存按钮时它会被调用。目的(如这里的几篇文章所示)是执行表单验证,创建错误消息,然后 onClientLoad 事件将显示消息并将焦点返回到它找到的第一个问题字段。

这里是sn-ps的代码;来自 SSJS 脚本库:

function DBValidate(FormName:String) 
	var efn:string = null;		// error Field Name
	var errorMessages:String = null;
	
	// here is where we group validation by the calling form.
	switch (FormName) 
		case "FieldDef":
		if ( isEmpty(currentDocument.getItemValue("FormName")[0]) ) setError("FormName","Form name cannot be blank");
		if ( isEmpty(currentDocument.getItemValue("EnglishFormName")[0]) ) setError("EnglishFormName","English form name cannot be blank");
		break
		default:
	
	// We built the error messages (All will be displayed in a promptbox in the onClientLoad event 
	// of the form) The form MUST have an ErrorMessage field because we embed carriage returns 
	// in the message and viewScope.get doesn't like those too much..... We can however pass 
	// the error field(for focus if I ever get that working.....)in a viewScope variable.
	getComponent("ErrorMessage").setValue(errorMessages);
	viewScope.put("errorField",efn);
	if (errorMessages == null ) 
		return true;
	 else  
		return false;
	

function setError(fName:string,emsg:string)
	// after failing a field validation in DBValidate we
	// make note of the field name and build the error message that
	// we're going to display in the onClientLoad event.
	// Make note of the first field ID to fail so we can
	// set focus to it.
	if (efn==null) efn=getClientId(fName);
	if (errorMessages == null) 
		errorMessages = String.fromCharCode(10) + emsg;
	 else 
		errorMessages += String.fromCharCode(10) + emsg;
	
	return
	<xp:eventHandler event="onClientLoad" submit="false"
		refreshMode="norefresh">
		<xp:this.script>
			<![CDATA[
				// the DBValidation routine sets the ErrorMessage computed field to something
				// if there was an error. If we had one, then we display a message, extract the field
				// name from the message.
				var em = XSP.getElementById("#id:ErrorMessage").innerhtml;
				if (em.length > 0)  
					alert(em);
					var efn = '#javascript:viewScope.get("errorField")';
					var ef = dojo.byId(efn);
					ef.focus();
				
			]]>
		</xp:this.script>
	</xp:eventHandler>

ef.focus() 确实有效。我可以看到光标闪到第一个有错误的字段,但随后消失了。

我不知道是什么原因造成的。我尝试在调试器中跟踪,但是在退出 onClientLoad 事件后,我开始徘徊在非常密集的代码中(显示 UI 的上半部分是灰色的,所以我真的不知道什么时候应用焦点然后删除。我没有定义任何其他事件。

【问题讨论】:

如果您有两个或更多错误,它会尝试循环遍历所有错误吗?(甚至非常快) 它循环遍历将错误消息存储在 errorMessages 字段中的任何错误。在 setError 例程中,我通过获取 viewScope 变量获取了在“efn”字段中遇到错误的第一个字段的 ID,该字段在我的 onClientLoad 事件中得到。调试器显示我正在返回正确的字段并且焦点命令正在工作,我看到垂直的黑色光标线暂时出现在该字段中,但随后它消失了。 onClientLoad 事件之后发生了一些事情 只是为了好玩,请尝试在 if 语句后添加“return false”行 您的代码是在“客户端”onClientLoad 还是“服务器”onClientLoad 中?它看起来在服务器端,但 XSP.getElementByID 是客户端。我从未尝试过,但我认为 XSP 类和方法在 SSJS 中不起作用。 你是不是打算把这个加到Client端,不小心放到了Server端,好办?? 【参考方案1】:

请在ef.focus() 行之后添加return false。这将立即停止执行任何服务器端代码。

【讨论】:

【参考方案2】:

我遇到过类似的问题,其中一些“幕后道场魔法”正在发生 - 因此转移了焦点。

我解决它的方法有点“hack”,我使用客户端超时功能将焦点设置延迟 100-200 毫秒。

不理想,但我放弃了让它直接工作的尝试;-)

/约翰

【讨论】:

我将代码替换为;设置超时(函数()ef.focus(),300)。我不认为这是它。以前的尝试,我硬编码字段名称而不是使用 dojo 函数。结果相同。 嗯...好的。那只是一个快速的尝试;-)

以上是关于.focus 没有原地踏步的主要内容,如果未能解决你的问题,请参考以下文章

五年了还在原地踏步咋整?

2018.5.3

10年手动测试仍原地踏步?是该好好反思了

无语!你竟然连CompletableFuture都不知道,还天天说在jdk8原地踏步~

行业发展过快?你还在原地踏步?掌握这些关键技能就显得尤为重要了

机器人(自动化)等专业课程创新的结果