ラベル JavaScript の投稿を表示しています。 すべての投稿を表示
ラベル JavaScript の投稿を表示しています。 すべての投稿を表示

2016-05-11

iOSのSafariとUIWebViewでspeechSynthesis.getVoices()が空っぽ

JavaScriptで、speechSynthesis.getVoices() とやれば、テキストを音声読み上げするときに設定するvoiceのリストが返ってくるはずなんだけど、iOSだと空っぽのemptyリストが返ってきてしまう。実際には、音声読み上げ可能なはずなのに、空っぽ。iOSのバージョン9.2でしかチェックしていない。

さあ困った。どうする?

予想としては、Objective-Cのコードで  [AVSpeechSynthesisVoice speechVoices]; とやったときに取得できるvoiceは利用可能なのでないかと思う。

実際に試してみる。やっぱりそうみたい。利用可能なのはこんな感じ。(ここから転載

LocaleLanguage/Country
ar-SAArabic (Saudi Arabia)
en-ZAEnglish (South Africa)
th-THThai (Thailand)
nl-BEDutch (Belgium)
en-AUEnglish (Australia)
de-DEGerman (Germany)
en-USEnglish (United States)
pt-BRPortuguese (Brazil)
pl-PLPolish (Poland)
en-IEEnglish (Ireland)
el-GRGreek (Greece)
id-IDIndonesian (Indonesia)
sv-SESwedish (Sweden)
tr-TRTurkish (Turkey)
pt-PTPortuguese (Portugal)
ja-JPJapanese (Japan)
ko-KRKorean (Korea)
hu-HUHungarian (Hungary)
cs-CZCzech (Czech Republic)
da-DKDanish (Denmark)
es-MXSpanish (Mexico)
fr-CAFrench (Canada)
nl-NLDutch (Netherlands)
fi-FIFinnish (Finland)
es-ESSpanish (Spain)
it-ITItalian (Italy)
ro-RORomanian (Romania)
no-NONorwegian(Norway)
zh-HKChinese (Hong Kong)
zh-TWChinese (Taiwan)
sk-SKSlovak (Slovakia)
zh-CNChinese (China)
ru-RURussian (Russia)
en-GBEnglish (United Kingdom)
fr-FRFrench (France)
hi-INHindi (India)

var msg = new SpeechSynthesisUtterance("てきすと");
msg.lang = "ja-JP";
speechSynthesis.speak(msg);

のように地域コードつきでlangを指定する。言語コードだけ指定して、msg.lang = "ja"; とやるのではダメみたい。

2016-05-04

HTML5のバリデーションチェックを使うのやめた

翻訳コンニャクで、HTML5のバリデーション(checkValidityなど)を利用してみたのだが、ブラウザごとの挙動にばらつきがありすぎて使いにくい。これから書き直して、サーバーサイドのチェックだけにする予定。

特に、Safariの挙動が制御しにくい。checkValidityは動くし、validationMessageも設定されているのだが、それにもかかわらずポップアップでエラー表示が行われない。Safariのためにゴチャゴチャ処理を書くとわけわからないことになりそう。

Safariは、executeCommandも動かないし、最近のIEよりも扱いにくい。

2013-08-23

TinyMCEエディタにマークアップした初期値を表示

TinyMCE4で、HTMLをエディタの初期値に表示する方法。下書き保存とかした内容を再編集するさいに必要になる。
こんな感じにやればいいっぽい。

<script type="text/javascript">
        tinymce.init({
            selector: "textarea",
         });
        tinymce.on("AddEditor", function(e) {
            tinyMCE.activeEditor.on("init", function(event) {
                tinyMCE.activeEditor.setContent("<h1>見出し</h1>テキスト");
            });
        });
    </script>

djangoで使おうと思って、プラグインを導入した方がいいのか迷ったんだけど、管理者サイトで使うのでなければテンプレートでJavaScriptを編集するの良さそう。

2012-03-14

CoffeeScriptで書いた後で思ったこと

CoffeeScriptの構文が美しいことに感動して、小さなプログラムを書いてみました。遊びでこっそり書くプログラムではなく、公開するつもりのプログラムです。
それで気づいたのは、JavaScriptで書いてもほとんど同じだということです(jQueryを使ったからかもしれません)。

ひとつだけ大きく違ったのは、何の迷いもなく、クラスをきれいに書けるということです。
しかし、JavaScriptでも、継承のやり方さえ決めてしまえば、それなりに可読性の高いコードを書けるような気もします。
デバッグのことを考えると、やはりCoffeeScriptよりも、JavaScriptのほうが有利です。

JavaScriptで継承をどんな風に書くか考えてみます。CoffeeScriptのプログラムをJavaScriptで書きなおしてみるかもしれません。

次のように create関数を定義して、これでオブジェクトの生成や継承をやることすれば、JavaScriptでもコードがすっきりするように思います。継承をするときは、createで生成して、extendで差分を定義します。newを隠蔽しているあたりは、クラス型の継承ではなく、プロトタイプ型の継承と言ってよいかと思います。
var create = function(proto) {
    var Meta = function() {};
    if (undefined !== proto && null !== proto) {
        Meta.prototype = proto;
    }
    var obj = new Meta();
    obj.__meta__ = Meta;
    obj.extend = function(obj) {
        for (var m in obj) {
            this[m] = obj[m];
        }
        return this;
    };
    return obj;
};

使い方は以下のような具合です。
var base = create({
    name: function() {return "this is base";}
});
var derived = create(base).extend({
    name: function() {return "this is derived";}
});
クラスを使わずにオブジェクトから直接オブジェクトを生成するイメージですが、var d1 = creat(derived); var d2 = create(derived); というようにできるので、とくに困ることはなさそうです。

『一挙に英語翻訳』のWeb版で苦戦

『一挙に英語翻訳』のWeb版をつくろうとしているのですが、ブラウザごとの挙動が違っていて、とくにIE対策が困難そうです。

IE6は、そもそもサポート外と考えていますが、 IE7でもページが真っ白になって表示できません。
IE8やIE9でも、「→」がきちんと表示されない(横棒が欠けてしまう)という問題があります。もっとも「⇒」ならばちゃんと表示されるようなので、これは大した問題ではありません。

問題は、IEでは、window.open() で複数のタブを開こうとするとポップアップ・ブロックに引っかかってしまうことです。タブ一つだけなら開けるのですが、複数はダメみたいです。
ポップアップがブロックされた場合はメッセージが一応表示されるのですが、これが表示されるタブから別のタブに遷移してしまっているため、ユーザーが気づかない可能性が高いです。
さらに、ポップアップ・ブロックのメッセージは、ページが更新されると消えてしまいます。しばらく時間が経過しただけでも消えてしまうようです。

ページが更新されるとポップアップがブロックされたことを通知するメッセージが消えてしまうことには、Ajaxを使えば対応できそうです。
しかし、ブロックされずに複数のタブを開くにはどうしたらいいかはよく分かりません。window.open() に失敗した場合は、戻り値がnullだかundefinedだかになるようなので、そこでブロックの有無を判定して、ユーザーにメッセージを表示するというのが良いのかもしれません。
window.open() を使わずに、$("form").submit() とする方法も試してみましたが、こちらもやはり開けるタブはひとつだけで、残りはブロックされてしまいます。

2012-03-12

JavaScriptでtextareaに入力中の文字数をカウントする

textareaなどに入力された文字数を表示する場合は、次のようにchangeイベントとkeyupイベントpasteイベントをハンドリングします。changeイベントだけだと、入力欄からフォーカスが外れて編集モードが終了するまで文字数が更新されなくなってしまうので、keyupイベントもハンドリングすることが必要です。また、テキストエリアに文章が貼り付けられた場合に備えて、pasteイベントもハンドリングします。
$("input[type='txtarea']").bind("keyup change paste", function() {
    var txt = $(this).val();
    var len = txt.length;
    console.debug("the text length is " + len)
});


2012-02-27

Ubuntuでnode.jsを試してみる、あとCloud9でも

Ubuntu 11.10にnode.jsをインストールしてみました。apt-getでいけます。パッケージマネージャのnpmもapt-getでいけます。
$ sudo apt-get install nodejs-dev
$ sudo apt-get install npm
サンプルコードとして、次のようなコードを書いて、hellonode.jsという名前で保存します。
var sys = require("sys");
var http = require("http");

var server = http.createServer(
  function(req, res)
  {
    res.writeHead(200, {"Content-Type": "text/plain"});
    res.write("Hello World!");
    res.end();
  }
);
server.listen(8080);
sys.log("Server is running at http:127.0.0.1:8080");
で、terminalで、
$ node hellonode.js
と入力したらとちゃんと動いているのをブラウザで確認できました。まあ、ちょっと遊んでみただけです。

調子に乗ってexpressもインストールしてみたけど、node.jsで遊ぶんならCloud9が手軽でいいかもしれません。ブラウザ上で動くIDEですが、意外と快適です。
ただ、正しくコマンドを打ったはずなのに原因不明のエラーになったり、あるはずのモジュールが見つからなかったりしました。しばらく待ってページを開き直して、また同じことを試してみたら上手くいきましたが。 

なお、Macでも、portを使ってnode.jsとnpmをインストールできるみたいです。

2012-02-24

JavaScriptでページのトップに滑らかにスクロールさせる

JavaScriptでページのトップにまでアニメーション付きで滑らかにスクロースするコードを書いてみました。特徴は、jQueryなどのライブラリを必要とせず、ほんの数行のプログラムだという点です。ちゃんとテストしていないから、動かないブラウザもあるかもしれません。
(function()  {
    var getScrollTop = function() {
        return document.body.scrollTop || document.documentElement.scrollTop;
    };
    var getScrollLeft = function() {
        return document.body.scrollLeft || document.documentElement.scrollLeft;
    };
    var startTime = new Date() - 0;
    var scrollInterval = setInterval(function() {
        var currTime = new Date() - startTime;
        if (currTime > 500) {
            clearInterval(scrollInterval);
            scrollTo(0, 0); 
        }
        else {
            var x = getScrollLeft() * 3 / 4;
            var y = getScrollTop() * 3 / 4;
            scrollTo(x, y);
        }
    }, 30);
})();
なんでこんなコードを書いたかというと、AndroidのWebViewに滑らかにスクロールさせるメソッドが見つからなかったからです。scrollTo(int x, int y)だと一瞬でページのトップに来てしまいます。しかし、上のコードをJavaにそのまま移植すると、スレッドの関係で問題が生じる可能性がある気がします。そこらへんはまだ検証していません。