• 締切済み

JscriptでsetTimeout

JscriptでIEを操作してあるページのリンクをクリックしたいです。 リンクにjavascriptが入っているため同期処理でクリックすると、 その先に進みません。 そのため非同期処理でクリックしたく、setTimeoutを使って 関数を作りましたが動きません。 setTimeout('function ck(ie,ID){ ie.document.querySelector(ID).click();}',10); ※ieはIEオブジェクト、iDはリンクのID属性です。 ちなみに上記をVBAから呼び出して動かしています。 setTimeoutをはずせば普通に動きました。 setTimeoutはwindowオブジェクトが必要なので、 それを省略しているのが悪いとも考えましたが、 VBAでどうやってIEのwindowオブジェクトを作るのかが分かりません。 setTimeout以外にも非同期実行できる方法があれば それでも構いません。 どうかご教授お願いいたします。

みんなの回答

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.1

setTimeout の第1引数は object または、関数名の文字列、です。関数宣言を文字列で与えてもobjectにはなりません。 文字列にせず、関数宣言 を書くと関数objectになり、これを無名関数といいます。 しかし引数を与えると実行してしまうので、実行結果が関数objectになるようにしなければならないので、return にさらに関数宣言を書くということになる。 よって、無名関数を2重に書く形になる。 まず、外側は、関数宣言を()で括ってさらに引数を与える(ie,ID)をつける  (function(ie,ID) { })(ie,ID)  この関数は、setTimeout行の引数判定時点で実行される。 次にこの関数の内部では return function(){} ; で引数無しの関数objectを返す この関数objectが setTimeoutに対する第1引数としてわたされる。この関数objectは、setTimeoutの第2引数で指定した時間経過後に実行される。 全体を見やすく、改行と字下げをつけると以下のように。 setTimeout(  (function(ie,ID) {   return function(){    ie.document.querySelector(ID).click();   };  })(ie,ID) , 10); // 全角空白で字下げしてるので、半角空白に置換または削除して実行ソースとすること // 外側の関数を省略すると、ieとID変数がメモリリークとなるので注意のこと。

momomo100
質問者

補足

ありがとうございます。 VBAから呼び出すためには関数名が必要みたいだったので、 以下のようにしてみました。 function clk(ie,id) { setTimeout(  (function (ie,id) { return function () { ie.document.querySelector(id).click(); }; })(ie,id) , 10); } これを変数ieを省略してIEのF12ツールで試したところ 問題なく動きました。 しかしVBAから呼び出ししようとすると js.CodeObject.clk IE, IDの部分でオブジェクトがありませんの エラーが出てしまいます。 ※js.CodeObject.関数名 引数1, 引数2で 変数cdに入っているJscriptを呼んでいます。 URLは非同期処理じゃないとクリックしても 進まないサイトがあったのでお借りしました。 どうか引き続きご教授お願いいたします。 Sub click_test() Dim IE As InternetExplorer Dim js As New ScriptControl js.Language = "JScript" Dim cd As String cd = cd & "function clk(ie,id) {" cd = cd & "setTimeout(" cd = cd & "(function (ie,id) {" cd = cd & "return function () {" cd = cd & "ie.document.querySelector(id).click();" cd = cd & "};" cd = cd & "})(ie,id)" cd = cd & ", 100);" cd = cd & "}" js.AddCode (cd) Set IE = CreateObject("InternetExplorer.Application") IE.Visible = True IE.Navigate "http://kamicha1.web.fc2.com/Excel/Test20090726.html" Do While IE.Busy Or IE.readyState < READYSTATE_COMPLETE DoEvents Loop Dim ID As String ID = "#popOK" js.CodeObject.clk IE, ID msgbox"OK" End Sub

関連するQ&A

  • VBAからjavascriptに値を渡す

    VBAでIEを操作しております。 一部javascriptを使って以下のようなコードで、リンクをクリックしています。 ie.document.Script.setTimeout "javascript:document.getElementById(""ID"").click()}", 10 getElementById(""ID"")のID部分を変数にしたいのですが、 Dim ID as String ID=○○ ie.document.Script.setTimeout "javascript:document.getElementById(○○).click()}", 10 としてもうまく動きません。 javascriptの中身をfunctionにして、引数に○○を持っていっても動きませんでした。 どうすれば引数を渡すことができますか。 jscriptを使えばできそうな気がしたのですが、 js.CodeObject.関数名(引数)で渡せる引数が1つだけ?のようで こちらも頓挫しております。どうかご教示お願いします。

  • setTimeoutでループしたいのですが…………

    下記コード例(jQuery)で、「hoge1」「hoge2」に対する処理をずっと続けたいのですが、どうすればよいでしょうか? ・再帰処理? ・それはどう書けば良いでしょうか? $(function(){  $(window).load(function(){   setTimeout(function(){    $('#hoge1').animate({略},150,'linear',function(){     $('#hoge2').animate({略},150,'linear',function(){     });    });   },1000);  }); });

  • 子画面を自動で閉じた後、親画面を再描画するJavaScriptが・・・・

    IEだと動くんですけど、Netscapeだと動かないんです。なんかsecurityErrorが出まして・・・。子画面を閉じるまでは動いてるんですが、親の再描画の部分でエラーが出てるようです。どこが原因かお分かりになる方いらっしゃいますか?よろしくお願いします。 <%//処理を何秒後に行うか 時間をset%> function setTimer(){ timer1=setTimeout("clo()",3000); timer2=setTimeout("location()",3000); } <%//windowをclose%> function clo(){ window.close(); } <%//親画面を再描画する%> function location(){ var url='<html:rewrite page="/hogehoge/hoge.do" />'; window.opener.location.href = url+'?member_id='+変数; }

  • setTimeoutでオブジェクト表示非表示の切替

    ・setTimeoutでオブジェクトの「表示」「非表示」切替は出来るでしょうか? ・ページを更新しないと出来ない、とかあるのでしょうか? ・クリック処理等をせずに、自動で切り替える処理があれば知りたいです。 ・例えば、5秒間隔ぐらいで、指定要素の「表示」「非表示」自動切替をしたいのですが… ・jQueryは使っても使わなくても良いです

  • オブジェクト指向のsetTimeoutの呼び出し方法

    オブジェクト指向を勉強中です しかし今一しっくりきません。 setTimeoutの呼び出し部分の記述は、これでいいのでしょうか? やりたいことは、沢山の画像を一度に違ったタイミングでフェードアウト・インをすることです。 <html> <body> <img src="./img/1.gif" width="50" height="50" id="a"> <img src="./img/2.gif" width="50" height="50" id="b"> <input type="button" value="pp" onClick="img2.fin(10,50)"> <script> var img1 = new ImageEffect( 'a',100 ); img1.fout(10,30); var img2 = new ImageEffect( 'b',100 ); img2.fout(5,30); function ImageEffect( id,val1 ){ var func=[]; this.obj = document.getElementById( id ); this.opacity=(val1==undefined)? 100:val1; this.opacitySet = function(n){ this.obj.style.filter='alpha(opacity='+n+')'; this.obj.style.MozOpacity=n/100; this.obj.style.opacity=n/100; this.opacity = n; } this.fout = function(step,wtime){ func[id] = this; this.opacity-=step; if(this.opacity<1) this.opacity = 0; this.opacitySet(this.opacity); if( this.opacity ) setTimeout( function(){ func[id].fout( step, wtime);}, wtime);//ここの呼び出し } this.fin = function(step,wtime){ func[id] = this; this.opacity+=step; if(this.opacity>100) this.opacity = 100; this.opacitySet(this.opacity); if( this.opacity ) setTimeout( function(){ func[id].fin( step, wtime);}, wtime);//ここの呼び出し } }

  • name属性とid属性の違い。DOMの概念?

    name属性とid属性の違いは何なのでしょうか。特にid属性についてよくわかりません。 本を読むと、「これからはDOMというオブジェクトの構造モデルが主流になる。DOMではオブジェクトをid属性で特定できる。」というようなことが載っていました。また、「id属性はname属性と同じようなもの」とも書いてありました。 そこで、あるオブジェクトに対し、"name="ではなく"id="として名前をつけました。そしてそのオブジェクトのidを指定して扱おうとしたのですがうまくいきません。 name=idではないのでしょうか。idはどのように使えばよいのでしょうか。idを利用する際の注意点等を教えていただければと思います。 (私の環境はwindows98、IE6です。)

  • setTimeoutメソッドでローカル変数を渡したい

    setTimeoutメソッドでローカル変数を渡したい 表題の件につきましてご教授をお願いします。 やりたい事は 【1秒ごとにある関数(引数が必要)を走らせて一定回数後に停止する】 なのですが、setTimeoutで引数が渡せずに困っています。 (引数は固定ではないのでローカルの変数を使用したです。) あるWEBページで下記の方法で引数が渡るとありましたが、当方の環境ではエラーが発生します。 function test1(){ var the_string = "hello"; the_timeout = setTimeout("alert(" + the_string + ");",1000); } イメージとしては下記のようにIDとcntを渡し、受け取った関数で引数を処理、 その後再帰的に同一関数に引数を送る、です。 function timeA(timeIDA,cntA){ timeID = timeIDA; cnt = cntA; alert(cnt); cnt++; clearTimeout(timeID); timeID = setTimeout("timeA(timeID,cnt)",1000); } 動作環境はWIN IE5.0以上、NC4.75以上を考えています。 何か良い解決方法がありましたら、教えてください。 よろしくお願いします。 #もっと露骨にwaitに相当するメソッドがあると嬉しいのですがr(^^;

  • HTML中のJavaScript読み込みエラー

    技術者ではなく使用者の立場ですが、こちらで質問させて頂きます。 あるサイトの特定ページを読み込んでリンクをクリックしても、 リンク先のページに飛ばなくなりました。(ある日突然・・) 2台のパソコンで同じページを読み込んでHTMLをソース表示で 比べてみたところ、<HEAD>のJavaScriptのリンク先の記述が 読み込まれていなくて、 <script language="JavaScript"> <!-- function SymError() { return true; } window.onerror = SymError; var SymRealWinOpen = window.open; function SymWinOpen(url, name, attributes) { return (new Object()); } window.open = SymWinOpen; //--> </script> サイト管理者に確認してブラウザ(IE6.0SP2)の設定も リセットして見ましたが結果は同じでした。 考えられる原因と対処方法を教えてください。

  • VBAのJScriptのeval()の挙動について

    VBAのコードを調べていますが、 JScriptで記述されている部分があり、 この部分でよく分からない挙動があるので教えてください。 (JSONデータをパースしているコードです) 具体的には、(実際のコードを簡略化したもの) ---------------------------------------- Sub test() Dim x As String Dim sc As Variant Dim y As String x = "{""A"":""d"",""B"":""e"",""C"":""f""}" Set sc = json_perse(x) y = sc.CodeObject.getValue("B") Debug.Print y End Sub Public Function json_perse(ByVal x As String) As Variant Dim sc As Object Set sc = CreateObject("ScriptControl") With sc .Language = "JScript" .AddCode "function getValue(){ var $tmp=''; for(var $i = 0; $i < arguments.length; $i++){ $tmp += ""['"" + arguments[$i] + ""']""; } return eval('e' + $tmp); }" .AddCode "var e = eval(" & x & ");" End With Set json_perse = sc End Function ------------------------------------------ のコードを実行すると、 getValue()の引数で指定した文字列(ここではB) の後の:の後の文字(ここではe)が返されますが、 なぜ、このようになるのかがよく分かりません。 この処理をしている部分を抽出すると ------------------------------------- function getValue(){  var $tmp='';  for(var $i = 0; $i < arguments.length; $i++){  $tmp += ""['"" + arguments[$i] + ""']"";  }  return eval('e' + $tmp); } var e = eval(" & x & "); ------------------------------------- となっていて、 eval()は、文字列として指定されたコードをJavaScriptのコードとして評価する ということですが、 eval(" & x & ")とeval('e' + $tmp)の部分が何をしているのかがよく分かりません。 なぜ、このコードを実行すると、 $tmpの文字(この場合はB)の後の:の後にある値が取得できるのでしょうか。

  • javascript setTimeout

    javascript初心者ですが、練習を兼ねて神経衰弱を作っています。 setTimeoutを使って「めくったカードが違う場合、少し時間を経過させてから元に戻す」 という動作を作りたいのですが、うまくいきません。 /--------------------------------------------------------/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>神経衰弱</title> <style type="text/css"> ul { width: 300px; list-style:none; margin: 0; padding: 0; } li { float:left; margin: 0; padding; 0: } img { vertical-align: bottom; /*上下隙間埋め*/ } #all { width: 300px; margin: 0px auto 0px; margin-top: 50px; } </style> </head> <body> <div id="all"> <ul> <li><img src="none.jpg" alt="3" width="100" height="100" id="c_1" onclick="conce('c_1')" /></li> <li><img src="none.jpg" alt="1" width="100" height="100" id="c_2" onclick="conce('c_2')" /></li> <li><img src="none.jpg" alt="4" width="100" height="100" id="c_3" onclick="conce('c_3')" /></li> <li><img src="none.jpg" alt="4" width="100" height="100" id="c_4" onclick="conce('c_4')" /></li> <li><img src="none_2.jpg" alt="" width="100" height="100"/></li> <li><img src="none.jpg" alt="2" width="100" height="100" id="c_5" onclick="conce('c_5')" /></li> <li><img src="none.jpg" alt="1" width="100" height="100" id="c_6" onclick="conce('c_6')" /></li> <li><img src="none.jpg" alt="2" width="100" height="100" id="c_7" onclick="conce('c_7')" /></li> <li><img src="none.jpg" alt="3" width="100" height="100" id="c_8" onclick="conce('c_8')" /></li> </ul> </div> <script type="text/javascript"> var card_c = 0; //数字が表示されているimgの数 var card_first; //altの数 var card_second; //altの数 var click_first; //開けた場所1 var click_second; //開けた場所2 function conce(aaa){ //クリックで無地に数字を表示 var imgId = document.getElementById(aaa);//クリックしたimgのid if(card_c==0){ //1枚目 imgId.src = imgId.alt+".jpg"; card_c++; card_first = imgId.alt; click_first=aaa; }else{//2枚目 imgId.src = imgId.alt+".jpg"; card_second = imgId.alt; click_second=aaa; if(card_first==card_second){ card_c=0; }else{ setTimeout("bunki()",500); card_c=0; } function bunki(){ document.getElementById(click_first).src="none.jpg"; document.getElementById(click_second).src="none.jpg"; } } } </script> </body> </html> /----------------------------------------------/ どこが間違っているのでしょうか。 よろしくお願いします。