2021年11月 4日 (木)

何か変だ・・・続報

問題の記事は「<Select><Option> の代替品(1)」といったタイトルだったのですが、タイトル文字列の中に html のタグがあったのが問題だったようです。

タイトルを「Select Option の代替品(1)」のようにに修正すると正常な表示になりました。

何か変だ

今日、「<Select><Option> の代替品」の(1)から(3)まで、3つの記事を投稿したのですが、表示が変です。しばらく状況を見る事にします。

連投したのがまずかったのか???

Select Option の代替品(3)

・<li> について、それから・・・

<li> にはてこずりました。オプションリスト表示の高さを得るために

「リストの高さ = 1行の高さ X 行数」としているので、どうしても「1行の高さ」が必用なんですが、


・<li> の高さが取れない。undefined が返ってきます。かなり粘ってみたのですがダメ。高さが取れないので、他の物の高さから「<li> の高さ = 40px」として進めたのですが、


・<li> に高さをセットしても反映されない。これもかなりの時間を使ってしまいました。分かったのは

・【表示されていない】状態の <li> の高さなどは取得できない。同様に

・【表示されていない】状態の<li> に高さ等をセットしても反映されない。


色々いじっていたら、表示されていれば高さなどを取得できるし、値をセットすれば反映されるという事が分かりました。高さは何とかなったのですが・・・次に引っかかったのは・・・


・valign:middle がきかない。何が何でも上寄せになってしまいます。これにも時間を使ってしまいましたが、高さ:20 とし、padding-top=10; padding-botton:10 とすると、それらしい見かけになりました。
他のエレメントはそれなりに動くのだけれど <li> は違うんですね。これ、<li> の仕様なのかバグなのか分かりませんが・・・


短いけど、今回はこれだけ。の予定だったんですけど早速、テスト用 Html のバグが発覚しました。MySelect の外枠(outline)が【横倒しした「こけし」】みたいな形になってしまう事があるんです。Firefix だとOKなんですが、Chrome, Edge では「こけし」になってしまいます。調べてみたら、MySelect の2つの <input type=text. の間の改行が原因でした。Html ファイル上では単なる改行なんですが、この改行コードが「標準高さの空白文字」と解釈されていたようです。border などを表示させると、2つの text の間に空白がありました。標準よりも高い2つの textbox に挟まれて標準高さの空白文字、となっていたと思われます。これの outline を表示していたので、標準高さの空白の部分が「首」になっていたんですね。ところで、【Firefix だとOKなんですが、Chrome, Edge では「こけし」になってしまいます。】どっちが本来の仕様なんでしょうね。ひょっとすると仕様はないのかも知れませんね。HTMLって、ブラウザの裁量にまかされている部分がかなりあるようなので。結局、この改行を削除してOKとなりました。読みにくいけど、しょうがない。

Select Option の代替品(2)

・JavaScript その1

【インデント調整のために全角スペースを使用しています】


<script language="JavaScript">

var selectedCode = ''; // 送信元ページから受け取ったパラメータ

TestParam の値var codeIDList =

 [ [222, 'アイルランド'], [278, 'アメリカ'], [242, 'イギリス'],

 [223, 'イタリア'], [207, 'オーストリア'], [230, 'オランダ'],

 [218, 'ギリシャ'], [238, 'スペイン'], [212, 'チェコ'],

 [213, 'デンマーク'], [217, 'ドイツ'], [113, '日本'],

 [231, 'ノルウェー'], [220, 'ハンガリー'], [216, 'フランス'],

 [208, 'ベルギー'], [232, 'ポーランド']

];

// selectedCode の値とオプションリスト内での行番号、キャプションの対応表。

// 配列の要素番号が行番号、[x][0] は selectedCode の値、

//[x][1] は対応するキャプションで、MySelect に表示する文字列、オプションリスト内で強調表示する行を得るために使用する。

// 受信した selectedCode を用いて [x][0] を検索し、一致したものの要素番号と [x][1] の文字列を使用する。

var initialSelection = -1; 選択されtものの行番号。

-1 は「何も選択されていない」を表す。

//

//  <body onload=... で実行する function   処理内容は

// イベントハンドラの登録、Html パラメータ TestParam の受信、

// codeIDList を用いて対応するオプションリスト内での行番号、キャプションを得る

//

function onLoadFunction(){

// イベントハンドラの登録。

 document.addEventListener('auxclick',    closeMyOption, {capture:true}); 

 document.addEventListener('scroll', closeMyOption, {capture:true}); 

 document.addEventListener('keydown', closeMyOption, {capture:true});

 document.addEventListener('mousedown', mouseDownHandler,{capture:true});

// 呼出元ページからのパラメータの受信

 var urlStr = document.location.search; // URL を得る。

 initialSelection = -1; // 行番号、初期化

 if((urlStr != null) && (urlStr.length != 0)){ // URL があるならば

// パラメータ値を得る・・・これは「手抜き」です。パラメータは TestParam だけなので

// パラメータ名を無視して = の後を取得しています

  var eqPos = document.location.search.indexOf('=');

  selectedCode = urlStr.substring(eqPos + 1);

  if(selectedCode != ''){ // パラメータがあるならば

   for(var i=0; i<codeIDList.length; i++){ // codeIDList 内を検索し

    if(codeIDList[i][0] == selectedCode){

     initialSelection = i; // 行番号を得る。

     var mySelectElement = document.getElementById('MySelT0');

// mySelect のキャプション表示 text のエレメントを取得し、キャプションを書き込む。

     mySelectElement.value = codeIDList[i][1]; break;

    }

   } 

  }

 }

}


// オプションリスト表示中の場合には

var activeMySelect=null; // mySelect の id

var activeMyOption=null; // myOption の id

// が格納される。非表示の時はいずれも null。オプションリストが表示されているかの判断に使用する。

var selectedItems=null; // String[][]

  // [0]:mySelect の id

  // [1]:選択されている行の番号

  // オプションの行が選択された状態で再びオプションリスト表示する時

  // 強調表示すべき行を得るために使用する


var normalHeight=20;  <li> の高さ(次回説明)

//
// オプションリストを表示する。mySelect をクリックした時に呼ばれる

// @param mySelectID MySelect の id

// @param mySelectTextID MySelect 内のキャプション表示領域の id

// @param myOptionID オプションリストの id

// @param myUlID オプションリストの <ul> の id

// @param numOptions オプションリストの行数 <li> の数

//

function dispMyOption(mySelectID, mySelectTextID, myOptionID, myUlID, numOptions){

 var myOptionElement = document.getElementById(myOptionID);

 var ulElement = document.getElementById(myUlID);

 if(activeMyOption != null){ // オプションリスト表示中ならば

  myOptionElement.style.display='none'; // 表示を終わる。

  activeMyOption=null; // これはオプションリスト表示中に

  activeMySelect=null; // mySelect がクリックされた場合の処理である。

  return;

 }

 var selectedNo = -2; // 現在選択されている行

// -2:情報がない -1:選択された行はない。 0以上:選択されている行番号

 if(selectedItems == null){ // 情報格納領域がない場合は

  selectedItems = new Array(0); // 作成する

 }

 for(var i=0; i<selectedItems.length; i++){ // 処理中の mySelect の情報が

  if(selectedItems[i][0] == mySelectID){ // 存在するかを調べる

   selectedNo = selectedItems[i][1]; // 存在する場合、それが現在の選択行である

   break;

  }

 }

 if(selectedNo == -2){ // 情報がない場合

  selectedNo = initialSelection; // パラメータで受取った値を現在の選択行とし

  var workArray = new Array(2); // それを selectedItems に保存する。

  workArray[0] = mySelectID;

  workArray[1] = selectedNo;

  selectedItems.push(workArray);

 }

 var optionRows = ulElement.children; // <ul> 以下の子要素(<li>)を得る。

 for(var i=0; i<optionRows.length; i++){ // 各 <li> に対して

  optionRows[i].style.backgroundColor=''; // 背景色なしとする。

 }

 if(selectedNo != -1){ // 現在の選択行がある場合

  var selectedRow = optionRows[selectedNo]; // その行の背景色を

  selectedRow.style.backgroundColor='aquamarine'; // 「選択色」とする。  }

// 処理に必用なエレメントを得る

 var mySelectTextElement = document.getElementById(mySelectTextID);

 var mySelectTextRect = mySelectTextElement.getBoundingClientRect();

 var mySelectElement = document.getElementById(mySelectID);

// mySelect エレメントの上端、下端、左端の座標、幅を得る

// オプションリストの表示サイズ、表示位置の決定に使用する。

 var mySelectRect = mySelectElement.getBoundingClientRect();

 var mySelectTop = mySelectTextRect.top; // 上端

 var mySelectBottom = mySelectTextRect.bottom; // 下端

 var mySelectLeft = mySelectRect.left; // 左端

 var mySelectWidth = mySelectRect.width; // 幅

 var myOptionLiHeight=normalHeight + 20; // <li> の高さ(次回説明)

 var myOptionTotlaHeight=myOptionLiHeight * numOptions;// オプションリスト全体の(全行表示した場合の)高さ

 var windowHeight=window.innerHeight; // window の高さ

 var upperMatgin=mySelectTop; // mySelect 上側の余地

 var lowerMargin=windowHeight-mySelectBottom; // mySelect 下側の余地

 var dispAbove=false; // true:オプションリストは mySelect の上側に表示する

 var numRows = 0; // 表示すべき行数

//

// 表示位置、オプションリストの大きさ(高さ)を得る

//

 if((upperMatgin < myOptionTotlaHeight) && (lowerMargin < myOptionTotlaHeight)){

// 全体の高さが上下いずれの余地よりも大きい場合、高さの調節が必用

  dispAbove = lowerMargin < upperMatgin; // 余地の大きい側に表示する。

  var margine; // 表示に使える余地

  if(dispAbove){

   margin = upperMatgin;

  }else{

   margin = lowerMargin;

  }

  numRows = Math.floor(margin / myOptionLiHeight); // 表示行数

  myOptionTotlaHeight = myOptionLiHeight * numRows; // 表示高さ

 }else{

  dispAbove = lowerMargin < myOptionTotlaHeight; // 高さの表示不要。表示位置を得る。

 }

 ulElement.style.height = myOptionTotlaHeight; // <ul> に高さをセット

 ulElement.style.width = mySelectWidth; // <ul> に幅をセット

 if(dispAbove){ // 表示位置(Y座標)をセットする。

  myOptionElement.style.top = mySelectTop - myOptionTotlaHeight;

 }else{

  myOptionElement.style.top = mySelectBottom;

 }

 myOptionElement.style.left = mySelectLeft; // 表示位置(X座標)

 var listElement=document.getElementById(myOptionID);

 listElement.style.display='block'; // 表示する

 for(var i=0; i<optionRows.length; i++){

  optionRows[i].style.height=normalHeight; // <li> の高さをセットする

 }

// 選択された行がオプションリストの先頭でない場合、その行が表示の中ほどになるように

// (リストの最後ならば下端になるように)スクロール量(行数)を決定する。

 var scrollRows = 0; // スクロール量(行数)

 if(selectedNo != 0){ // 先頭ではない場合

  var maxScrollRows = numOptions - numRows; // 可能な最大スクロール量

  var scrollOffset = Math.floor(numRows / 2); // 中ほどとするためのオフセット

  scrollRows = selectedNo - scrollOffset; // 実際のスクロール量

  if(scrollRows < 0){ // 負数になったら「0」とする

   scrollRows = 0;

  }else{

   if(maxScrollRows < scrollRows){ // 可能な最大スクロール量を越えたら

    scrollRows = maxScrollRows; // 可能な最大量とする

   } // (下端に選択行が表示される)

  }

 }

 ulElement.scrollTop=scrollRows * myOptionLiHeight;

 activeMyOption=myOptionID; activeMySelect=mySelectID;

}


今回はここまで。

このブログ入力ソフト、ソースコードを書くには不適当だね、改行やインデントが無視されたりする。当たり前か・・・。

【後でUpする予定のサンプルの html は,表示の乱れなんか気にせずに「生」のものを書きこみます。コメントも削除します。

Select Option の代替品(1)

スマホ版を作成中ですが、スマホは指で操作するため、ボタンなどを大きくしなくては思ったように操作できません。<Select><Option> では、オプションリストの行の高さを大きくしたいのですが、<Option> に style をセットしても手応えなし。
考えているうちに、<Select><Option> と同じような動きをする物が作れそうに思えてきたので、やってみました。本物の <Select><Option> とは多少違うのですが、主要な機能は同じものを作る事ができました。

【まだPC Windows 10 でしか動かしていません]

ブラウザのウインドウを小さくして動かした限り、よさそうです。実際のスマホの場合、アンドロイドだったりするわけで、問題が出る可能性はありますが、とりあえず動いたので公開します。

使っているのは JavaScript だけです。

多分、「<Select><Option> の代替品(5)」で実行可能な html ファイルを書き込む予定です。このブログサイトにはダウンロード可能なファイルをUpし、読者がダウンロードできる機能はないようなので、html をテキストとして投稿する予定です。

・<Select><Option> は使わない。

<Select> は <Option selected> あるいは最初の <Option> にある caption を現在選択されている物として表示すると思われます。つまり、<Option> が必用。<Option> が意図したように動いてくれないならば <Option> は使えない。<Select> は使用して <Option> の代わりに <MyOption> などを使うには <Select> を処理する部分(つまり、ブラウザ)を修正しなくてはならないでしょう。そういう訳なので、<Select><Option> は使いません。

・<Select> の代替品 【以下、MySelect と書く場合があります。】

必用条件は、現在の選択値のキャプションを表示できる事、それを JavaScript で書き換える事ができる事、ユーザーは書き換えられない事、クリックした時イベントが発生する事、<Select> の value 相当の値を適切なパラメータ名で送信できる事などです。結局、以下のようにしました。


<span style="outline:solid thin;width:150px;" id="MySel0" onClick="dispMyOption('MySel0','MySelT0','MyOpt0','MyLi0','17')">

<input type="text" readonly style="cursor:default;outline:none;border:none;width:135px;height:40px;" id="MySelT0" value="">

<input type="text" readonly style="cursor:default;outline:none;border:none;text-align:right;width:15px;height:40px;" value="v " class="aH">

</span>

<input type="hidden" name="TestParam" value="">

・現在選択値の表示、▽のボタンには readonly の text を使っているのは、最初に思いついたのが readonly text だったからで、動作したのでそのままになっています。

・Html パラメータの送出には <hidden> を使っています。hidden の name に記述する名前は <Select> に記述する名前です。

・text に表示される枠があると、現在値表示、▽ボタンに個別の枠が表示されてしまい、見た目が大きく異なります。「枠なし」とします。

・2つの text 全体を囲む枠は欲しいので、<span> で囲み、それに枠を付けました。

【重要】2つの ,input typw=text ...> の間に改行を入れてはいけません。ここでは読みやすさのために改行していますが、実際の html に改行を入れると

Firefox:まともに表示される。

Chrome, Edge : こけしを横倒ししたよう不思議な形の外形が表示される。

となります。どうやた、改行はデフォルト高さの空白文字に変換されているようです。


・<Select> の代替品、行ごとの説明

<span style="outline:solid thin;width:150px;" id="MySel0" onClick="dispMyOption('MySel0','MySelT0','MyOpt0','MyLi0','17')">

style="outline:solid thin; 枠あり、細い実線 width:150px;

id="MySel0   JavaScript で処理する時に参照するための id onClick="dispMyOption('MySel0','MySelT0','MyOpt0','MyLi0','17') クリックされた時の処理


'MySel0'   <Select 代替品を囲む <span> の id

'MySelT0' 現在値を表示する readonly text の id

'MyOpt0' オプションリスト(後述)全体の id

'MyUl0' オプションリストの <ul> の id

'17' オプションリストの行数


<input type="text" readonly style="cursor:default;outline:none;border:none;width:135px;height:40px;" id="MySelT0" value=""> 現在値を表示する領域。


<input type="text" readonly style="cursor:default;outline:none;border:none;

text-align:right;width:15px;height:40px;" value="v " class="aH">

▽を表示する領域。▽は小文字の v で代用しています。

</span>
<input type="hidden" name="TestParam" value="">

選択値を Html パラメータとして送出するためのもの。name は送出されるパラメータの名前で、<Select name=...> に記述する名前。

・<Option> の代替品

<div id="MyOpt0" style="display:none;position:fixed;border:1px solid #000;background-color:#fff;">

<ul style="list-style:none;padding-left:0;padding-top:0;margin-top:0;padding-bottom:0;margin-bottom:0;overflow-y:auto;" id="MyUl0">

<li onMouseOut="onMouseOutFunction('MySel0',this,'0');" onMouseOver="this.style.background='lightskyblue';" style="text-align:left;padding-left:20;padding-top:10;padding-bottom:10;" onClick="setValue('MySel0','MySelT0','MyOpt0','222','アイルランド','0','TestParam')">アイルランド</li>

<li onMouseOut=・・中略・・</li>  必用なだけ繰返し記述

</ul></div>
オプションリストには <div><ul> <li></li> </ul><div> を使いました。<div> はオプションリスト全体で、その時の画面の大きさ、スクロール量に応じて表示位置を調整する時、オプションリスト全体を「1つの物」として扱うためのものです。

<ul> <li> の説明は不要は省略


・<Option> の代替品 行ごとの説明

<div id="MyOpt0" style="display:none;position:fixed;border:1px solid #000;background-color:#fff;">

id="MyOpt0" JavaScript から参照するための id

styledisplay:none; 初期状態は非表示

position:fixed;border:1px solid #000; 境界線あり、1px 幅の実線、黒色background-color:#fff; 背景色は白

<ul style="list-style:none;padding-left:0;padding-top:0;margin-top:0;padding-bottom:0;margin-bottom:0;overflow-y:auto;" id="MyUl0">

id="MyOpt0" JavaScript から参照するための id
styledisplay:none; 非表示

position:fixed; 位置は固定。実際に表示する時 JavaScript で調整します。

border:1px solid #000 境界線。1px 幅の実線、黒色

background-color:#fff 背景色は白


<li onMouseOut="onMouseOutFunction('MySel0',this,'0');" onMouseOver="this.style.background='lightskyblue';" style="text-align:left;padding-left:20;padding-top:10;padding-bottom:10;" onClick="setValue('MySel0','MySelT0','MyOpt0','222','アイルランド','0','TestParam')">アイルランド</li>

onMouseOut="onMouseOutFunction('MySel0',this,'0');マウスが離れた時の処理

onMouseOver="this.style.background='lightskyblue'; マウスが乗った時の処理。「選択色」とする。

styletext-align:left; テキストは左詰め

padding-left:20 左の padding

padding-top:10; 上の padding

padding-bottom:10; 下のpaddingon

Click="setValue('MySel0','MySelT0','MyOpt0','222','アイルランド', '0','TestParam')">

クリックされた時の処理。

'MySel0','MySelT0','MyOpt0', JavaScript から参照するための id。

何の id かは「<Select> の代替品、行ごとの説明」にあります。

'222' 「アイルランド」の パラメータ値。<Option value=...> に記述する値に相当。

'アイルランド' クリックされた時、mySelect に表示する文字列。<Option> </Option> 間に記述する文字列に相当。

'0' 「アイルランド」の、<ul> 内の位置。行番号。

'TestParam' Html パラメータの名前。JavaScript が <hidden> を参照するための名前。</ul></div>
今回はここまで。次回は JavaScript その1。かなり長いスクリプトなので、2回に分けて書きます。

大文字、小文字に気をつけましょう・・

以前、<Select><Option> の高さを変えようとして「あきらめた」のですが、できそうに思える【手口】を思いついたので、試作品を作りました。私のテストページでは動作しているのですが、そのページ、サーブレット(JSP と Java で HTML を作成する)なので一般的ではないように思えました。そこで、ごく簡単なページを作成して(Jsp や Java なしで)動くページを作ろうとして【大トラブル】。

<body onload=... で document.addEventListener() を行う必要があるので、<body onLoad="onLoadFunction()"> とし、

function onloadFunction(){......} を作成しました。ところが動かない。

「onLoadFunction は定義されていない」というエラーが出てしまいます。

エディタでHtml のソースコード内を検索すると「onLoadFunction()」は確かに存在するし、1行づつ、というより1文字づつ読み返してもヘンな所はない。「onLoadFunction」は予約語か。。。まさか。ググってもそんな事例は見つからない。はまりました。

数時間後に、<onLoad="onLoadFunction()">、function onloadFunction(){ と記述しているのに気づきました。大文字と小文字が違っていたんですね。JavaScript は大文字と小文字を区別します)

私が常用しているエディタの検索は「大文字、小文字を区別しない」がデフォルトで、そのまま検索していたんですね。

気を付けましょう。

2021年10月29日 (金)

Windows 10 共有プリンタが動かない

誰かに情報を渡す時はメールに添付したりUSBメモリーに入れたりで、紙で渡す事はずいぶん少なくなりました。が、今日、久しぶりに「印刷」しようとしました。

とことが、共有プリンタが動かない。PC2台のうち1台をプリンタサーバーとしています。PC1にはUSBでプリンタを接続、PC2はLAN経由でPC1のプリンタを使うようにしています。

【現象】

・PC1(ローカルにプリンタがある)からは印刷できる。

・PC2からPC1にアクセスできる。共有フォルダへのアクセスもOK。

・PC2から印刷しようとしても、PC1の印刷キューにデータが入らない。

・PC2で【印刷】アイコンとかボタンをクリックすると、それがグレーアウトされたままになる事が多かった。そのうち「○○は応答しません」になったりする。

調べてみたら最近の Windows Update 以降動かなくなっているようです。ソフトの修正や機能追加でバグを作ってしまうのは「よくある事」なんですが、テストくらいちゃんとやってから出火して(あっ、いい誤変換)ほしいですね。

結局、PC2にある印刷したいファイルを共有フォルダにコピーし、それをPC1から印刷しました。ヘンな事が起こったら本格的なトラブルシューティングする前にググってみた方がよさそうですね。

2021年10月28日 (木)

自転車を買いました

クルマの運転をやめたんですが、移動が不便だし、バス代も安くないので自転車を買いました。これからは体力は衰える一方なので、電動アシスト付きにしました。

買ったお店は「自転車屋」ではなくビックカメラ。理由は対応が良かったから。自転車屋さん、改善しないと未来はないよ、と思ってしまいます。

さて「コレ下さい」。代金を支払って1時間半ほど待った後、ウチまで乗って帰ったのですが、ふらついてうまく乗れない。と言って、コースアウトしたりコケたりするほどではないんですが、真っすぐには走れない。考えてみると自転車に乗るのは殆ど半世紀ぶり。エンジン付き二輪車に乗らなくなってから1/3世紀。乗り方を忘れてしまったようです。肩や腕に余計な力が入っているとか、ペダルを踏む時の体の支え方とかなんでしょうけど、しばらく練習が必用ですね。・・・トシだねぇ・・・

2021年10月24日 (日)

私のPC,Windows11 へのアップデートは出来ないらしい

バックグラウンドで Windows Update が動いていたらしく、やたら重い状態が続いていたのですが、ダウンロードが終わったのかなと思って【設定】【更新とセキュリティー】を開いてみました。すると

「このPCは現在 Windows 11 のすべてのシステム要件を満たしていません」と表示されているではないですか。調べてみたら、「CPU が要件を満たしていない」「TPM 2.0」が実装されていないからのようです。CPU は intel i5-4440。最新ではないけど、骨董品でもないぞ。製造終了は 2017 年らしい。

TMPはセキュリティー関連の機能のようなのだが、i5-4440 には実装されていない。Microsoft によるとPCの買い替えを検討しろだと。ひどい話だ。

ソフト屋ならば、「このCPUではTMPが使えないので安全性が低くなる」が、Windows 11 は動作するとかの迂回処置をしてほしいな。まあ、Windows 11 が必用なわけではないから我慢するか。

・・・待てよ・・・Microsoft は新OSをリリースしたら旧OSのサポートを止めるのが通例で、となると Windows 10 はいつまでサポートされるのか。調べてみたら、2025年10月14日だと。Windows 10 から無料でアップデートとか喜ばせておいて、ハードウエアの買い替えを求めるなんて酷いじゃぁないか。Windows 10 を 2035 年ごろまでサポートしてくれるならアップデートしないのも選択肢にあるんだけどね。

後付けのTPMモジュールというのもあるらしい。企業ユーザーが殆どで一般には出回っていないらしい。まだ情報が不足なんだけど、探してみるか。

2021年10月23日 (土)

自転車選び

自動車やめて自転車に乗り換え。まずは自転車を買わなくっては。自転車屋めぐりとかやっているのですが、何の拍子か、いきなり Peugeot (プジョー、フランス)の自転車を思い出しました。何となくオシャレな感じがするので調べてみたら、細々と輸入されているようですが、実用的な車種は輸入されていないようです。そうだろうな。

結局、お店にある物を買う事になりそうです。なんか、面白くない。

ところで、クルマやオートバイにはそれ専門のサイトがあって、実用車の評価記事なんかもあるんですが、自転車にはなさそうですね。まぁ、普通は「このへんの物」を買う人が殆どだと思うんで、しょうがないか。