プロが教える店舗&オフィスのセキュリティ対策術

アパレルのショッピングサイトの運営をしております。クライアントから「自社デザインを真似たものや盗用したものを頻繁に見かけるようになったため右クリック禁止で商品写真の画像をコピーされないようにしたい」との依頼がありました。
右クリック禁止は気休め程度と説明しましたが、残念ながら理解を得られませんでした。
私のJava Scriptの知識は読むことができる程度です。浅薄な知識ではどうにもすることができず、こちらに投稿させていただきました。どうぞよろしくお願いいたします。

実現したい内容は、▼次のとおりです。

┌─────   
│商品画像 
│A0101.jpg
└─────
↓↓クリックで別ウインドウが開く
┏━━━━━━━━
┃        
┃ 商品拡大画像 
┃ A0101L.jpg(末尾の'L'はLサイズの意味)

┃    ×閉じる
┗━━━━━━━━

1.商品画像をクリック。ファイル名A0101.jpgを変数に記憶。
2.A0101.jpgの末尾に’L'を加える。(A0101L.jpg)
3.別ウインドウを開き、拡大画像を表示。
4.拡大画像の横幅を調べ、別ウインドウを、高さ(600px)、横幅(
拡大画像+左右余白10px)にリサイズ。
5.画像上での右クリック禁止(<IMG SRC="A0101L.jpg" oncontextmenu="alert('画像コピー禁止');return false;">)

▼イメージに近いサイト
「ノードストローム」 (商品画像の下、>LARGE VIEWをクリック)
http://store.nordstrom.com/product/product_brand …

▼現在はtarget="_blank"で別ウインドウを開かせています。
<A href="picture/A0101L.jpg" target="_blank"><IMG src="picture/A0101.jpg"></A>

A 回答 (7件)

通常のページAとウィンドウで開くページB別の説明です。



■ページA

まず<head>~</head>に

<script type="text/javascript">
<!--
function winOpen(img, num){
var winuri = "pageB.html"; // サブウィンドウのパス
var imgsrc = img.src || img;
window.open(winuri + "?img=" + imgsrc + "&num=" + num, "image", "width=700,height=600,scrollbars=1,resizable=1");
return false;
}
//-->
</script>

width=700,height=600は横幅と縦幅なので適当な値に変えてください。
サブウィンドウのパスには、ページBのパスを入れてください。


サムネイル画像と文章
<img src="A0101.jpg" onclick="winOpen(this, 3)">
<a href="#" onclick="return winOpen('A0101.jpg', 3)">商品の拡大写真</a>


■ページB

まず<head>~</head>に

<script type="text/javascript">
<!--
location.search.match(/^\?img=([^&]+)(\.[^&\.]+)&num=(.+)$/);
var img = RegExp.$1;
var ext = RegExp.$2;
var num = Number(RegExp.$3);

function changeImage(img){
var imgsrc = img.src || img;
imgsrc.match(/^(.*)s(\.[^\.]+)$/);
document.main.src = RegExp.$1 + "l" + RegExp.$2;
return false;
}

document.write = img && ext && num ? document.write : function(){};
//-->
</script>


そして↓が<tr><td>拡大画像</td><td>サムネイル画像全て</td></tr>の部分です。

<tr>
<td>
<script type="text/javascript">
<!--
/* 拡大画像 */
document.write('<img src="' + img + 'l' + ext + '" name="main" id="MAIN">');
//-->
</script>
</td>
<td>
<script type="text/javascript">
<!--
/* サムネイル画像 */
document.write('<img src="' + img + 's' + ext + '" class="thumbnail" onclick="changeImage(this)"><br>');

for (var i = 1; i < num; i++) {
document.write('<img src="' + img + String.fromCharCode(0x60 + i) + 's' + ext + '" class="thumbnail" onclick="changeImage(this)"><br>');
}
//-->
</script>
</td>
</tr>


BODY開始タグ
<body oncontextmenu="alert('画像コピー禁止');return false" onselectstart="return false" ondragstart="return false">


透明な画像
<img src="blank.gif" id="blank">


CSS
<style type="text/css">
<!--
img#blank {z-index: 1;position: absolute;top: 0;left: 0;width: 100%; height: 100%;}
img#MAIN {z-index: 0;position: relative;}
img.thumbnail {z-index: 2;position: relative;}
-->
</style>

以上です。



>この違いはどうして生まれるのでしょうか?
window.openのオプションにresizable=1を加えることでサイズを変えられるようになります(スクロールバーを有りにするならscrollbars=1)。

window.open(URI, window名, オプション);
    • good
    • 0
この回答へのお礼

こんにちは665さん。早速の回答ありがとうございます。
もうまさに希望とおりの動作で大変うれしいです。しかも予想以上に短いスクリプトでびっくりしました。これでクライアントにも鼻高々で見せることができます。
長い間、いたらぬ説明に辛抱強く付き合ってくださり本当に感謝しております。
今回はいろんなことを学ぶことができました。早く自分でもスクリプトを書けるようになりたいものです。

アパレルサイトのリニューアルが始まったばかりでまだ実現できていない問題が山積みですので再びここでお会いするかもしれません。そのときはよろしくお願いいたします。
ありがとうございました。

お礼日時:2005/09/09 13:21

>追加する仕様



多分いろいろと書き換えるか前とは完全に別なものになりそうなので次の2つを説明してください。

1.今回も画像サイズに対応してウィンドウサイズ変化させるのか?
2.もし変化させるならサムネイル画像のスペースが必要となるが、何を基準にウィンドウサイズを決めるのか?


いずれにせよ2つのページ(通常のページAと別ウィンドウのページB)を作った方が簡単でしょう。

それぞれの役割としては、
ページAはページBを開き、どのサムネイルをクリックしたかをページBに伝える(location.searchを使って値の受け渡しをする)。
ページBはよくあるサムネイルをクリックして同じページに表示するスクリプトを入れる。

この回答への補足

こんにちは665さん、早々のお返事ありがとうございます。面倒な質問におつきあいいただき大変感謝しています。
>前とは完全に別なものになりそうなので次の2つを説明してください。
うーんそうなんですか。思っていた以上にやっかいな代物なんですね。まずは指摘された2点を考えてみました。

>1.今回も画像サイズに対応してウィンドウサイズ変化させるのか?

すみません。これをはっきりしておかなければならなかったですね。
これは最初に開いたウインドウサイズの横幅をそのまま持続したいと考えています。理由は2つあってサムネイルをクリックするたびにウインドウサイズが変わると目がチカチカしてしまうのと、その他の写真の横幅が大体同じくらいのサイズのためです。

IEやFireFoxの場合ウインドウ枠右下の///となっている場所をドラッグするとウインドウサイズが自由に可変するのでユーザにはこれでサイズを合わせてもらえばよいと思います。
ただよく違いがわからないのですが、ウインドウ枠右下に///が出ない場合があってその場合はウインドウサイズを可変することができないんですね。今気が付きました。
この違いはどうして生まれるのでしょうか?スクロールバーを表示しないようにすることと何か関係があるのでしょうか?

>2.もし変化させるならサムネイル画像のスペースが必要となるが、何を基準にウィンドウサイズを決めるのか?

説明不足で申し訳ありませんでした。
ウインドウサイズを決定するのは、<左>最初に読み込んだ画像の横幅+<右>サムネイルを置くスペース(100px)を考えています。
■別ウインドウ
 <左>  <右>  
┌─────┬─┐□..サムネイル(末尾に"a,b,c…"+"s")   
│拡大画像 │□│A0101s.jpg onclick→<左>A0101l.jpg  
│A0101l.jpg │□│A0101as.jpg onclick→<左>A0101al.jpg
│     │□│A0101bs.jpg onclick→<左>A0101bl.jpg   
│     │□│A0101cs.jpg onclick→<左>A0101cl.jpg
└─────┴─┘
 
>いずれにせよ2つのページ(通常のページAと別ウィンドウのページB)を作った方が簡単でしょう。

すみません。ここがよくわかりませんでした。▼次であっていますでしょうか?
■通常ページA
┌───────┐   
│商品画像   │   
│A0101.jpg   │ ←画像をクリックして
│       │ ↓別ウインドウBを開く 
│       │ onclick='location.search="A0101"'?
└───────┘ 
■別ウインドウB
┌─────┬─┐   
│拡大画像 │□│   
│A0101l.jpg │□│
│     │□│   
│     │□│
└─────┴─┘
document.write("<tr><td>A0101l.jpg></td>
<td><img src=A0101s.jpg><br><img src=A0101as.jpg><br><img src=A0101bs.jpg><br><img src=A0101cs.jpg><br></td></tr>");

以上のような説明でうまく伝わりましたでしょうか?
イメージと同じものはこの前に紹介したvictoria secretのページです。
何かと説明不十分で申し訳ありませんが、お手すきのときに教えていただければ何よりです。よろしくお願いいたします。

補足日時:2005/09/07 22:52
    • good
    • 0

>「商品画像だけではクリックすると拡大写真が現れることがわからない。


>一見しただけでもわかるように商品画像の下に”商品の拡大写真”という
>テキストリンクを設け、商品画像をクリックしたときと同じように
>商品の拡大写真が現れるようにする」


方法はいくつかありますが、

リンクを次のように、
<a href="#" onclick="return largeImage('picture/EL050301.jpg')">商品の拡大写真</a>

そしてlargeImage関数を次のようにすると目的の機能が追加できます。
function largeImage(img){
(img.length >= 0 ? img : img.src).match(/^(.+)\.([^\.]+)$/);
var lisrc = RegExp.$1 + "L." + RegExp.$2;
objImg = new Image();
objImg.src = lisrc;
setTimeout("getSize()", 200);
return false;
}


ちなみに試してみたコードが成功しないのは必要な引数がないからです。
<a href="#" onclick="winOpen('picture/EL050301L.jpg',0,0,'yes');return false;">商品の拡大写真</a>

ただこれだとJavaScriptが読めないでもURLがばれかねませんしスクロールバーが常に表示されます。

この回答への補足

665さん、ご連絡遅くなりまして申し訳ありません。休み中にもかかわらず早々の対応に頭が下がるばかりです。クライアントに確認するのに時間がかかりお礼を申し上げるのが遅くなって心苦しい限りです。
さてクライアントに見せたところ、また厳しい注文を出されて参っています。できるだけスクリプトを書いてみましたが、引数など肝心なところがわかっていないようで先に進めません。難易度が高すぎるので断ろうかと思ったのですが、最後の望みで投稿しました。容易に解決できないような難易度であれば教えてください。クライアントにも納得してもらいます。お手すきのときにアドバイスいただければうれしいです。

●同商品の他の画像のサムネイルを載せて他の画像の拡大写真も見られるようにする。
▼次のサイトの仕様と同じ。商品写真下のALTERNATE VIEWまたはLAREGER VIEWをクリックすると現れる。
http://www2.victoriassecret.com/commerce/applica …

▼追加する仕様
1.商品写真または”商品の拡大写真のテキスト”をクリックすると拡大写真が別ウインドウで開く。
2.同ウインドウ内に商品写真のサムネイルと同商品のその他の写真のサムネイルが現れる。
3.サムネイルをクリックするとそれぞれの拡大写真に入れ替える。
※2.まで作ってみたのですが根本的に考え方が違っているようです。3.はdreamweaverのswapImageを利用しようとしましたが、先に進めませんでした。

商品写真A0101(拡大写真A0101l)
その他の商品写真A0101a,A0101b,A0101c…(拡大写真A0101al,A0101bl,A0101cl)
※拡大写真は末尾にlが付く。
※その他の写真はオリジナル写真の末尾にa,b,c...と付く。不定数。最大でも6枚程度
※オリジナル写真1枚だけのときは引数1としてサムネイルはオリジナル写真のみ。その他の写真が2枚あるときは引数3とする。


▼書いてみたスクリプト
<script type="text/javascript">
<!--
var objImg;
function winResize(win, img){
var objImg = new Image();
objImg.src = img;
win.resizeBy(objImg.width + 116 - 600 , objImg.height > 600 ? 0 : objImg.height - 600);
}

function winOpen(lisrc, w, h, bar) {
var newWin = window.open("","","width=" + (w ? w : "600") + ",height=" + (h ? h : 600) + ",scrollbars=" + bar).document;
newWin.open();
newWin.write('<html><head><title>拡大画像</title><style type="text/css"><!-- body {padding:0;margin:0;text-align:left;} #blank {position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;} --></style></head>');
newWin.write('<body oncontextmenu="alert(\'画像コピー禁止\');return false" onselectstart="return false" ondragstart="return false">');
newWin.write('<table><tr><td><img src="blank.gif" alt="" id="blank"><img src="' + lisrc + '" alt=""' + (w && h ? '' : ' onload="opener.winResize(self, this.src)"') + '></td><td width="100" align="center" valign="top" bgcolor="#CCCCCC"><SCRIPT Language="JavaScript"><!-- alternateImage(img,3); //--></SCRIPT></td></tr></table>');
newWin.write('</body></html>');
newWin.close();
}

function largeImage(img){
(img.length >= 0 ? img : img.src).match(/^(.+)\.([^\.]+)$/);
var lisrca = RegExp.$1 + RegExp.$2;


 // クリックした写真のサムネイル//
var lisrc = RegExp.$1 + "l." + RegExp.$2; // 拡大写真は末尾にlが付く//
objImg = new Image();
objImg.src = lisrc;
setTimeout("getSize()", 200);
return false;
}

function getSize(){
var bar = "";
var w = objImg.width;
var h = objImg.height;
if (w) {w += 116;}
bar = (h > 600 || !h) ? "yes" : "no";
if(h > 600) {
h = 600;
}

var a=new Array("a","b","c","d","e"); // その他の写真は末尾にa,b,c...が順に付く。その他の画像の拡大写真はal,bl,cl...//
function alternateImage(img,n){
document.write('<br><img src="' + lisrca + '" alt=""><br>'); // クリックした写真のサムネイルを表示する。//
var i=0;
for (i=0;i<n;i++;){
var lisrca = RegExp.$1 + 'a[i]' + RegExp.$2;
document.write('<br><img src="' + lisrca + '" alt=""><br>');
} // その他の写真のサムネイルを枚数分表示する。//
}

winOpen(objImg.src, w, h, bar);
}
//-->
</script>

補足日時:2005/09/06 06:03
    • good
    • 0

すみません。

少し読み間違えていました。
#3は600px以上のときにサイズが変化するようになっていました。

これが修正したものですが、ウィンドウが開いた後でスクロールバーの表示非表示の切り替えができないみたいなので、最初から表示された状態になります。

<script type="text/javascript">
<!--
var objImg;
function winResize(win, img){
var objImg = new Image();
objImg.src = img;
win.resizeBy(objImg.width + 20 - 600, objImg.height > 600 ? 0 : objImg.height - 600);
}

function winOpen(lisrc, w, h, bar) {
var newWin = window.open("","","width=" + (w ? w : "600") + ",height=" + (h ? h : 600) + ",scrollbars=" + bar).document;
newWin.open();
newWin.write('<html><head><title>拡大画像</title><style type="text/css"><!-- body {padding:0;margin:0;text-align:center;} #blank {position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;} --></style></head>');
newWin.write('<body oncontextmenu="alert(\'画像コピー禁止\');return false" onselectstart="return false" ondragstart="return false">');
newWin.write('<p><img src="blank.gif" alt="" id="blank"><img src="' + lisrc + '" alt=""' + (w && h ? '' : ' onload="opener.winResize(self, this.src)"') + '></p>');
newWin.write('</body></html>');
newWin.close();
}

function largeImage(img){
img.src.match(/^(.+)\.([^\.]+)$/);
var lisrc = RegExp.$1 + "L." + RegExp.$2;
objImg = new Image();
objImg.src = lisrc;
setTimeout("getSize()", 200);
}

function getSize(){
var bar = "";
var w = objImg.width;
var h = objImg.height;
if (w) {w += 20;}
bar = (h > 600 || !h) ? "yes" : "no";
if(h > 600) {
h = 600;
}
winOpen(objImg.src, w, h, bar);
}
//-->
</script>

スクロールバーの有無の判断が必要になったため少しコードが長くなりましたが、簡単に説明すると次のようになっています。

まず一端拡大画像をロードし、画像サイズを取り出す。
取り出しに成功すれば、適切なサイズでウィンドウを開く。
ロードに時間がかかり一定時間内に画像サイズが分からなかった場合、
ウィンドウを開き、その後ウィンドウサイズを変更する。

この回答への補足

665さん、お礼が遅くなりまして申し訳ありませんでした。
詳細なスクリプトまで作っていただき大変感激です。
希望とおりの動作に思わず小躍りしてしまいました!

最後にもうひとつだけ機能を加えようといろいろコードを書いてみたのですが思うように動作してくれません。どこが間違っているのでしょうか?
恐らく基本的なことを理解していないためだと思います。
何度もお手間をかけてしまって大変心苦しいのですが、ご指導いただければうれしいです。

▼加えたい機能
「商品画像だけではクリックすると拡大写真が現れることがわからない。一見しただけでもわかるように商品画像の下に”商品の拡大写真”というテキストリンクを設け、商品画像をクリックしたときと同じように商品の拡大写真が現れるようにする」

▼画面
┌─────   
│商品画像    ←画像リンク
│A0101.jpg
└─────
”商品の拡大写真”←テキストリンク

▼試してみたコードの一例
<img src="picture/EL050301.jpg" onclick="largeImage(this)"><br>
<a href="#" onclick="winOpen()">商品の拡大写真</a>

補足日時:2005/09/02 20:57
    • good
    • 0

画像のサイズ所得にそんな方法があったとは気付きませんでした。


サイズの指定を不要にしたことと、透明な画像(ここではblank.gifとします)を付けたのが主な改良点です

縮小画像のIMG要素に次のonclick属性を追加

onclick="largeImage(this)"


このスクリプトを<head>~</head>に

<script type="text/javascript">
<!--
function winResize(win, img){
var objImg = new Image();
objImg.src = img;
win.resizeBy(objImg.width + 20 - 600, objImg.height <= 600 ? 0 : objImg.height - 600);
}

function largeImage(img){
img.src.match(/^(.+)\.([^\.]+)$/);
var lisrc = RegExp.$1 + "L." + RegExp.$2;
newWin = window.open("","","width=600,height=600").document;
newWin.open();
newWin.write('<html><head><title>拡大画像<\/title><style type="text/css"><!-- body {padding:0;margin:0;text-align:center;} #blank {position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;} --><\/style><\/head>');
newWin.write('<body oncontextmenu="alert(\'画像コピー禁止\');return false" onselectstart="return false" ondragstart="return false">');
newWin.write('<p><img src="blank.gif" alt="" id="blank"><img src="' + lisrc + '" onload="opener.winResize(self, this.src)" alt=""><\/p>');
newWin.write('<\/body><\/html>');
newWin.close();
}
//-->
</script>

IE6とFirefoxで動作を確認しています。
    • good
    • 0

補足のスクリプトもそうだけど横幅は取得できるみたい、それぞれのブラウザの対応状況は知らないけど。

IE6はできました。
img = new Image();
img.src = "picture/A0101L.jpg";
w = img.width;

この回答への補足

Manuelさん、お返事が遅くなって申し訳ありません。書き込みを見落としていたようで、今気が付きました。
丁寧に教えていただきありがとうございました。

補足日時:2005/09/06 06:11
    • good
    • 0

まず、「拡大画像の横幅を調べ」ということですが、画像そのものの持つサイズは調べることができません。


したがって、あらかじめ調べて引数で指定する必要がありそうです

まずこのスクリプトを<head>~</head>に
<script type="text/javascript">
<!--
function largeImage(img, width){
img.src.match(/^(.+)\.([^\.]+)$/);
var lisrc = RegExp.$1 + "L." + RegExp.$2;
var newWin = window.open("", "", "width=" + (width + 20) + ",height=600");
newWin.document.open();
newWin.document.write('<html><head><title>拡大画像<\/title><\/head><body oncontextmenu="return false" onselectstart="return false" ondragstart="return false" style="text-align:center;"><p><img src="' + lisrc + '" alt=""><\/p><\/body><\/html>');
newWin.document.close();
}
//-->
</script>

次に縮小画像のIMG要素に次のonclick属性を追加してください。
600の部分は拡大画像の横幅です。適当な値に変えてください。

onclick="largeImage(this, 600)"


それから気休め程度にコピーを防ぎたいなら、スクリプトをJSファイル化したりコードを難読化するといった方法があります。
また透明な画像blank.gifを用意して、拡大画像と一緒に次のIMG要素を記述するようにすれば多少コピーのされにくさは高まるかと思います。
<img src="blank.gif" style="position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;" alt="">

この回答への補足

665さん、丁寧に教えていただきありがとうございます。
イメージしていたものとかなり近いもので大変うれしいです。早速あれこれいじってみました。

> また透明な画像blank.gifを用意して、

なるほど!目からうろこです。これにはまったく気がつきませんでした。これは効果的ですね。右クリック禁止のアラート表示とともにぜひ取り入れさせてもらいます。

> 「拡大画像の横幅を調べ」ということですが、画像そのものの持つサイズは調べることができません。

サイズは調べることができないんですね。
それでは▼こちらで紹介されているスクリプトと組み合わせて、画像の幅の大きさにウインドを開くことはできませんでしょうか?

「画像を、ぴったりの大きさの別ウィンドウで開く」
 http://mugi.cc/js/000307.htm

アパレルサイトのため着用写真が多く、写真は縦長で拡大画像の高さはモニターの高さを超えています。そのため▼ノードストロームのサイトのように高さは600px程度に固定して縦方向にスクロールバーを付けたいと考えています。
▲上のスクリプトの場合だと画像の高さがモニターを越えてしまうと下の方が見えなくなってしまって不便です。
もし可能であればノードストロームのサイトのように高さが600px未満なら画像の高さにあわせて、600px以上なら600pxに固定というのがいちばん理想的です。

http://store.nordstrom.com/popup/product/largerv …

お手数をおかけしますが、もう少しだけお力をお借りできませんでしょうか?
自分なりにスクリプトを組み合わせて試してみたのですが、すぐにエラーが出て何ともうまくいきません。
お時間あるときに教えていただければ幸いです

補足日時:2005/09/01 09:18
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!