Обнаружение отдельного характера Unicode поддерживает с JavaScript

Метод, который я больше не беспокоился о культурах и проблемах с форматированием, заключается в том, что я отформатировал его как валюту и затем вынул символ валюты.

if (decimal.TryParse(tblCell, out result))

{
  formattedValue = result.ToString("C").Substring(1);
}
24
задан 2 revs 17 December 2009 в 00:27
поделиться

3 ответа

Не уверен, что на него можно положиться в будущем (браузеры могут изменить то, что показано для неподдерживаемых символов), и я не уверен, что это оптимизировано (поскольку у меня нет хорошего понимания идеальных границ для измерения здесь) ), но следующий подход (рисование текста на холсте и проверка результата в виде изображения) может, в случае проверки, обеспечить более надежную и точную проверку, чем проверка ширины. Весь код в начале - это просто обнаружение в браузере, которое мы должны использовать, так как обнаружение функций невозможно.

(function () {

// http://www.quirksmode.org/js/detect.html
var BrowserDetect = {
    init: function () {
        this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
        this.version = this.searchVersion(navigator.userAgent)
            || this.searchVersion(navigator.appVersion)
            || "an unknown version";
        this.OS = this.searchString(this.dataOS) || "an unknown OS";
    },
    searchString: function (data) {
        for (var i=0;i<data.length;i++) {
            var dataString = data[i].string;
            var dataProp = data[i].prop;
            this.versionSearchString = data[i].versionSearch || data[i].identity;
            if (dataString) {
                if (dataString.indexOf(data[i].subString) != -1)
                    return data[i].identity;
            }
            else if (dataProp)
                return data[i].identity;
        }
    },
    searchVersion: function (dataString) {
        var index = dataString.indexOf(this.versionSearchString);
        if (index == -1) return;
        return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
    },
    dataBrowser: [
        {
            string: navigator.userAgent,
            subString: "Chrome",
            identity: "Chrome"
        },
        {   string: navigator.userAgent,
            subString: "OmniWeb",
            versionSearch: "OmniWeb/",
            identity: "OmniWeb"
        },
        {
            string: navigator.vendor,
            subString: "Apple",
            identity: "Safari",
            versionSearch: "Version"
        },
        {
            prop: window.opera,
            identity: "Opera",
            versionSearch: "Version"
        },
        {
            string: navigator.vendor,
            subString: "iCab",
            identity: "iCab"
        },
        {
            string: navigator.vendor,
            subString: "KDE",
            identity: "Konqueror"
        },
        {
            string: navigator.userAgent,
            subString: "Firefox",
            identity: "Firefox"
        },
        {
            string: navigator.vendor,
            subString: "Camino",
            identity: "Camino"
        },
        {       // for newer Netscapes (6+)
            string: navigator.userAgent,
            subString: "Netscape",
            identity: "Netscape"
        },
        {
            string: navigator.userAgent,
            subString: "MSIE",
            identity: "Explorer",
            versionSearch: "MSIE"
        },
        {
            string: navigator.userAgent,
            subString: "Gecko",
            identity: "Mozilla",
            versionSearch: "rv"
        },
        {       // for older Netscapes (4-)
            string: navigator.userAgent,
            subString: "Mozilla",
            identity: "Netscape",
            versionSearch: "Mozilla"
        }
    ],
    dataOS : [
        {
            string: navigator.platform,
            subString: "Win",
            identity: "Windows"
        },
        {
            string: navigator.platform,
            subString: "Mac",
            identity: "Mac"
        },
        {
               string: navigator.userAgent,
               subString: "iPhone",
               identity: "iPhone/iPod"
        },
        {
            string: navigator.platform,
            subString: "Linux",
            identity: "Linux"
        }
    ]

};
BrowserDetect.init();


/**
* Checks whether a given character is supported in the specified font. If the
*   font argument is not provided, it will default to sans-serif, the default
*   of the canvas element
* @param {String} chr Character to check for support
* @param {String} [font] Font Defaults to sans-serif
* @returns {Boolean} Whether or not the character is visually distinct from characters that are not supported
*/
function characterInFont (chr, font) {
    var data,
        size = 10, // We use 10 to confine results (could do further?) and minimum required for 10px
        x = 0, 
        y = size,
        canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');
    // Necessary?
    canvas.width = size;
    canvas.height = size;

    if (font) { // Default of canvas is 10px sans-serif
        font = size + 'px ' + font; // Fix size so we can test consistently
        /**
        // Is there use to confining by this height?
        var d = document.createElement("span");
        d.font = font;
        d.textContent = chr;
        document.body.appendChild(d);
        var emHeight = d.offsetHeight;
        document.body.removeChild(d);
        alert(emHeight); // 19 after page load on Firefox and Chrome regardless of canvas height
        //*/
    }

    ctx.fillText(chr, x, y);
    data = ctx.getImageData(0, 0, ctx.measureText(chr).width, canvas.height).data; // canvas.width
    data = Array.prototype.slice.apply(data);

    function compareDataToBox (data, box, filter) {
        if (filter) { // We can stop making this conditional if we confirm the exact arrays will continue to work, or otherwise remove and rely on safer full arrays
            data = data.filter(function (item) {
                return item != 0;
            });
        }
        return data.toString() !== box;
    }

    var missingCharBox;
    switch (BrowserDetect.browser) {
        case 'Firefox': // Draws nothing
            missingCharBox = '';
            break;
        case 'Opera':
            //missingCharBox = '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,197,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,73,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,197,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,73,0,0,0,0';
            missingCharBox = '197,255,255,255,255,73,36,36,36,36,36,36,36,36,197,255,255,255,255,73';
            break;
        case 'Chrome':
            missingCharBox = '2,151,255,255,255,255,67,2,26,2,26,2,26,2,26,2,26,2,26,2,26,2,26,2,151,255,255,255,255,67';
            break;
        case 'Safari':
            missingCharBox = '17,23,23,23,23,5,52,21,21,21,21,41,39,39,39,39,39,39,39,39,63,40,40,40,40,43';
            break;
        default:
            throw 'characterInFont() not tested successfully for this browser';
    }
    return compareDataToBox(data, missingCharBox, true);
}

// EXPORTS
((typeof exports !== 'undefined') ? exports : this).characterInFont = characterInFont;

}());

var r1 = characterInFont('a', 'Arial'); // true
var r2 = characterInFont('\uFAAA', 'Arial'); // false
alert(r1);
alert(r2);

ОБНОВЛЕНИЕ 1

Я попытался обновить для современного Firefox (чтобы проверить ожидаемые шестнадцатеричные цифры на холсте), и проверить, чтобы, в отличие от моего В приведенном выше коде холст (и шаблон, соответствующий ему) был достаточно большим, чтобы вместить самый широкий символ для context.measureText() (U + 0BCC из моего тестирования, хотя предположительно зависел от шрифта, в моем случае «Arial Unicode MS»). В https://bugzilla.mozilla.org/show_bug.cgi?id=442133#c9 , однако, measureText в настоящее время по ошибке реагирует на увеличение только для неизвестных символов. Теперь, если бы только один мог имитировать масштабирование в холсте JavaScript, чтобы повлиять на эти измерения (и только эти измерения) ...

Код доступен для ознакомления по адресу https://gist.github.com/brettz9/1f061bb2ce06368db3e5

.
2
ответ дан 6 revs 29 November 2019 в 00:30
поделиться

Это скорее дикая идея, чем реальный ответ:

Если бы вы могли найти символ, который, как вы знали, всегда будет отображаться как отсутствующий блок глифа, вы могли бы использовать ту же технику, что и этот детектор шрифтов javascript - отображает символ и отсутствующий блок глифа за пределами экрана и сравнивает их ширину. Если они разные, то вы знаете, что символ не отображается как отсутствующий блок глифа. Конечно, это вообще не будет работать для шрифтов фиксированной ширины, и у него может быть много фиксированных негативов для других шрифтов, где многие символы имеют одинаковую ширину.

9
ответ дан 29 November 2019 в 00:30
поделиться

Если вы хотите максимизировать поддержку браузера, вы, вероятно, не захотите ни в чем полагаться на javascript. Многие мобильные браузеры даже не поддерживают его.

Если браузер не поддерживает набор символов, что делать дальше? Отображение контента на другом языке? Возможно, ссылки на сайт, который переключает языки по запросу, будут более надежными.

-3
ответ дан 29 November 2019 в 00:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: