[jQuery]wordpressで画像にリンクしてるときだけlightboxしたい

wordpressで記事書いてて思うのは、aタグは普通のページリンクと、拡大画像表示用と2種類あって、毎回毎回aタグにclass=”lightbox”って書くのがめんどくさ…
いや、手間だしヒューマンエラーもあるようなので、記事を書く際に画像を入れたら勝手に拡大画像へのリンクが付く事ですし、めんどうな事は機械にやってもらいました。

[javascript]
<script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/js/jquery.lightbox.js"></script>
//↑lightboxのプラグイン

$(function(){
$(‘div.entry-content a’).has(‘img’).click(function(){
$(‘div.entry-content a’).lightbox();
});
});
[/javascript]

「.has()」でimgタグがあるかを判断して、あった場合にlightboxするようにしてます。
if使わなくていいのが楽でいいね。

このページを参考にしました。
https://js.studio-kingdom.com/jquery/traversing/has

追記

ご指摘をもらいました。

これでいいらしいです。ちゃんと動きました。
[javascript]
$(‘.entry-content a:has(img)’).lightbox();
[/javascript]

[jQuery]$(document).readyと$(window).loadの違い[自分メモ]

今までずっとjqueryの実行タイミングをデフォで$(document).readyで書いてました。
今更こんな事書いたら、いろんなお客さんから怒られそうですが、今まで作ってきたjsアニメーションの実行のタイミングは何かをクリックしたら動かすといったような、必ずトリガーが何かしらあるものでした。

で、ちょうど今ページ読み込みと同時に動くアニメーション作っているのですが、PC環境だと問題なくてもスマホで問題があるんすよ。
wifiならまだしも、3G環境でただでさえ読み込みに時間がかかる状態で実行のタイミングが$(document).readyだと、スマホでデータの読み込みが終わった時点でアニメーションが終了しているという本末転倒な事態になる事が判明。

$(document).readyってなんぞ

DOMが読み込まれた時点で実行します。
htmlの構造が読まれた時って事だもんで、画像ファイルの読み込みを待たずにスクリプトの処理を開始します。

じゃあ$(window).loadってなにさ

DOM内に含まれる全ての要素の読み込みが完了した時点で実行します。
なので、今回の懸念である「3G回線」で画像の読み込み待ってる間にアニメーション終わっとるがな、という事態を解消するにはうってつけだったわけで。

ただ、調べている間に見つけたサイトには$(document).readyの方が良い的な事書いてあったので、$(window).loadはあまり推奨はされていないみたいですね。
うーん、もうちょっと勉強が必要だなぁ。

今気づいたけどもう2ヶ月もconcrete5に関する記事書いてないや…。

[Concrete5]メールフォーム送信時にページの先頭に移動してしまう問題

前回の記事同様、Concrete5についているフォームブロックには結構不満があってですね。

送信ボタン押した時に、ページの先頭に行っちゃうんですよ。

例えば「お問い合わせ」っていうお問い合わせ専門のページを作って、コンテンツ部分はフォームのみしか存在しないっていう場合は、ページの先頭に戻ってもウインドウ上にはフォームのエリアが見えているから、エラーがあった場合や、確認画面、完了画面も見えるから言う程問題じゃないんですが、
縦1000pxくらいの紹介コンテンツがあって、「申し込みは以下のフォームから」みたいなフォームを含むページの場合、送信ボタンをクリックした後にページの先頭に戻ってしまうと「あれ?これ送信できたのかな?」って思って改めてそこまでスクロールして見てもらわなきゃいけないという、ユーザに負担をかけるユーザビリティ的に非常に粗悪なものになってしまう訳です。

で、どうしたもんかなーと考えたあげく、フォームブロックのカスタムテンプレートではどうにもなりませんでした。
というのも、submitボタンクリックした時点で、フォームのID取得のためにURL内に「#」が使われてて、フォーム部分へスクロールするためのhtml側の「#」が重複して使用出来ないっていうのがあって、もう私諦めようと思いました。
お客さんには説明して、「フォームだけは別ページにしてもらえませんか」って懇願して、許してもらおうと思ったんですが、
今をときめくjavascriptちゃんなら!javascriptちゃんならきっとなんとかしてくれるッ!と思い、試してみました。

[javascript]
$(function(){
var getURL = location.href; //URLを取得
var contactScroll = $(‘#contact’).offset().top; //#contactの位置を取得
if ( getURL.indexOf( "submit_form#" ) != -1 ) { //indexOfでURL内に含まれる文字列"submit_form#"を検索して、存在した場合の処理
window.scrollBy(0, contactScroll); //ウインドウを#contactの位置までスクロール
}
});
[/javascript]

前述の様に、フォームブロックでフォームIDを取得してURLに#が使われてるなら、URLに入ってるフォームIDを逆手にとってやろうと。

↓フォームの送信ボタンをクリックしたら、URLにクッソ長いパラメータが付くのですが、共通して「cID」とか「stackID」とかが存在します。
https://www.xxxxxx.xcom/index.php?cID=1&stackID=169&bID=69&btask=passthru_stack&ccm_token=1363257182:45a7934ae05865ab764c648a45552a6b&method=submit_form#1363252323&listbeginp=

フォームのブロックに必ずつくのは「submit_form#」なので、javascriptでURL内を検索して「submit_form#」があったら「#contact」の場所までウインドウをスクロールしてやれば良いと気づいたんです!

あぁ、解決できてホント良かった!!

今さら…。jQueryとprototypeの共存とか…。

私は最近はもっぱらjQueryしか使ってないのですが、4〜5年前のトレンドというか、なんというか、prototype派の人もいたわけですよ。

でですね。

「prototype使ってて、今後はjQueryに移行したいけど、今の段階だとprototypeも残したい」みたいな案件もあるんですねぇこれが。

prototype使ってるhtmlにそのままjQuery入れると、”$”が共通して使用しているため、競合してしまってどっちかが動かないか、もしくは両方全く動かない状態に陥ります。

じゃーどうしましょう。

こーしましょう。
まず、prototype.jsから読み込みをします。
で、noConflictの記述をします。

<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/jquery-x.x.x.js"></script>
<script>
jQuery.noConflict();
var j$ = jQuery;
</script>

上記まで書けたら、解決までほぼ完了。

と言いたいところですが、jQueryで使用している”$”を全て”j$”にする必要があります(jQueryのソースファイルじゃなくて、プラグインで使用している”$”です)。

例えば、jQueryでスクロールを制御しているのであれば、

[javascript]
$(function(){
$(‘a[href^=#]’).click(function() {
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? ‘html’ : href);
var position = target.offset().top;
});
return false;
});
});
[/javascript]

と上記のように書いてあったとして、それを下記のように書き換えます。

[javascript]
j$(function(){
j$(‘a[href^=#]’).click(function() {
var href= j$(this).attr("href");
var target = j$(href == "#" || href == "" ? ‘html’ : href);
var position = target.offset().top;
});
return false;
});
});
[/javascript]

とりあえず全部の”$”を”j$”にすりゃOKです。”$”を”j$”に全置換したらいいんじゃないかしら。

これで競合せずにjQueryとprototypeが使用できるようになります。

でもまーぶっちゃけ、jQueryとprototypeを両方使うなんて普通に考えたらしないんだけど、案件次第でさ…。