カテゴリーアーカイブ JavaScript

村上 著者:村上

【JavaScript】aタグでの画面遷移をキャンセルする方法

久しぶり?なJavaScriptについての私用備忘録。
今回は、HTMLのaタグをクリックした際に、画面遷移をさせない方法についてです。

例えば、下記のように指定していた場合に使えます。

<a href="#">リンク1です</a>

普通に実行すると、URLの最後に # が付いてしまいますが、画面遷移を無効にすることで、URLの最後に # が付くことを防ぐことができます。

 

で、この実装方法ですが、preventDefault というメソッドを使います。
具体例は下記のとおり。

// 本サイトのトップページへのリンクです
<a href="https://cpoint-lab.co.jp/" id="link">https://cpoint-lab.co.jp/</a>
// リンクの要素を取得
var element = document.getElementById("link");
element.addEventListener("click", function(e){
    // リンクがクリックされたときの処理
    e.preventDefault();  // 画面遷移を無効化
}, false);

コード自体は、実にシンプルです。
リンクがクリックされたときに、デフォルトのイベント=画面が遷移するのを抑止しています。

なお、jQuery の場合は、下記のように記述します。

$("#link").on('click', function(e){
    e.preventDefault();  // 画面遷移を無効化
});

クリックを検知している箇所の記述が違うだけですが、こんな感じ。

他にも、stopPropagation というメソッドや return false で遷移を無効化している例もありましたが、個人的にはこれが一番わかりやすかったので、こちらを使用しています。

 

以上、aタグでの画面遷移をキャンセルする方法でした。
なお、フォームの送信をキャンセルするのにも使えます。
画面遷移は使用頻度低そうですが、フォームの送信キャンセルは ajax とかでよく使われるので、覚えておいて損はないはず。
似たようなことでお困りの方は、是非ご参考にしていただければ幸いです。

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】要素に指定したCSSスタイルを取得する方法

CSSの変更や追加だったら、

// IDがcontentの要素の横幅を100pxに変更
$("#content").css('width', '100px');

上記のような記述が有効ですが、単にCSSの取得だけをしたかったので、方法をまとめ。

なお、今回参考にしたサイトはこちらです。

styleタグのCSSや外部CSSの値を取得 – 三等兵
http://d.hatena.ne.jp/sandai/20100616/p1

 

結果だけ先に載せると、下記のように記述すると、各スタイルが取得できます。

// ID が contentの要素のCSSを取得
var element = document.getElementById('content');
var style = element.currentStyle || document.defaultView.getComputedStyle(element, '');

あとは、取得したいプロパティを指定すれば、そのプロパティの値を取得できるので、if 文の条件式に入れるなりして使用できます。

if(style.display == 'none'){
    // displayプロパティの値が none の時のみ実行する処理
}

 

上で紹介したサイトによると、.style は 要素に対して style 属性で指定したスタイルしか取得できないとのこと。
サンプルはこんな感じ。

<div id="content" style="width:100px"></div>
var element = document.getElementById('content');
console.log(element.style.display);

そのため、上記のコードでは、width は取得できますが、display は取得できないとのこと。
なので、読み取り専用の getComputedStyle() メソッドを使って、スタイルを取得しています。
また、currentStyle はIEの独自規格で、getComputedStyle() が使えないIEで実行したときのための記述です。
もしIEでは絶対に使わないとのことでしたら、currentStyleは省略してもよさそうですね。

 

ということで、JavaScriptでCSSで指定したスタイルを取得する方法でした。
私は、指定した要素の表示・非表示に応じて、とある処理を実行するかどうかを変更したかったので、今回こちらの処理を使いました。
が、普通にCSSの変更だけなら、今回の記事の一番最初に書いた処理でOKなので、あまり使用頻度は高くなさそうですね。

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】フォームの送信ボタンの2重クリックを防止する方法

最近このフォームの2重送信に悩まされているので、とりあえず思いついた対処をメモ。
しかし、まだ解決には至っていません…何故効かないのか…。

 

■ ボタンを無効化する(disabled)

送信ボタンを押した後、JavaScriptで、そのボタンを押せなくする方法です。
これが一番わかりやすいかな?
サンプルコードは下記のとおりです。

<form>
    <input id="submit" type="submit" value="送信" />
</form>
var postingFlg = false;
$("#submit").on("click",function(){
    document.getElementById("submit").disabled = true;
    $.ajax({
        type: "POST",
        url: "送信先URL",
        data: "送信するデータ",
        success: function(msg){
            document.getElementById("submit").disabled = false;
        });
    }
});

ボタンが押されたら、ボタンを「disable = true」にし、送信などの処理が終わったら「disable = false」にして、再びボタンを有効化します。
そうすることで、処理中はボタンを押しても処理が走らないようにすることができます。
これは直感的で使いやすい印象ですね。

 

■ フラグを立てる

上のと少し似ていますが、こちらはフラグとなる変数を宣言し、その内容を見るパターン。
サンプルはこんな感じ。

<form>
    <input id="submit" type="submit" value="送信" />
</form>
var postingFlg = false;
$("#submit").on("click",function(){
    if(!postingFlg){
        postingFlag = true;
        $.ajax({
            type: "POST",
            url: "送信先URL",
            data: "送信するデータ",
            success: function(msg){
                postingFlg = false;
            }
        });
    }
});

送信の処理は、postingFlg の値が false の時のみ実行するようにしておきます。
そしてボタンが押されたら、postingFlg の値を true にし、処理が終わったら、postingFlg を false に戻します。

 

とりあえず試したのは上記の2つです。

個人的な好みは、1つ目のボタンの無効化ですね。
そもそもボタンを押せなくなるので、ユーザ側にもわかりやすいかと思います。
が、このあたりは、状況に応じて使い分けてください。
そして、もっといい方法があれば、是非お教えいただきたい…!
どうぞよろしくお願い致します。

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】配列←→JSON文字列に変換する方法

今回はJSONの取扱いについて。
JSONから配列へ、もしくはその逆をやることがあるので、まとめてみます。

 

■ JSON → 配列

JSON文字列を配列にするときには、JSON.parse() を使います。
使用例は下記のとおりです。

var json_text = '{ "a" : 100, "b" : 200, "c" : 300 }';
var arr = JSON.parse(json_text);

 

■ 配列 → JSON

先程とは逆に、配列をJSON文字列に変換したいときは JSON.stringify() を使います。

var arr = ["a","b","c"];
var json_text = JSON.stringify(json_text);

 

パッと見ただけでは、何かが変わったようには見えないのですが、確かに配列←→JSON文字列に変換できていました。
JavaScriptでは、Ajaxの処理をするときに、渡すデータが JSON だったり、もしくは結果が JSON で返ってきたりするというシチュエーションが多いかな?
意外と使用頻度は高そうですが、特にスペルミスで、再検索したりするので、この機会に備忘録を兼ねてまとめてみました。
私は特に stringify のつづりを間違えます…。iが抜けるとか。

もしJSONを扱うときがあったら、ご活用いただければと思います。

  • この記事いいね! (2)
村上 著者:村上

【JavaScript】テキストボックスに当てられたフォーカスを外す方法

今回はタイトル通り、Webサイトなどでテキストボックスに当てられたフォーカスを解除する方法です。
パソコンでは特に問題ないのですが、スマートフォン、特にAndroidでフォーカスが外れなかったために、ソフトフェアキーボードが消えず、ちょっと面倒な目にあったんですよね…。

で、肝心の方法ですが、フォーカスを外したいタイミングで下の3行を実行するだけ。

// 現在アクティブな要素を取得する
var active_element = document.activeElement;
// フォーカスを外す
if(active_element){
  active_element.blur();
}

いたってシンプル&簡単です!

 

ただ、この処理は要素からフォーカスを外すだけなので、逆に指定した要素にフォーカスを当てたい場合は下記のように記述します。

var element = document.getElementById("フォーカスを当てたい要素のID"); 
element.focus(); // カーソルを合わせる

 

ということで、要素からフォーカスを外す方法でした。
そこまで使用頻度は高くなさそうですが、覚えておけば便利かも?
もし、使う場面があれば、是非ご活用ください。

  • この記事いいね! (0)
村上 著者:村上

【Cordova】cordova-plugin-facebook4でFacebookログインのパーミッションを複数指定する方法

CordovaアプリでFacebookログインをする時に利用するプラグイン「cordova-plugin-facebook4」でちょっとハマったので備忘録もかねてまとめ。
「cordova-plugin-facebook4」の導入については、下記をご確認ください。

GitHub – jeduan/cordova-plugin-facebook4
https://github.com/jeduan/cordova-plugin-facebook4

今回やりたいのは、ログイン時に、利用者に公開プロフィールの一部とメールアドレスへのアクセスを許可するかを確認し、名前とメールアドレスを取得する、です。
ログイン機能自体はプラグインがすでに用意されているのでこちらを利用します。
ただ、public_profile を指定して取得できる公開プロフィールの中にメールアドレスは含まれていないため、emailについても指定する必要がありました。
が、何故か挙動がおかしい、と若干ハマりました。

 

先に、正常に動作したコードをお見せすると、下記のように記述しました。

facebookConnectPlugin.login(["public_profile","email"],
    function(result) {
        // ログイン成功時の処理
    },
    function(error) {
        // ログイン失敗時の処理
    }
);

ログイン処理を行う、facebookConnectPlugin.login() という関数の第一引数にパーミッションを配列で記述すると、その指定したパーミッションを許可するか、ログイン時に利用者に確認してくれます。

で、何が間違っていたかというと、一緒に指定するパーミッションのようでした。
現在開発中のこのアプリは、アプリからFacebookへの投稿も行う機能もあるため、publish_actions というアプリの利用者の代わりに、投稿ができるパーミッションを許可するかも確認しているのですが、この publish_actions と一緒に email を記述していたのが問題のようでした。
そのため、public_profile と email を一緒に確認し、そのあとで publish_actions を確認する、という流れにすると問題なく動作しました。
読み込みのみのパーミッションと、読み込み&書き込みのパーミッションは、混合して記述してはいけない、という事みたいですね。

Facebookログインのパーミッションについて、詳しくは下記のFacebookのリファレンスを確認してください。

アクセス許可のリファレンス – Facebookログイン
https://developers.facebook.com/docs/facebook-login/permissions

なお、基本的なアクセス許可(公開プロフィールの一部取得、メールアドレス取得、友達のリストにアクセス)では、Facebookの審査は必要ありませんが、その他のパーミッション(アプリからFacebookに投稿など)は審査が必要です。

 

些細な指定ミスでしたが、記述の形式自体は合っていたために、修正に手間取りました。
皆様、もFacebookログインを利用する際は、十分お気を付けください。

  • この記事いいね! (0)
村上 著者:村上

【アプリ】Cordovaで開発したアプリを高速化するポイント

現在開発中のアプリがようやく完成間近の形になってきたので、機能以外の改善も行い始めました。
それがアプリの速度改善!
特にAndroidで動作させると遅いので、調べながらではありますが、手を付け始めています。

今回参考にしたサイトはこちら。

PhoneGapアプリのパフォーマンスを改善する10のポイント -Adobe MAX 2013
https://news.mynavi.jp/article/20130520-am2013pg/

成功するPhoneGapアプリを開発するための高速化&UXテクニック
http://blog.asial.co.jp/1142

どちらも2013年の記事なのでやや古めですが、参考になりそうな内容です。

 

で、まずは手っ取り早く試せそうなものを一つずつ試してみました。

1.ハードウェアアクセラレーションを意識してCSS Transitionsを利用する

具体的には、CSSに下記のスタイルを適応することです。

transform: translate3d(0, 0, 0);

このスタイルを追加することで、HTML DOMの描画にGPUが用いられるようになるとのこと。
そうすると、滑らかな描画を実現でき、さらにアプリの速度が大きく向上することもあるそうです。
ただし、あまり多くのHTML DOM要素の描画にGPUを用いると、GPU上の利用可能メモリーが埋まってしまう可能性があり、そうすると突然アプリがクラッシュする危険性もあるとのこと。
特に、深くネストされたDOM要素にこのスタイルを適応すると、上記のようにアプリがクラッシュすることがあるため、安易に追加するのは控えるべきですね。

2.Clickイベントは使用しない

スマートフォンのClickイベントは、画面がタッチされてから発生するまでに300msほどの遅延があるため、Clickイベントの仕様は、動作が遅くなる原因になります。
そのため、代わりにTouchStartを使用するか、FastclickなどのスマホでのClickイベントの応答速度を早くするライブラリを利用するのが良いとのこと。
ちなみに、開発中のアプリには、このFastclickを導入しています。

Fastclick の導入については、こちらを参考にしました。

スマホのクリック応答速度を劇的に速くしてくれる 『FastClick』 の使い方
http://phiary.me/fastclick-usage/

 

3.コンテンツのリフローを控える

リフローとは、要素の位置や大きさなどの再計算を行うことを指します。
リフローの計算は負担が大きいので、必要最小限に抑えるべきとのこと。

…これやってる…。
でも、この処理はどうしてもやらなければならないので、どうにかならないか確認しなければですね。
あとは、下記も効果的とのこと。

  • DOM要素の数を減らす
  • 深くネストされたHTML DOM構造を避ける

…これもやっちゃってるなぁ…。
これについては、コードを確認して、削れそうなところは削らねば。
 

4.テストする

最後のポイントとしては、実際のデバイス、実際のデータを使い、実際の環境でテストする、とのこと。
特に、少し古めのスペックが低めの端末でテストするのがよさそうですね。
私は、私用の端末はそこそこ良いものを買ってしまったので、案外サクサクと動いてしまい、あまり参考にならない…。
会社にあるテスト用端末をお借りしなければですね。

 

他にもまだ改善点はありますが、とりあえず私が試せたもの、確認したものは以上です。
とりあえず、リフローを改善しよう…!

私と同じくCordovaのアプリを開発している方は、是非参考にしてみてください。

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】指定した文字に一致したすべての文字を置換する方法

少し久しぶりな気がするJavaScriptネタ。
今回は、これまた業務中に質問された、文字列の置換について。
自分でも少しハマりやすいと思った点なので、おさらいもかねてまとめます。

 

文字列を置換するには、.replace() というメソッドを使います。
使い方は下記の通り。

var text = "あいうえお";
var replaceText = text.replace("あ","か");
document.write(replaceText);

こちらを実行した結果は、「かいうえお」となります。
変数text内の「あ」が「か」に置換されました。

 

で、ハマるポイントはここから。
上の例のように、置換したい文字が文字列に1つしかない場合はこちらでも問題ないのですが、置換したい文字が文字列の中に複数あった場合は、この方法ではうまくいきません。

例としては下記の通り。

var text = "あああああ";
var replaceText = text.replace("あ","か");
document.write(replaceText);

上記のコードを実行した結果は、「かああああ」となり、一番最初の「あ」しか置換されていません。
これを防ぐためには、正規表現を使うか、RegExpオブジェクトを使う方法があります。

 

まず、正規表現を使う方法は下記のとおり。

var text = "あああああ";
var replaceText = text.replace(/あ/g,"か");
document.write(replaceText);

こちらを実行すると、すべての「あ」が「か」に置換され、「かかかかか」と出力されます。

次に、RegExpオブジェクトを使う方法について。
RegExpは、正規表現用のオブジェクトであるとのこと。
あまり使ったことはないのですが、正規表現が苦手!という人にはこちらの方がわかりやすいのかも?

なお、下記の二つは同じ意味になります。

var regExp = /あ/g ;
var regExp = new RegExp( "あ", "g" ) ;

そして、RegExpを使ったコードの例は下記の通り。

var text = "あああああ";
var targetStr = "あ" ;
var regExp = new RegExp( targetStr, "g" ) ;
var replaceText = text.replace(regExp,"か");
document.write(replaceText);

こちらも実行した結果は「かかかかか」となります。

 

.replace()メソッドは便利ではありますが、単に文字列を指定するだけだと、最初にヒットした文字列しか置換されない、という点が要注意ですね。
久しぶりに使ったときは、この癖を忘れていて改めて調べ直してしまいました。
正規表現を使うという点が、苦手意識を持っている人には少しだけネックかもしれませんが…。
なお私はよく「正規表現チェッカー」というサイトで正規表現が正しいかどうか確認します。
ページ下部にリファレンスも載っているのでお勧めです。

正規表現チェッカー PHP: preg_match() / JavaScript: match()
http://okumocchi.jp/php/re.php

  • この記事いいね! (0)
村上 著者:村上

Safariで「YYYY-MM-DD HH:II:SS」形式をDate.parse()するとNaNを返す問題とその対処法について

昨日この仕様でハマったので覚え書きもかねて。

JavascriptのDate.parse()とは、カッコ内の日時文字列を解析して、1970年1月1日 00:00:00からのミリ秒数に変換してくれる関数です。
具体的には下記のように使用します。

Date.parse('Thu, 1 Nov 2017 13:41:00 GMT+0900');
// =1509511260000

が、この解析できる日付文字列の形式が限られており、よくデータベースで用いられている「YYYY-MM-DD HH:II:SS」形式の日付文字列を入れてしまうとNaNを返すとのこと。

どうやら文字列の中にハイフンが入っていることが原因のようです。
また、Date.parse()だけではなく、new Date()のなかにハイフンを用いた日付文字列を入れた場合でも、同じくNaNを返す仕様になっているとのこと。
なお、一部のブラウザでは、ハイフンにも対応しているようで Google Chrome では、「YYYY-MM-DD HH:II:SS」形式でも、正しくミリ秒数が返ってきました。
普段使用しているブラウザが Google Chrome だったため、他ブラウザで動作検証するまで気が付きませんでした。

 

こちらの仕様については、ハイフンスラッシュに置換することで対応できました。
具体的なコードはこちら。

Date.parse([日付文字列].replace(/-/g , "/"));

replace関数を用いて、ハイフンをスラッシュに置換することで、無事日付のミリ秒数が取得できました。

 

以上、今回私がハマったJavascriptの関数でした。
そもそも、日付をミリ秒数に変換するなんてこと早々しないので、実際に触ってみるまで、こんな仕様になっているとは全く知りませんでした。
原因がわかってしまえば対処は難しくありませんでしたが、知らないと原因特定までに時間がかかりそうな仕様でしたので、Javascriptで日付を扱うときは十分お気を付けください。

  • この記事いいね! (1)