文字数カウント

  • /*
     * @title 文字数カウント
     * @description 選択範囲、またはアクティブなテキストボックス・テキストエリアの文字数を表示する小窓を作成する。小窓はドラッグ可能。練習を兼ねて作った過去作なのでコードはぐちゃぐちゃです。
     * @include http://*
     * @license NYSL
     */
    
    
    if (document.getElementById("strLenChkDiv")==null) var strLenChkWnd = "", strLenChkWndStyle = "";
    (function (w, d) { // w=window, d=document
    
    var str = "";
    var TIMER = d.all ? 200 : 100; // IE系のみ更新間隔を延ばす
    var divPadding = "8px";
    
    // イベントリスナ追加
    var addEvent = function(target, evt, func) {
      if (w.addEventListener) {
        return target.addEventListener(evt, func, false);
      }
      else if (w.attachEvent) {
        if (target===w) target = d;
        return target.attachEvent("on"+evt, func);
      }
      else return false;
    };
    
    try {
      d.body.removeChild(d.getElementById("strLenChkDiv"));
      return false;
    }
    catch (e) {}
    
    // http://misttrap.s101.xrea.com/sample/bytelength_for_mbstring.htm
    String.prototype.getByteLenUTF8 = function() {
      for(var i = this.length, num, res = i * 2; i-- > 0;) {
        if((num = this.charCodeAt(i)) > 0x7ff && (num < 0xd800 || num > 0xdfff)) {
          res++;
        } else if(num < 0x80) {
          res--;
        }
      }
      return res;
    };
    
    (function () {
      var mouse = {};
      mouse.X = 0;
      mouse.Y = 0;
      var draggable = false;
      
      strLenChkWnd = d.createElement("div");
      strLenChkWnd.id = "strLenChkDiv";
      strLenChkWnd.setAttribute("style"
      ,  "position: fixed !important;"
      +  "z-index: 999999 !important;"
      +  "left: 8px;"
      +  "top: 8px;"
      +  "width: 200px !important;"
      +  "height: 100px !important;"
      +  "border: 6px double silver !important;"
      +  "border-radius: 6px !important;"
      +  "background-color: white !important;"
      +  "margin: 0 !important;"
      +  "padding: 6px !important;"
      +  "color: black !important;"
      +  "font-size: 16px !important;"
      +  "font-family: 'メイリオ', 'ヒラギノ角ゴ Pro W3', 'MS Pゴシック', sans-serif !important;"
      +  "font-style: normal !important;"
      +  "font-weight: normal !important;"
      +  "text-align: left !important;"
      +  "line-height: 24px !important;"
      +  "cursor: move;"
      +  "user-select: none;"
      +  "float: none !important;"
      +  "display: block !important;");
      strLenChkWnd.onmousedown = function() { return false };
      addEvent(strLenChkWnd, "mousedown", function(evt) {
        evt = evt || window.event;
        draggable = true;
        mouse.X = evt.clientX;
        mouse.Y = evt.clientY;
        return false;
      });
      addEvent(window, "mouseup", function() {
        draggable = false;
        return false;
      });
      addEvent(strLenChkWnd, "mousemove", function(evt) {
        var left, top;
        evt = evt || window.event;
        var s = (w.addEventListener ? this : strLenChkWnd).style; // IEだとthisがwindowを指すので
        if (draggable) {
          left = parseInt(s.left, 10);
          top  = parseInt(s.top , 10);
          s.left = left + evt.clientX - mouse.X + "px";
          s.top  = top  + evt.clientY - mouse.Y + "px";
        }
        mouse.X = evt.clientX;
        mouse.Y = evt.clientY;
        return false;
      });
      d.body.appendChild(strLenChkWnd);
    })();
    
    var getStr = function () {
      var ret = "";
      var selectStr
        = w.getSelection  ? w.getSelection().toString()
        : d.getSelection  ? d.getSelection()
        : d.selection    ? d.selection.createRange().text
        : "";
      
      
      if (!selectStr) {
        var a = d.activeElement;
        try {
          if (a.selectionEnd - a.selectionStart)
            return a.selectionEnd - a.selectionStart;
        }
        catch (e) {
          if (a.tagName=="textarea" || a.tagName=="input")
            return a.value || a.innerHTML || "";
          else selectStr = "";
        }
      }
      
      if (selectStr) ret = selectStr;
      else {
        var obj = d.activeElement;
        if (obj) {
          if (obj.tagName.toLowerCase() == "textarea") {
            ret = obj.value;
            if (!ret) ret = obj.innerHTML;
          }
          if (obj.tagName.toLowerCase() == "input"
          && ( !obj.type || obj.type.toLowerCase() == "text")) ret = obj.value;
        }
      }
      return ret;
    };
    
    //
    // ここがメイン
    //******************************************************
    function loop() {
      str = getStr(window);
      if (d.getElementById("strLenChkDiv")==null) {
        clearInterval(iv);
        return false;
      }
      writeText(str);
    }
    function writeText(str) {
      var obj = strLenChkWnd;
      
      if (str && typeof(str) != "number") {
        var c = str.split("\n").length-1;
        obj.innerHTML = "<p>文字列長 : "+str.length+" 文字</p><p>改行数 : "+c+" 個</p>";
      }
      else if (typeof(str) == "number")
        obj.innerHTML = "<p>文字列長 : "+str+" 文字</p>";
      else
        obj.innerHTML = "<p>文字列長 : "+str.length+" 文字</p>";
      if (getCharset().toUpperCase() == "UTF-8") {
        var bytes = str.getByteLenUTF8();
        obj.innerHTML += "<p>バイト数 : "+bytes+" bytes</p>";
      }
      
      var cn = obj.childNodes;
      for (var i=0; i<cn.length; i++) {
        if (cn[i].nodeType == 1) {
          cn[i].setAttribute("style",
            "margin: 0 !important;"
          +  "padding: 4px 0 !important;"
          +  "color: black !important;"
          +  "font-size: 16px !important;"
          +  "font-family: 'メイリオ', 'ヒラギノ角ゴ Pro W3', 'MS Pゴシック', sans-serif !important;"
          +  "font-style: normal !important;"
          +  "font-weight: normal !important;"
          +  "text-align: left !important;"
          +  "line-height: 24px !important;"
          +  "z-index: inherit !important;");
        }
      }
    }
    
    function getCharset() {
      if (d.characterSet)
        return d.characterSet;
      else if (d.charset)
        return d.charset;
    }
    
    if (strLenChkWnd) {
      var iv;
      loop();
      iv = setInterval(loop, TIMER);
    }
    
    })(window, document);
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2013/04/23 02:26:37 - 2013-04-23
  2. 2013/04/23 02:24:30 - 2013-04-23