カテゴリーアーカイブ 言語

村上 著者:村上

【CSS】複数行の長い文章の文末を省略する方法

以前紹介した、長い文章の文末を省略して末尾に「…」を表示させる方法の複数行対応バージョンです。
前回のやり方では、一行のみの表示しかできないので、複数行で文末を表示させたいときはこちらの方法をお試しください。
ただし、ChromeSafari 限定ですので、その点はご注意ください。

今回参考にさせていただいた記事はこちら。

【複数行にも対応】長過ぎる文字列を省略して末尾を三点リーダー(…)にする方法いろいろ – PSYENCE:MEDIA
https://tech.recruit-mp.co.jp/front-end/tips-ellipsis/

ちなみに、以前投稿したCSSで文末を省略する方法はこちら。

【CSS】長い文章の文末を省略して末尾に「…」を表示させる方法
https://cpoint-lab.co.jp/article/201805/【css】長い文章の文末を省略して末尾に「」を

 

コードはこちら。

<p>春はあけぼの。やうやう白くなりゆく山際、少し明かりて、紫だちたる雲の細くたなびきたる。</p>
#text{
    width: 300px;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}

overflow: hidden; を使うところは、前回と同じです。
-webkit-line-clamp を使うことで、指定した行に三点リーダー(クランプ)を追加することができます。
こちらのプロパティの値は、三点リーダを追加したい行数を指定します。
display: -webkit-box; は、-webkit-line-clamp と併用することにより、-webkit-line-clamp で指定した行数までを表示するようにしてくれます。

 

以上、複数行の行末尾を省略する方法でした。
上で紹介したサイトでは、ChromeSafari 以外のブラウザでも同じことを行う方法もありますので、IEでもこの表示にしたいときは参考にしてみてはいかがでしょうか。
ちなみに、少しトリッキーな方法とのことです。

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

【jQuery】FastClickライブラリを特定の要素のみ無効にする方法【iOS】

Cordova開発をしているとお世話になるライブラリが、この「FastClick」だと思います。
これを使うことで、モバイルでアプリを実行したときのクリックの反応速度がかなり改善されます。
が、ものによっては、この FastClick ライブラリと競合を起こすライブラリもあるようで、今日、まさにその現象に遭遇しました。

 

競合を起こしたライブラリは、OpenstreetMap を使用した地図を表示できる「MapBox」です。
地図の表示の全てに影響するわけではなく、地図に表示したマップピンをクリックして、吹き出しを表示するロジックに影響が出ており、iOS でのみ吹き出しが表示できない状態でした。
クリックの動作をする箇所でのエラーだったので、最初は Click イベントを取得できていないことを疑いましたが、エラーログを見たところ、FastClick との競合が原因でした。

 

解決方法ですが、こちらのサイトを参考にしました。

JS/jQueryでFastClick.jsを使ってスマホのclickイベントの300ms遅延をなくす|ITハット
http://ithat.me/2016/11/06/js-jquery-smartphone-click-event-300ms-delay-fastclick

サンプルに書くほどでもないのですが…対策方法は、FastClick を無効化したい aタグなどの要素に、needsclick というクラスを追加するだけです。

<a class="needsclick">FastClickを無効にしたい要素</a>

特定の要素のみに FastClick を適用する方法もありますが、現在開発中のシステムでは、無効化したい要素がここのみだったので、この方法を採用しました。
ちなみに、特定の要素のみに適用する方法は下記の通りです。

<div>
    <div class="fastclick">
        <!-- FastClickを適用する要素 -->
    </div>
    <div>
        <!-- FastClickを適用しない要素 -->
    </div>
</div>
$(function(){
    FastClick.attach($('.fastclick')[0]);
});

全てに FastClick を適用するときには、下記のように記述します。

$(function(){
    FastClick.attach(document.body);
});

対策としては以上です。

 

ということで、FastClick を一部無効化する方法でした。
ライブラリの競合はやはり厄介ですね。
最悪、FastClick を無効化しなければいけないのでは…と思ったので、解決策があって良かったです。

  • この記事いいね! (0)
著者:杉浦

documentFragmentをIEで使う方法

 DocumentFragmentは小型のdocumentの様なものを定義する関数です。DocumentFragmentで定義されたDOMは画面に反映されません。
DocumentFragment – Web API インターフェイス | MDN
 下の画像の表はDocumentFragmentの対応表です。

 見ての通りInternet Explorerは2018/05/22時点でBasic support、querySelector、querySelectorAllにのみしか対応していません。他にも内部にDocumentFragmentを作成するコンテンツテンプレート要素であるタグにも対応していません。このためgetElementIDのようなdocumentに対してよく使用する関数すらDocumentFragmentにかけようとするとエラーないし予期せぬ動作を招くことがあります。基本サポートの範囲がよくわからなかったので、実装していないのではないかと疑い同等の機能を他の記述で試すぐらいしか解決法がわかりませんでした(W3Cの仕様書なり技術書なりにあるはず)。querySelector、querySelectorAllには対応しているので要素探索は楽なので、対象の要素に対してappendChild等の基本的であろうコードを書くのがコーディングの方針になると思います。
 InternetExplorerはFirefox、chromeなどの他ブラウザよりも律義にレンダリングを頻繁にしてくれます。そのためDOMの追加が大量にあるような場合は一度DocumentFragmentなどの画面に影響しない部分でDOMをまとめて構成、一括してdocumentにつなげる方がとても良いです。以下はtable_masterというIDのついた親を持ち、hoge_tableというIDのついたtable内のtbody_topというIDのついたtbodyを、tbody内のHTMLコードを表す文字列hoge_strで置き換える例です。


var df = document.createDocumentFragment();
df.appendChild(document.getElementById("hoge_table"));
df.querySelector("#tbody_top").innerHTML = "";
var tbd = document.createElement("tbody")
hoge_str = "abc";
tbd.innerHTML = hoge_str;
while(tbd.firstChild){
	df.querySelector("#tbody_top").appendChild(tbd.firstChild);
}
document.getElementById("table_master").appendChild(df.firstChild);
  • この記事いいね! (0)
村上 著者:村上

【JavaScript】使用しているモバイル端末の種類を判定する方法

今回は、どの端末を使用しているかを判定する方法について。
ちなみに、AndroidiOS の判定しかしていません。

参考にさせていただいたサイトはこちらから。

使用してるブラウザを判定したい – Qiita
https://qiita.com/sakuraya/items/33f93e19438d0694a91d

コードはこちら。

var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("android") != -1){
    // Android の時の処理
}
if ((userAgent.indexOf("iphone") != -1)||(agent.indexOf("ipad") != -1)){
    // iOS(iPhone、iPad)の時の処理
}

navigator.userAgent でユーザーエージェントを取得します。
そして、取得できた結果は .toLowerCase() メソッドを使って全て小文字に変換します。
で、.indexOf() メソッドで、指定された値が最初に現れたインデックスを取得します。
なお .indexOf() メソッドは、指定した値がなかった場合、-1 を返します。

あとは、Android、iOSごとに行いたい処理を ifで分岐した先に記述すればOKです。
思っていたよりも簡単ですね!

 

以上、使用しているデバイス端末の種類を判定する方法でした。
ちなみに、私はこちらをアプリのアップデートを促す際の処理で使っています。
もし、インストールされているアプリが最新のバージョンよりも古かったら、端末を判定し、Google Play もしくは App Store のそれぞれのページに遷移させています。
使っているのはその箇所のみですね。
端末ごとに分けなければいけない処理は意外と少なく、この程度で済むようです。

なお、参考にさせていただいた記事では、ブラウザの判定も紹介されています。
今のところ、ブラウザで分け無ければいけない処理はありませんが、機会があったらこちらも参考にさせていただきたいと思います。

  • この記事いいね! (0)
著者:杉浦

コード中のif節を減らす

これの記事はシンプルなif節を減らすことについての記事です。
例えば、次のようなプログラムがあるとします。条件ABCの真偽に応じて01を返すプログラムです。

if A
    if B
        if C
            return 1;
        else
            return 0;
        end
    else
        if C
            return 0;
        else
            return 1;
        end
    end
else
    if B
        if C
            return 1;
        else
            return 0;
        end
    else
        if C
            return 1;
        else
            return 0;
        end
    end
end

このプログラムは一見読みにくく、また余分な動作があります。if節を減らすことで速度と可読性の向上が見込めます。単純な真偽を表に表します。ABCが条件、Rが返り値です。1は値の1の他に真の意味も持ちます。0は値の0の他に偽の意味も持ちます。

A B C R
0 0 0 0
0 0 1 1
0 1 0 1
0 1 1 0
1 0 0 1
1 0 1 0
1 1 0 1
1 1 1 0

例えば~AB~C=1、AB~C=1です。~は否定の意味です。ここからB~C=1と短縮でき、以下の様にプログラムを変えることができます。

if B
    if C
        if A
            return 0;
        else
            return 0;
        end
    else
        return 1;
    end
else
    if C
        if A
            return 1;
        else
            return 0;
        end
    else
        if A
            return 1;
        else
            return 0;
        end
    end
end

判定が減った分、文量も処理量も減りました。
そんなこんなで真偽を最適化した場合、次のような式ができます。
1 = ~A~BC + B~C + A~C
この式に従った場合、以下の様にプログラムを変えることができます。

if C
    if ~A
        if ~B
            return 1;
        end
    end
else
    if A
        return 1;
    end
    if B
        return 1;
    end
end
return 0;

最初の書き方が愚直すぎるのもありますが随分と簡略化できました。
真理値の短縮には多くのアプリ、ライブラリもあるのでコードを簡略化したい際にはググって使うのが良いと思います。

  • この記事いいね! (1)
著者:杉浦

ハッシュ探索

 人間が本棚から特定本を探す時、どのような行動をとるでしょうか。
 慣れ親しんだ自宅の本棚ならここに入れてある、と一瞬で目当ての本の場所がわかると思います。図書館の様な場所なら辞書内を探す様にタイトルを追って大体の場所を行ったり来たりして探していくと思います。前者と後者の違いは題名と保管場所に密接な関係があるかないかの違いです。前者ならば題名を思い出した時に保管場所も共に思い出しているでしょう。後者ならば題名からこのあたりにあるだろうと推測を付けているでしょう。データ名がコンピュータがデータを保存している場所を示した場合、コンピュータも自宅の本棚から本を見つける様に一瞬で目当てのデータを探せるでしょう。ハッシュ探索は大体そのような方法です。
 コンピュータのデータ格納場所は番地、値で表せます。データ名もまた、値で表せます。データの格納番地をデータ名とした場合、データ名の場所にアクセスしにいけばそれで一発でデータを読み出せます。大体このような考えがハッシュ探索です。実際には、格納場所はもっと狭く、格納番地を読み出すためのコストもバカにならないので、データそのままでなく何らかの別のものをキー(格納番地)として扱います。それでも多くの場合で他のデータ構造より高速に特定のデータを読み出せます。
 多くの言語にはマップというデータ構造が備えられておりハッシュ探索に対応しています。先ほどのデータ名や格納番地足るキーと共にデータ値を登録していくデータ構造です。
追記:人間の頭が一瞬で目当てのデータを見つけられる主な仕組みはハッシュ探索の仕組みというより、頻繁に使われるデータや最近使用されたデータを上位(記憶の上層)に保管している仕組みです。

  • この記事いいね! (0)
著者:杉浦

javascriptのDOM操作の高速化に使える機能:DocumentFragment

 これはいくらかjavascriptを知っている人向けの記事で、javascriptの機能の一つDocumentFragmentの紹介です。
 DocumentFragmentはDOMツリーとほぼ同じ機能を持つ独立したノード、小型のdocumentの様なものを定義するインターフェースです。ルートであるdocumentのDOMツリーを操作した場合、レンダリングがしょっちゅう働きますが、DocumentFragmentに従って作成されたDOMツリー同然のノードを操作した場合はレンダリングが全く働きません。このためDocumentFragmentを用いてDOMツリーに連結する予定の木を作成、作成された木を連結、とすることで比較的高速にDOMツリーを操作できます。。
 DOMツリーとはHTMLドキュメントなどを木構造オブジェクトとして扱う際の木のことです。DOMツリー中のノードが削除、変更されたり、新たにノードが追加された場合、レンダリングが行われる場合があります。DOMの操作は重い動作である、という意見、記事がいくつも見られる理由の一つはおそらくこれでしょう。もっとも最近はブラウザも賢くなりレンダリング回数を少なくしようとしていますが、警戒するに越したことはないです。IEにおいてfor文中でappendChildを回す部分のあったプログラムを走らせたら、レンダリングの実行回数がえらいことになっていました。
 DocumentFragment – Web API インターフェイス | MDN
 使い方
var df = document.createDocumentFragment();
 このdfを好き勝手いじれます。dfをどこぞに連結する場合、DocumentFragmentの頂点ノードは削除され、一つの木として自然な形になります。
 レンダリングなどのブラウザの内部について述べられた記事:ブラウザのしくみ: 最新ウェブブラウザの内部構造 – HTML5 Rocks

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

【JavaScript】jQueryなしでappend()と同じことを実行する

DOM操作をするときに jQuery の append() を使うことが多いのですが、場合によっては jQuery が使用できないことがあるかと思います。
なので、今回はタイトル通り、jQueryなしで append() と同じことを行う方法についてです。

参考にさせていただいた記事はこちら。

innerHTML より insertAdjacentHTML を使う – Qiita
https://qiita.com/amamamaou/items/624c22adec32515e863b

 

実際のコードはこちら。
今回使うメソッドは、insertAdjacentHTML() というものです。

<div id="parent">
    <p>p要素 その1</p>
</div>
// id=parendの子要素の最下部に要素を追加 append()
var element = document.getElementById("parent");
element.insertAdjacentHTML("beforeend", "<p>p要素 その2</p>");

上記のコードを実行すると、ID が parent の要素の子要素の一番下に、指定したp要素が追加されます。
動作としては、jQuery の append() と全く一緒です。
ちなみに、insertAdjacentHTML() メソッドの第一引数を変更することで、append() 以外の動作を行わせることができます。

簡単に表でまとめてみました。

jQuery insertAdjacentHTML()
append() “beforeend”
prepend() “afterbegin”
before() “beforebegin”
after() “afterend”

jQuery で行えるDOM要素の挿入は、こちらの方法でも問題なくできるようです。

なお、もしHTML文字列ではなく、HTML要素を指定したい場合には、insertAdjacentElement() が利用できます。
第一引数は、insertAdjacentHTML() と全く同じで、追加したい要素を指定する第二引数のみが違います。
こちらは、実装しているコードで使い分けてください。

 

ということで、jQueryなしで append() などと同じことを実行する方法でした。
システムによっては、jQueryを使えないこともあるかと思うので、この方法は覚えておきたいと思います。

  • この記事いいね! (0)
著者:杉浦

HTMLの勧告とCSSの仕様

 HTML、CSSを始めとする様々なWWW(World Wide Web)上で用いられる技術の標準化を進める団体としてW3C(World Wide Web Consortium)という団体があります。W3Cの活動にはWHATWF(Web Hypertext Application Technology Working Group)が開発しているHTMLの仕様の勧告とW3C自身が開発しているCSSの仕様書の公開も含まれています。
以下はW3Cの公開している資料へのショートカットです。

HTML & CSS – W3C:HTMLとCSSについての基点になるページ
All Standards and Drafts – W3C:文字通り、全ての標準と草稿。仕様や技術文書が色々

 和訳がない文書が多数、文章量が多量、といったため読むのは結構な苦労ですが、情報はとても多く、ブラウザ依存の問題以外は網羅されているはずです。詳しく調べたい時にあたる資料として使えます。

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

【JavaScript】長い文章の文末を省略して末尾に「…」を表示させる方法

昨日の記事とほぼ同じタイトルですが、今回はCSSではなくJavaScriptで文章の文末を省略して末尾に三点リーダーを追加する方法です。
こちらは範囲からはみ出たかどうかではなく、文字数で判断をしています。

ちなみに、昨日の記事はこちらから。

【CSS】長い文章の文末を省略して末尾に「…」を表示させる方法
https://cpoint-lab.co.jp/article/201805/【css】長い文章の文末を省略して末尾に「」を/

こちらの記事では、CSSで指定した範囲からはみ出した文章の文末を省略しています。
複数行の表示には対応しておらず、省略後は1行の表示になります。

 

コードはこちら。

<p id="text"></p>
var text = "春はあけぼの。やうやう白くなりゆく山際、少し明かりて、紫だちたる雲の細くたなびきたる。";
var slicetext = text.length > 20 ? (text).slice(0,20)+"…" : text;
document.getElementById('text').innerHTML = slicetext;

文字数をカウントし、20文字以上だったら、slice メソッドを使って21文字目からをカットして、三点リーダーを追加しています。
そして、pタグの中に、そのカット後の文章を表示しています。
行っている処理はこれだけです!

 

JavaScriptで文末を省略する方法でした。
好みにもよりますが、明確に○文字以下で表示することが決まっている場合や、表示する範囲が不変で、かつ複数行で表示したいときなどに使えそうです。
1行だけ表示するなら、表示範囲も可変が可能なCSSで指定する方がよさそう。
このあたりは実装する内容によって使い分けてください。

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