質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

4160閲覧

既に定義済のclickイベントの前にチェック処理を追加したい(jQuery Bootpag)

ms5025

総合スコア292

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/01/11 03:08

前提・実現したいこと

■やりたいこと
既に定義済のclickイベントの前に独自のチェックファンクションを差し込み、
チェック不可なら定義済のclickイベントは起こさないようにしたい

■内容
現在jQuery Bootpagを使用してwebページのページング処理を行っています。
ページには商品画像、商品名、商品数(セレクトボックス)が列挙されており
1ページに表示できるmax商品数が決まっている、よくある画面です。
ページ切り替え時、ajaxで次ページのデータを取得しています。

今回、ページ切り替え時にセレクトボックスの値が選択されている場合、
「現在選択されている商品はクリアされますが次ページへ遷移してもいいか?」といった
ようなconfirmダイアログを表示する仕様が追加となりました。
キャンセルが押下されればそのままステイ、OKが押下されると次ページ遷移します。

発生している問題・エラーメッセージ

今まではjquery.bootpagの次ページ遷移処理(クリックされたページの<liタグにactiveクラスが追加されるような処理)が行われた後、
次ページを読み混むajax処理(自作のclickイベント①)が走って動いていました。

今回上記の仕様を追加するにあたり、
自作のclickイベント①側から、confirmダイアログでキャンセルが押下された場合、
jquery.bootpagの次ページ遷移clickイベントをキャンセルしたいのですが
jquery.bootpagの次ページ遷移処理が先に走る為、うまくいきません

jsの読み込み順序を変えても、jquery.bootpagのclickイベントのほうが先に走るようです。

↓ 自作のclickイベント①

js

1   2 // ページャーがクリックされたら 3 $('.bootpag').on('click', function (event, num) { 4 5     // okなら次のページ取得 6 var num = $(this).find('.active').data('lp'); 7 // データ取得して次ページ表示 8 dispPage(num); 9 10 });

以下がgitに上がってるjquery.bootpagのソースの一部です。

js

1(function ($, window) { 2 3 $.fn.bootpag = function (options) { 4 5 var $owner = this, 6 settings = $.extend({ 7 total: 0, 8 page: 1, 9 maxVisible: null, 10 leaps: true, 11 href: 'javascript:void(0);', 12 hrefVariable: '{{number}}', 13 firstLastUse: false, 14 first: '<span aria-hidden="true">&larr;</span>', 15 last: '<span aria-hidden="true">&rarr;</span>', 16 wrapClass: 'pagination', 17 activeClass: 'active', 18 disabledClass: 'disabled', 19 nextClass: 'next', 20 prevClass: 'prev', 21 lastClass: 'last', 22 firstClass: 'first' 23 }, 24 $owner.data('settings') || {}, 25 options || {}); 26 27 if (settings.total <= 0) 28 return this; 29 30 if (!$.isNumeric(settings.maxVisible) && !settings.maxVisible) { 31 settings.maxVisible = parseInt(settings.total, 10); 32 } 33 34 35 settings.next = '&raquo;次'; 36 settings.prev = '&laquo;前'; 37 38// settings.next = '&raquo;'; 39// settings.prev = '&laquo;'; 40// settings.first = '&laquo;最初'; 41// settings.last = '&raquo;最後'; 42 43 $owner.data('settings', settings); 44 45 function renderPage($bootpag, page) { 46 page = parseInt(page, 10); 47 var lp, 48 maxV = settings.maxVisible == 0 ? 1 : settings.maxVisible, 49 step = settings.maxVisible == 1 ? 0 : 1, 50 vis = Math.floor((page - 1) / maxV) * maxV, 51 $page = $bootpag.find('li'); 52 settings.page = page = page < 0 ? 0 : page > settings.total ? settings.total : page; 53 $page.removeClass(settings.activeClass); 54 lp = page - 1 < 1 ? 1 : 55 settings.leaps && page - 1 >= settings.maxVisible ? 56 Math.floor((page - 1) / maxV) * maxV : page - 1; 57 58 if (settings.firstLastUse) { 59 $page 60 .first() 61 .toggleClass(settings.disabledClass, page === 1); 62 } 63 64 var lfirst = $page.first(); 65 if (settings.firstLastUse) { 66 lfirst = lfirst.next(); 67 } 68 69 lfirst 70 .toggleClass(settings.disabledClass, page === 1) 71 .attr('data-lp', lp) 72 .find('a').attr('href', href(lp)); 73 74 var step = settings.maxVisible == 1 ? 0 : 1; 75 76 lp = page + 1 > settings.total ? settings.total : 77 settings.leaps && page + 1 <= settings.total - settings.maxVisible ? 78 vis + settings.maxVisible + step : page + 1; 79 80 var llast = $page.last(); 81 if (settings.firstLastUse) { 82 llast = llast.prev(); 83 } 84 85 llast 86 .toggleClass(settings.disabledClass, page === settings.total) 87 .attr('data-lp', lp) 88 .find('a').attr('href', href(lp)); 89 90 $page 91 .last() 92 .toggleClass(settings.disabledClass, page === settings.total); 93 94 95 var $currPage = $page.filter('[data-lp=' + page + ']'); 96 97 var clist = "." + [settings.nextClass, 98 settings.prevClass, 99 settings.firstClass, 100 settings.lastClass].join(",."); 101 if (!$currPage.not(clist).length) { 102 var d = page <= vis ? -settings.maxVisible : 0; 103 $page.not(clist).each(function (index) { 104 lp = index + 1 + vis + d; 105 $(this) 106 .attr('data-lp', lp) 107 .toggle(lp <= settings.total) 108 .find('a').html(lp).attr('href', href(lp)); 109 }); 110 $currPage = $page.filter('[data-lp=' + page + ']'); 111 } 112 $currPage.not(clist).addClass(settings.activeClass); 113 $owner.data('settings', settings); 114 } 115 116 function href(c) { 117 118 return settings.href.replace(settings.hrefVariable, c); 119 } 120 121 return this.each(function () { 122 123 var $bootpag, lp, me = $(this), 124 p = ['<ul class="', settings.wrapClass, ' bootpag">']; 125 126 if (settings.firstLastUse) { 127 p = p.concat(['<li data-lp="1" class="', settings.firstClass, 128 '"><a href="', href(1), '">', settings.first, '</a></li>']); 129 } 130 if (settings.prev) { 131 p = p.concat(['<li data-lp="1" class="', settings.prevClass, 132 '"><a href="', href(1), '">', settings.prev, '</a></li>']); 133 } 134 for (var c = 1; c <= Math.min(settings.total, settings.maxVisible); c++) { 135 p = p.concat(['<li data-lp="', c, '"><a href="', href(c), '">', c, '</a></li>']); 136 } 137 if (settings.next) { 138 lp = settings.leaps && settings.total > settings.maxVisible 139 ? Math.min(settings.maxVisible + 1, settings.total) : 2; 140 p = p.concat(['<li data-lp="', lp, '" class="', 141 settings.nextClass, '"><a href="', href(lp), 142 '">', settings.next, '</a></li>']); 143 } 144 if (settings.firstLastUse) { 145 p = p.concat(['<li data-lp="', settings.total, '" class="last"><a href="', 146 href(settings.total), '">', settings.last, '</a></li>']); 147 } 148 p.push('</ul>'); 149 me.find('ul.bootpag').remove(); 150 me.append(p.join('')); 151 $bootpag = me.find('ul.bootpag'); 152        153      //★★★ページャーでページをクリックしたらここが先に走るようです 154 me.find('li').click(function paginationClick() { 155 156 var me = $(this); 157 if (me.hasClass(settings.disabledClass) || me.hasClass(settings.activeClass)) { 158 return; 159 } 160 var page = parseInt(me.attr('data-lp'), 10); 161 $owner.find('ul.bootpag').each(function () { 162 renderPage($(this), page); 163 }); 164 return; 165 $owner.trigger('page', page); 166 }); 167 renderPage($bootpag, settings.page); 168 }); 169 } 170 171})(jQuery, window);

ページャーのhtmlです
classにactiveがついているのが現在のページです

html

1<p id="demo_top" class="demo_top"> 2 <ul class="pagination bootpag"> 3 <li data-lp="1" class="firszt"> 4 <a href="javascript:void(0);">«</a> 5 </li> 6 <li data-lp="2" class="prev"> 7 <a href="javascript:void(0);">«前</a> 8 </li> 9 <li data-lp="1" class=""> 10 <a href="javascript:void(0);">1</a> 11 </li> 12 <li data-lp="2" class=""> 13 <a href="javascript:void(0);">2</a> 14 </li> 15 <li data-lp="3" class="active"> 16 <a href="javascript:void(0);">3</a> 17 </li> 18 <li data-lp="4" class="next"> 19 <a href="javascript:void(0);">»次</a> 20 </li> 21 <li data-lp="78" class="last"> 22 <a href="javascript:void(0);">»</a> 23 </li> 24 </ul> 25</p>

試したこと

現在のページをhiddenで退避しておき、チェック処理がfalseの場合、
現在のページを再度activeに再度設定しなおすというのも考えたのですがせっかくjquery.bootpagのjsで一括設定しているのにわざわざ手動でclass切り替えをするのもどうなんだろうと思い質問してみました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

的外れかもしれませんが、document.addEventListenerで処理をいれると
jQueryより先に処理がされます

javascript

1<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 2<script> 3$(function(){ 4 $('.bootpage').on('click',function(){ 5 console.log($(this).text()); 6 }); 7}); 8</script> 9<script> 10document.addEventListener('click',function(e){ 11 e.stopPropagation(); 12 var t=e.target; 13 if(t.classList.contains("bootpage")){ 14 console.log('check'); 15 $(t).trigger('click'); 16 } 17},true); 18</script> 19<div class="bootpage">test1</div> 20<div class="bootpage">test2</div> 21<div class="bootpage">test3</div>

上記の通りcheckは2度走りますが、jQueryは1度だけ実行されます
うまく使えばclick前のチェック処理につかえるかもしれません

投稿2019/01/11 04:15

yambejp

総合スコア114757

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ms5025

2019/01/15 02:24

ありがとうございます!こちらの方法でclickイベント前にチェックを差し込むことができました! jqueryにあまり詳しくなくて困っていました。ありがとうございます。 なぜか.classList.containsが使えなくて、以下の方法にしたのですが 書き方としておかしい所があればまたコメントでもいいのでご指摘いただけますか? document.addEventListener('click', function (e) { e.stopPropagation(); var t = e.target; var node = t.parentNode.parentNode; if ($(node).hasClass('bootpag')) { // 選択中商品チェック if (checkSelectItem()) { $(t).trigger('click'); } } }, true);
yambejp

2019/01/15 02:26

ああ、確かにそうですね jQuery自体は読み込んでいるので、hasClassで十分だと思います
ms5025

2019/01/15 04:35

ありがとうございます!助かりました!ただこのやり方で既存のチェックボックスが動かなくなってしまいました。 どうやら $(t).trigger('click'); でチェックボックスの値がクリックで変わる前の値がとれてしまい、 それでチェックボックスのon/ofが正常に動かなくなってしまったようで・・・
yambejp

2019/01/15 04:40

e.stopPropagation()をif節の中にいれてください そうすれば関係ないタグに影響を与えなくなるでしょう
ms5025

2019/01/15 04:47

ありがとうございます。はい、そう思ってif文内に入れてみたんですが、それでも上記のとおり、チェックボックスの値がとれません。。。
ms5025

2019/01/15 04:48

キャッシュもちゃんと削除しました
yambejp

2019/01/15 04:51

命題のソースでは判断できません 当初言われていた.bootpageとも内容が違うようです チェックボックスはどこにあって、どう動作するのが正しいのかも 再度命題に追記してください
ms5025

2019/01/15 04:52

了解しました。ありがとうございます。
x_x

2019/01/21 04:23

bootpageに関係なくとも否応なくstopPropagation()としていますが、大丈夫なんですかね?
yambejp

2019/01/21 04:45

今回のはあくまでも提案のためのソースだったので汎用性はむしして とにかくバブリングを止めてしまいましたが 別の具体的な処理についての質問の際に、どこに設定すると良いか 提示しています
guest

0

バブリングフェーズではなく、キャプチャフェーズでイベントを捕まえれば、先に実行できるかもしれません。ただ、jQueryを介したイベントの設定では難しいかと思います。
DOMイベントのキャプチャ/バブリングを整理する 〜 JSおくのほそ道 #017 - Qiita

また、検証していませんが、jQueryのイベント実行順は、内部で変更することが可能なようですね。
jQuery のイベントハンドラの順番を入れ替える - Qiita
記事中にもあるように『jQuery の内部用 API を使うので将来動かなくなる』可能性はあると思います。

投稿2019/01/11 03:19

Lhankor_Mhy

総合スコア36072

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ms5025

2019/01/11 03:24

ありがとうございます。 jQuery のイベントハンドラの順番を入れ替える - Qiita は私も拝見しました。 しかしこれをするぐらいなら 「試したこと」に書いてある 現在のページをhiddenで退避しておく案のほうがいいのかなと個人的には思うですが どうなのでしょうか・・・
Lhankor_Mhy

2019/01/11 03:30

そうかもしれませんね。 私なら、useCapture を試すと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問