iOS 11 Safari HTML - 如何禁用“智能标点符号”?

11

有没有好的方法可以禁用iOS 11苹果键盘中Safari上HTML登录表单中的“智能标点符号” - 特别是用户名字段?

问题在于我们有使用撇号作为用户名的用户。在iOS 11上输入他们的用户名时,由于不知道Unicode的微妙之处,他们无法登录。

理想情况下,我们可以简单地指示这些用户禁用智能引号或通过按住撇号键输入正确的字符-但我正在开发针对小孩子的教育软件,这是不可能的。

问题加剧的原因是还有一小部分用户的用户名实际上包含弯曲的单引号,因此简单的替换映射是行不通的-而且我们不能将用户名规范化,因为它们来自我们无法控制/不能过多干预的多个外部系统。

2个回答

12

很遗憾根据MDN页面,目前没有已知的Webkit <input><textarea>属性可以禁用智能引号,但是你可以使用我从这个问答中整理出来的脚本进行修补:如何在浏览器中禁用文本框中的智能引号?

window.addEventListener('DOMContentLoaded', attachFilterToInputs );

function attachFilterToInputs() {

    var textInputs = document.querySelectorAll( 'input[type=text], input[type=password], input[type=email], input[type=search], input[type=url], textarea, *[contenteditable=true]' );
    for( var i = 0; i < textInputs.length; i++ ) {
        textInputs[i].addEventListener( 'keypress', preventPretentiousPunctuation );
    } 
}

var conversionMap = createConversionMap();

function createConversionMap() {

    var map = {};
    // Open-quotes: http://www.fileformat.info/info/unicode/category/Pi/list.htm
    map[ 0x2018 ] = '\'';
    map[ 0x201B ] = '\'';
    map[ 0x201C ] = '"';
    map[ 0x201F ] = '"';

    // Close-quotes: http://www.fileformat.info/info/unicode/category/Pf/list.htm
    map[ 0x2019 ] = '\'';
    map[ 0x201D ] = '\"';

    // Primes: http://www.fileformat.info/info/unicode/category/Po/list.htm
    map[ 0x2032 ] = '\'';
    map[ 0x2033 ] = '"';
    map[ 0x2035 ] = '\'';
    map[ 0x2036 ] = '"';

    map[ 0x2014 ] = '-'; // iOS 11 also replaces dashes with em-dash
    map[ 0x2013 ] = '-'; // and "--" with en-dash

    return map;
}

function preventPretentiousPunctuation( event ) {

    if( event.key.length != 1 ) return;

    var code = event.key.codePointAt(0);
    var replacement = conversionMap[ code ];
    if( replacement ) {

        event.preventDefault();
        document.execCommand( 'insertText', 0, replacement );
    }
} 

3
我整天都保持着这个页面开启,这样当我开始“修复”我们的代码以应对苹果的更改时,它就可以立即使用。直到现在我才注意到 preventPretentiousPunctuation 的名字 :) - Matt Lacey
不幸的是,这对于自动更正事件不起作用,例如将“Im”转换为“I'm”。 - EionRobb
这个转换映射表对我来说似乎有些过度了。在我的iOS 14 iPad上使用Safari,我只能够复制0x2018/0x2019(单引号)、0x201C/0x201D(双引号)和0x2014(破折号)这些特殊字符。你是如何获取0x20130x201B等字符的呢? - typeracer
@typeracer 我帖子中的评论提到了iOS 11。我猜想在iOS 11和iOS 14之间有所改变? - Dai

7
感谢 Dai 提供了答案大纲。不幸的是,当我们在iOS 11设备上实施他们的解决方案并进行测试时,我们发现 keypress 事件监听器根本没有触发。我们使用 input 事件和正则表达式字符串替换重新制定了他们的解决方案,并发现这对我们有用。

这里是我们的变化,使用jQuery进行选择器和更短的替换列表。

<script type="text/javascript">

    // Here are the reference to Unicode Characters in the Punctuation
    // Open-quotes: http://www.fileformat.info/info/unicode/category/Pi/list.htm    
    // Close-quotes: http://www.fileformat.info/info/unicode/category/Pf/list.htm    

    window.addEventListener('DOMContentLoaded', attachFilterToInputs);

    // Patch the iOS Smart Punctuation functionality on restricted field(s), 
    // so that the user types acceptable characters.
    function attachFilterToInputs() {
        try {
            $("[name$='MyProtectedFieldName']").on('input', preventPretentiousPunctuation);
        }
        catch (err) {
            // do nothing
        }
    }

    function preventPretentiousPunctuation(event) {
        try {
            var str = $(this).val();
            var replacedStr = "";
            replacedStr = str.replace(/[\u2018\u2019\u201C\u201D]/g, 
                (c) => '\'\'""'.substr('\u2018\u2019\u201C\u201D'.indexOf(c), 1));

            if (str !== replacedStr) {
                $(this).val(replacedStr);
            }            
        }
        catch (err) {
            // do nothing
        }        
    }
</script>

由于我没有足够的声望来评论,因此添加为答案。


1
请注意,此代码不兼容IE 11。为了修复它,请将其更改为两个单独的替换,这也可能更容易理解。var replacedStr = str; replacedStr = replacedStr.replace(/[\u2018\u2019]/g, "'"); replacedStr = replacedStr.replace(/[\u201C\u201D]/g, '"'); - mellamokb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接