jQueryでスライダーを作ったのですが、一般的 or メンテしやすい書き方ありますか?
受付中
回答 2
投稿
- 評価
- クリップ 0
- VIEW 681
SPAの開発に向けて、メンテしやすいコード作りを勉強してます。
jQueryでスライダーを作ったのですが、もっと良い書き方ありますか?
※今回はObserverの考え方は取り入れてません。
疑問点
- BEMベースのクラス名が長いので変数化したが、動的な部分は変数でないものもあり、混乱する
- そもそもクラス名の付け方やタグ構造が悪いから書きづらい?
- 最初に操作するセレクターはどこまで変数に格納すべきか
- BEMは使いたいけど長くなる
サンプルコード
前の質問で、アドバイスを貰い、定数のような扱いをやめました。
また動的な部分以外は、HTMLに直書きしました。
https://teratail.com/questions/126691
皆さんだったらどう書きますか?
<div id="slider" class="slider">
<div class="slider_view">
<a class="slider_view_item" href="#"><img src="img/thumb-01.jpg" alt=""></a>
<a class="slider_view_item" href="#"><img src="img/thumb-02.jpg" alt=""></a>
<a class="slider_view_item" href="#"><img src="img/thumb-03.jpg" alt=""></a>
<a class="slider_view_item" href="#"><img src="img/thumb-04.jpg" alt=""></a>
<a class="slider_view_item" href="#"><img src="img/thumb-05.jpg" alt=""></a>
</div>
<div class="slider_nav"></div>
<div class="slider_control">
<button class="slider_control_item slider_control_item-prev" type="button" data-role="none" role="button"></button>
<button class="slider_control_item slider_control_item-next" type="button" data-role="none" role="button"></button>
</div>
</div>
$(function(){
var $target = $('#slider');
var $item = $target.find('.slider_view_item');
var $prev = $target.find('.slider_control_item-prev');
var $next = $target.find('.slider_control_item-next');
var index = 1;
function init(){
var _navHtml = '<button class="slider_nav_item" type="button" data-role="none" role="button"></button>';
$item.each(function(){
$target.find('.slider_nav').append(_navHtml);
});
$target.find('.slider_nav_item').each(function(i){
$(this).on("click",function(){
view(i + 1);
});
});
$prev.on("click",function(){
view(index - 1);
});
$next.on("click",function(){
view(index + 1);
});
view(index);
}
function view(val){
index = val;
$item.hide().each(function(i){
if(index == i + 1){
$(this).show();
return false;
}
});
$target.find('.slider_nav_item').removeClass('is-active').each(function(i){
if(index == i + 1){
$(this).addClass('is-active');
return false;
}
});
var _count = $item.length;
$prev.show();
$next.show();
if(index <= 1) $prev.hide();
if(index >= _count) $next.hide();
}
init();
});
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
「jQuery plugin 作り方 」で検索して、jQuery を用いたライブラリの作り方にあわせてみるのはどうでしょう。(下記URLは検索結果の上位を適当に並べています)
【jquery プラグイン/作成】
https://qiita.com/rorono/items/11e5dbd53cb93edb8b4d
【jQueryプラグインの作り方 | てらこや.work】
https://www.terakoya.work/jquery-build-plugin/
【はじめてのjQueryのプラグインの作り方~5ステップ | Web制作・Webシステムの株式会社ワイワイエンジン】
https://yyengine.jp/blog/jquery/jquery-plugin-5step/
【jQueryプラグインの作り方について詳しく | Developers.IO】
https://dev.classmethod.jp/slide/html5-css3-jquery-jqplugin/
【初心者でも分かる!jQueryのプラグインの作り方 | Yuuの悠々自適Blog】
https://yuu.1000quu.com/how_to_make_jquery_plugin
【【jQuery】プラグインの様々な作り方(定義パターン)】
http://matometaru.com/jquery-plugin-define-patterns/
【jQueryを使うなら知っておきたいjQueryプラグインの作り方|クロノドライブ】
https://html-coding.co.jp/knowhow/tips/jquery/
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
タグの構造に関しては問題ないかと思います。
BEMの書き方に関してですが、経験上プロジェクトで使い方がカスタマイズされていることがほとんどです。ただelementを明確にするうえで、単語をアンスコ一個で繋げていくのは、避けた方がいいかと思います。
私は
・blockはハイフンなしも可。
・elementの「__」以降、単語がつながるときは「_」を利用。
・modifierはクラス名「is-***」で記述。cssのマルチクラスセレクタでの指定を許容。
というルールを提案し、採用されることが多いです。
<div id="slider" class="slider">
<div class="slider__view">
<a class="slider__view_item" href="#"><img src="img/thumb-01.jpg" alt=""></a>
<a class="slider__view_item" href="#"><img src="img/thumb-02.jpg" alt=""></a>
<a class="slider__view_item" href="#"><img src="img/thumb-03.jpg" alt=""></a>
<a class="slider__view_item" href="#"><img src="img/thumb-04.jpg" alt=""></a>
<a class="slider__view_item" href="#"><img src="img/thumb-05.jpg" alt=""></a>
</div>
<div class="slider__nav"></div>
<div class="slider__control">
<button class="slider__control_item is-prev" type="button" data-role="none" role="button"></button>
<button class="slider__control_item is-next" type="button" data-role="none" role="button"></button>
</div>
</div>
という感じでしょうか。絶対の正解はないかと思います。重要なのはチームでルールを決めてしっかりと順守することです。cssに関しても守るべきルールがありますのでこちらで確認してみてください。
[一番詳しいCSS設計規則BEMのマニュアル]
https://qiita.com/Takuan_Oishii/items/0f0d2c5dc33a9b2d9cb1
jsに関して、当方、マークアップ寄りのエンジニアなのでjsの技術は中の下程度ですが、こんな私でもさっと見たときにやっていることがなんとなく分かるので、可読性という点ではそれほど悪くないと思っています。
変数汚染を防ぐ理由でも、即時関数を利用して処理をまとめることと、view()の処理をちょっと変えました。
// 即時関数でラップして $ を引数にするとパフォーマンスが上がります
;(function($){
$(function(){
// BEMの長くなるクラス用
const prefixSlider = '.slider';
var $target = $('#slider');
var $item = $target.find( prefixSlider + '__view_item');
var $prev = $target.find( prefixSlider + '__control_item.is-prev');
var $next = $target.find( prefixSlider + '__control_item.is-next');
var $pagerItem;
var index = 0;
// スライダーの長さは最初に取得
var maxSize = $item.length;
// コンストラクタ
var init = (function(){
// pagerの生成
var createPager = (function(){
var _navHtml = '<button class="slider__nav_item" type="button" data-role="none" role="button"></button>';
$item.each(function(){
$target.find('.slider__nav').append(_navHtml);
});
$pagerItem = $target.find('.slider__nav_item');
}());
// event一覧
var myEvent = (function(){
$pagerItem.on("click",function(){
index = $(this).index();
view(index);
});
$prev.on("click",function(){
view('prev');
});
$next.on("click",function(){
view('next');
});
}());
// 描画
var drawing = (function(){
view(index);
}());
}());
function view( direction ){
if( direction === 'next' ){
// 進む
index = ( index >= (maxSize-1) ) ? 0 : ++index;
}else if( direction === 'prev' ){
// 戻る
index = ( index <= 0 ) ? (maxSize-1) : --index;
}else{
// 番号指定
index = direction;
}
// 指定番号を表示、ほかの兄弟要素非表示
$item.eq(index).show().siblings().hide();
// 指定番号をアクティブ、ほかの兄弟要素非アクティブ
$pagerItem.eq(index).addClass('is-active').siblings().removeClass('is-active');
}
});
}($));
ループを計算する処理は、view()の最初の処理でやりました。pager押された時の番号指定も雑ですが、同じif文の中で処理しています。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 89.99%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる