標準入力ファイル要素を置き換える

最近、カスタマイズを行っている間(たとえば、ロシアの学者は私を許します)、私はそれを標準フォーム要素、特にファイル要素のweb改造(もう一度、親愛なるロシアの学者)と呼びさえします。 一番下の行はこれです:ファイル要素から、特に「ファイルのアップロード」ダイアログボックスが必要です。これは、MozillaおよびOperaブラウザでプログラム的に抽出することは不可能です。 コマンドdocument.getElementById( 'SaveForm')。クリック(); 何も返しません。 開発者は、それは安全ではないと主張しますが、これは議論の余地があります。 しかし、IEは私を喜ばせ、ファイル要素にマウスクリックをシームレスに送信します。これはおそらく、セキュリティに「危険な穴」を残した開発者の監視によるものです。



私は避けなかったので、何も起こりませんでした。 3時間歩いた後、理想的な解決策の最初の証言に遭遇しました:ファイルをdivに入れ、divを透明にします(不透明度:0%)、透明ではあるが見えない(可視性:隠された)、相対的に不透明度を上げる必要があるという事実に注意を引きます:0%は要素を目から隠し、可視性:マウスからも隠します。 しかし、フォントサイズで遊ぶと、メソッドの魅力が失われ始め、見えないボタンを見逃す可能性があります。

1時間後、別のyamzbrowserの例に出会いました(htmlページに挿入されたswfオブジェクトからサーバーにファイルをアップロードできます)。 彼は最初の方法を繰り返しますが、! 違いが1つあります。移動するときに、マウスカーソルの下のdivを置き換えます。 ところで、私はOperaのおかげでこれを正確に発見しました(私は通常Foxを使用しています。Operaで例を開いたのは大きな偶然です)。



両方の方法を研究した後、それらを1つに組み合わせて、Web上のより広範なアプリケーションのためのソリューションを開発しました。 それで、座って始めましょう。

仮定



  1. ファイルを置き換える要素のサイズは、ファイル自体のサイズとは大きく異なる場合があります。
  2. ファイル要素はフォームの一部です。
  3. 偏執病者のみがブラウザでJavaScriptを無効にします
  4. 訪問者は、Firefox、Opera、またはIEを使用しているユーザーのささやかな99%に属します。
  5. ソリューションは、すべてのブラウザで同じアルゴリズムで動作するはずです。 IEでさまざまなツールを使用するオプションはdocument.getElementById( 'SaveForm')で、クリック();およびFFとOperaの場合、置換は受け入れられません
  6. 解決策がページで重複している可能性があります


アルゴリズム



置換ボタンの上にマウスを置くと、要素のあるレイヤーがカーソルの下に置き換わります。そのため、カーソルはレイヤーの中央にあります。 ユーザーがボタンを見逃さないことと、可視性が可視に変わることを確実に知ることができます。要素を持つレイヤーは不可視のままですが、マウスからはアクセスできます。 カーソルを移動するとき、代替ボタン内のレイヤーを移動します;ボタンの端に到達すると、可視性は値を非表示にします。

レシピ



HTML



<form>

<div id="divFile1" class="file" onmousemove="divFileMove(this.id, 'buttonFile1',event);">

<input type="file" name="UploadFile" id="file1" size="1" onchange="result(this.id, 'divResult');" tabindex="1" />

</div>

<div id="divResult"> </div>

<image src="./images/fileUploadButton.jpg" id="buttonFile1" onmouseover="divFileShow('divFile1', event);"/>

</form>






CSS





div.file{

position : absolute ;

top : -1000px ;

left : -1000px ;

-moz-opacity : 0 ;

filter : alpha(opacity=0) ;

opacity : 0% ;

visibility : hidden ;

}








div.file-仮定番号6を考慮して、idではなく使用される.fileクラスです。

上、左:-1000px-念のため、javascriptが到達する前にレイヤーを非表示にします。

-moz-opacity、filter:alpha、opacity-FF、IE、Operaの透明度をそれぞれ設定します。

visibility:hidden-マウスを非表示にします。

Javascript



関数divFileShow(divId、e)、divIdはファイル要素を持つレイヤーのID、eはイベントです。 mouseXおよびmouseY関数は、すべてのブラウザーの左上隅に対するマウスの位置を計算します。 レイヤーをマウスから見えるようにし、カーソルの下に置き換えて、カーソルがレイヤーの中央にくるようにします。



function divFileShow ( divId,e ){

var div = document .getElementById ( divId ) ;

div.style.left = ( mouseX ( e ) - Math . round ( div.offsetWidth / 2 )) + "px" ;

div.style.top = ( mouseY ( e ) - Math . round ( div.offsetHeight / 2 )) + "px" ;

div.style.visibility = "visible" ;

}






divFileMove関数(divId、butId、e)。divIdはレイヤーのID、butIdは置換ボタンのID(ボタンの寸法を取得するために必要)、eはイベントです。 butIdオブジェクトの境界に達すると、レイヤーがマウスの後ろに移動します。

function divFileMove ( divId, butId, e ){

var div = document .getElementById ( divId ) ;

var button = document .getElementById ( butId ) ;

var move = true ;

var divX = parseInt ( div.style.left ) + Math . round ( div.offsetWidth / 2 ) ;

var divY = parseInt ( div.style.top ) + Math . round ( div.offsetHeight / 2 ) ;

if ( divX < button.offsetLeft || divX > ( button.offsetLeft + button.offsetWidth )) {

move = false ;

}

if ( divY < button.offsetTop || divY > ( button.offsetTop + button.offsetHeight )){

move = false ;

}

if ( move ){

div.style.left = ( mouseX ( e ) - div.offsetWidth / 2 ) + "px" ;

div.style.top = ( mouseY ( e ) - div.offsetHeight / 2 ) + "px" ;

} else {

div.style.visibility = "hidden" ;

}

}






関数結果(fileId、divResultId)。fileIdはファイル要素のID、divResultIdは選択したファイルの名前が表示されるレイヤーのIDです。 この関数は、ファイル名のみをレイヤーのinnerHTMLに渡し(たとえば、「all my passwords.txt」)、title属性に完全なパスを入れます。これはもっと便利だと思います。



function result ( fileId, divResultId ){

var divResult = document .getElementById ( divResultId ) ;

var formFile = document .getElementById ( fileId ) ;

divResult.innerHTML = formFile.value. replace ( /^([^\\\/]*(\\|\/))*/ ,"" ) ;

divResult.setAttribute ( "title",formFile.value ) ;

}






そして最後に、IEと他のブラウザーのページ上のカーソルの位置を決定する2つの関数(mouseX(e)、mouseY(e)、ここでeはイベント)は、2文字だけ異なるため、そのうちの1つを指定します。

function mouseX ( e ){

if ( e.pageX ) return e.pageX;

if ( e.clientX ) return e.clientX + document . body .scrollLeft;

}






ご注意



ファイル要素を持つレイヤーはボタンとオーバーラップするため、イベントはホバーに渡されません。したがって、マウスオーバーをシミュレートする必要がある場合は、ボタンクラスを変更するか画像を変更することにより、適切な機能を追加する必要があります。

実用的な例 、誰かが正当な理由に貢献したい場合は、オンラインプレゼンテーションの例を投稿してください。この記事のリンクと感謝を保証します。

ブラウザFirefox 2、Opera 9、IE 6でテスト済み。

ご清聴ありがとうございました。



PSキャッシュデスクを離れることなく、事前にバグを報告してください;)



All Articles