【问题标题】:vbscript: getref with parametervbscript:带参数的getref
【发布时间】:2012-10-10 17:09:01
【问题描述】:

有没有人将参数传递给使用 getref 调用的函数? 下面的代码只是一个例子,不起作用,如何将参数传递给mySub sub?

<button id="myBtn">Click me</button>

<script type="text/vbscript">
  document.getElementById("myBtn").onclick=GetRef("mySub") 

  Sub mySub(parameter)
   alert(parameter)
  End Sub
</script>

【问题讨论】:

  • 您为什么使用 VBScript 来编写客户端脚本?您的目标浏览器是什么?
  • 纯 IE,顺便说一句,它是用于纯 vbscript 目的(.vbs),我只在客户端浏览器脚本中使用了这个示例,以明确我想要什么。我知道对 IE 和 Vbscript 作为语言的偏见,但在唯一的 IE 公司中,ActiveX 是一种祝福,javascript 很好。但是在一个安全的环境中,该死的有限。我使用很多 js 进行 Web 开发,其余的我想切换到 Ruby,但我的同事当然必须遵循

标签: asp-classic vbscript


【解决方案1】:

首先查看at this article about event handling(有人知道更好的参考吗?)以获取以下内容:

onclick 属性中提供的代码将在 用户单击包含在跨度中的文本。这个机制很棒 对于小的sn-ps代码,但是当你有一个 很多脚本。此事件机制适用于 VBScript 和 JScript。

幕后发生的事情是 Internet Explorer 调用 脚本引擎与脚本代码并告诉引擎创建 一个匿名函数(一个没有名字的函数)。认识的你们 VBScript 可能想知道它是如何做到的,因为 VBScript 不支持匿名函数。 VBScript 实际上创建了一个 包含脚本的名为“匿名”的子例程并返回一个 指向随后连接到事件的函数的指针。

然后用这个 .hta 做实验:

<html>
 <!-- !! http://stackoverflow.com/questions/10741292/vbscript-getref-with-parameter
 -->
 <head>
  <title>GetRef HTA</title>
  <HTA:APPLICATION
    APPLICATIONNAME="GetRef HTA"
  >
  <SCRIPT Language="VBScript">
   Sub SetClickHandlers()
     Set bttB.onClick = GetRef("NoParmsBttB")
     Set bttE.onClick = GetRef("Magic")
     Set bttF.onClick = GetRef("Magic")
   End Sub
   ' trivial handler, literally set
   Sub NoParmsBttA()
     Log "NoParmsBttA() called."
   End Sub
   ' trivial handler, set via GetRef
   Sub NoParmsBttB()
     Log "NoParmsBttB() called."
   End Sub
   ' one handler for many buttons, literally set
   Sub handleClickCD(oBtt)
     Log "handleClickCD() called; you clicked " & oBtt.id
   End Sub
   ' one handler for many buttons, set via Magic() & GetRef
   Sub handleClickEF(oBtt, dtWhen)
     Log "handleClickEF() called; you clicked " & oBtt.id & " at " & CStr(dtWhen)
   End Sub
   ' stuffed via GetRef into onClick
   Sub Magic()
     handleClickEF Me, Now
   End Sub
   Sub Log(s)
     MsgBox s, 0, Now
   End Sub
  </SCRIPT>
 </head>
  <body onLoad="SetClickHandlers">
   <!-- literal onClick handler in html code -->
   <button id="bttA" onClick="NoParmsBttA">A</button>
   <!-- no literal onClick handler, will be set by SetClickHandlers via GetRef() -->
   <button id="bttB">B</button>
   <!-- literal onClick handlers with parameter (Me, i.e. the Button) -->
   <button id="bttC" onClick="handleClickCD Me">C</button>
   <button id="bttD" onClick="handleClickCD Me">D</button>
   <!-- Two params handler via SetClickHandlers & Magic -->
   <button id="bttE">E</button>
   <button id="bttF">F</button>
 </body>
</html>

  1. 那个/如何指定一个不带参数的 Sub 来按字面意思或通过 GetRef(A 和 B)处理点击
  2. 您可以使用一个参数化的 Sub 来处理对许多按钮的点击,因为引擎将文字代码放入匿名 Sub(无参数)(C/D)中
  3. 您不能使用 GetRef("SubWithLotsOfParms") 来设置 onClick 属性 - 它需要没有参数的 Sub
  4. 您可以让不带参数的命名 Sub(例如 Magic)完成引擎的匿名工作;然后这个 Sub 可以与 GetRef 一起使用

WRT Salman A 的回答:

如果你真的需要这样的错误信息:

---------------------------
Error
---------------------------
A Runtime Error has occurred.
Do you wish to Debug?

Line: 54
Error: Wrong number of arguments or invalid property assignment: 'mySub'
---------------------------
Yes   No   
---------------------------

那么你只需要添加:

   Sub mySub(parameter)
     alert(parameter.toString())
   End Sub

   <!-- literal onClick handler in html code -->
   <button id="bttG" onClick="mySub">G</button>

到测试.hta。

WRT Peter 的建议 - 保持简单是值得的:

Option Explicit
Sub WithLotsOfParms(a, b, c, d)
  WScript.Echo Join(Array(a, b, c, d))
End Sub
Dim f : Set f = GetRef("WithLotsOfParms")
WithLotsOfParms 1, 2, 3, 4
f               1, 2, 3, 4

输出:

cscript 01.vbs
1 2 3 4
1 2 3 4

您使用 GetRef() 设置的变量名称与您使用字面量 Sub/Function 名称完全一样,这可能是昨天建立的。

【讨论】:

    【解决方案2】:

    我将如何实现这一目标:

            Dim elem: Set elem = document.getElementById("myBtn")
            elem.setAttribute "parameter", "somevalue"
            Set elem.onclick = GetRef("elem_onclick")
    
            Function elem_onclick()
                MsgBox Me.getAttribute("parameter")
            End Function   
    

    使用分配了 onclick 的元素来携带作为附加属性所需的任何参数。

    【讨论】:

    • +1 用于绕过参数传递问题的创造性和可用方式。
    【解决方案3】:

    安东尼的解决方案很聪明,我接受他的回答。 但是,由于我真正的问题是位于 vbs 而不是客户端脚本中,为了简单起见,我只选择了它作为示例,因此它不是我的解决方案。

    这是我的做法,以供参考。我使用了执行而不是 getref。例如

    execute ("call " & routine & "(parameter)")
    

    编辑:由于 Ekkehard 的评论,我用他的技术尝试了它并且它有效,所以我将使用这个解决方案,而不是我的第一个解决方法,这是我第一次应该问的问题,但我害怕它太复杂了。。 我把答案告诉他。

    sub one(para)
      WScript.Echo para & " from one"
    end sub
    
    sub two(para)
      WScript.Echo para & " from two"
    end sub
    
    sub main(subname, para)
      Dim f : Set f = GetRef(subname)
      f para
    end sub
    
    main "one", "test" '=>test from one
    

    【讨论】:

    • -1 表示复杂的提案完全错过了 GetREf()/'function pointers' 的要点。
    • @Ekkehard,你是对的,但这是一种解决方法,感谢这个完美契合的解决方案,首先不高兴使用执行,这是某种邪恶的评估。我给你答案吧
    • 我收回反对票,因为现在您的回答很好地显示了 GetRef() 的用法。
    【解决方案4】:

    更进一步...

    Dim iGetSub                             'Static'
    Function GetSub(sSub)                   'GetRef wrapper that supports object methods and arguments
    
        iGetSub = iGetSub + 1
        ExecuteGlobal "Sub GetSub" & iGetSub & ": " & sSub & ": End Sub"
        Set GetSub = GetRef("GetSub" & iGetSub)
    
    End Function
    

    因此:

    .onClick = GetSub("MySub(""Hello World"")")
    

    或者:

    .onClick = GetSub("MsgBox(""Hello World"")")
    

    甚至:

    .onClick = GetSub("MyObject.MyMethod(""Hello World"")")
    

    唯一的限制是您不能使用 Me 参考。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多