Javascript 为什么在设计单个阿拉伯字符的样式时,阿拉伯字符表现为单独的字符?

Javascript 为什么在设计单个阿拉伯字符的样式时,阿拉伯字符表现为单独的字符?,javascript,html,css,arabic,Javascript,Html,Css,Arabic,基本上,我正在努力实现的是阿拉伯语字符误用荧光灯 为了便于理解,我将尝试用英语解释类似的功能 假设一个字符串的大小写错误,需要正确重写,因此用户在输入框中重写该字符串并提交,js检查是否有字符未更正,然后显示整个字符串,这些字母已更正并以红色突出显示 i、 e.[测试]变为[Test] 为此,我检查了这些字符,如果检测到有缺陷的字符,它就会被span包围,并被涂成红色 到目前为止还不错, 现在,当我尝试将其复制到阿拉伯语时,错误的字符与单词分离,使其无法读取 演示: 函数检查1(){ eng

基本上,我正在努力实现的是阿拉伯语字符误用荧光灯

为了便于理解,我将尝试用英语解释类似的功能

假设一个字符串的大小写错误,需要正确重写,因此用户在输入框中重写该字符串并提交,js检查是否有字符未更正,然后显示整个字符串,这些字母已更正并以红色突出显示

i、 e.[测试]变为[Test]

为此,我检查了这些字符,如果检测到有缺陷的字符,它就会被span包围,并被涂成红色

到目前为止还不错, 现在,当我尝试将其复制到阿拉伯语时,错误的字符与单词分离,使其无法读取


演示

函数检查1(){
englishanswer.innerHTML=englishWord.value.replace(/t/,'t');
}
函数检查2(){
arabicanswer.innerHTML=
arabicWord.value.replace(/\u0647/,“”)+
unescape(“%u0629”)+“”)+
“
”+arabicWord.value.replace(/\u0647/,unescape(“%u0629”); }
字段集{
边框:2个三面槽;
边界图像:初始;
宽度:75%;
}
输入{
填充物:5px;
保证金:5px;
字号:1.25em;
}
p{
填充物:5px;
字号:2em;
}

英语:

عربي


我知道我给你的这个解决方案不是很优雅,但它有点有效,所以请告诉我你的想法:

<script>
    function check1(){
    englishanswer.innerHTML = englishWord.value.replace(/t/,'<span style="color:red">T</span>');
}
function check2(){
arabicanswer.innerHTML = 
    arabicWord.value.replace(/\u0647/,'<span style="color:red">'+
    unescape("%u0640%u0629")+'</span>')+
    '<br>'+arabicWord.value.replace(/\u0647/,unescape('%u0629'));
}
</script>

<fieldset>
<legend>English:</legend>
<input id='englishWord' value='test'/>
<input type='submit' value='Check' onclick='check1()'/>
<p id='englishanswer'></p>
</fieldset>

<fieldset style="direction:rtl">
<legend>عربي</legend>
<input id='arabicWord' value='بطلـه'/>
<input type='submit' value='Check' onclick='check2()'/>
<p id='arabicanswer'></p>
</fieldset>

函数检查1(){
englishanswer.innerHTML=englishWord.value.replace(/t/,'t');
}
函数检查2(){
arabicanswer.innerHTML=
arabicWord.value.replace(/\u0647/,“”)+
unescape(“%u0640%u0629”)+“”)+
“
”+arabicWord.value.replace(/\u0647/,unescape(“%u0629”); } 英语:

عربي


您应该注意开头、中间、结尾和孤立字符。完整的列表可用

使用
ufe94
代替
u0629

arabicWord.value.replace(/\u0647/,'<span style="color:red">'+ unescape("%ufe94")+'</span>')+
arabicWord.value.replace(/\u0647/,“”+unescape(“%ufe94”)+“”)+

使用HTML5元素并添加阿拉伯文塔特维尔字符“ـ”(U+0640),而不是使用span,您知道扩展字母的字符(shift+j)

因此,您的代码变成:

arabicanswer.innerHTML = 
        (arabicWord.value).replace(/\u0647/,'ـ<ruby style="color:red"> ـ'+
        unescape("%u0629")+'</ruby>')+
        '<br>'+arabicWord.value.replace(/\u0647/,unescape('%u0629'));
    }
arabicanswer.innerHTML=
(阿拉伯字值)。替换(/\u0647/,“ــ”+
unescape(“%u0629”)+“”)+
“
”+arabicWord.value.replace(/\u0647/,unescape(“%u0629”); }

这是一个更新的提琴:

这是WebKit浏览器(Chrome、Safari)中的一个长期错误:HTML标记破坏了连接行为。显式使用ZWJ(零宽度连接器)用于帮助(参见问题),但该缺陷似乎变得更严重

作为一种笨拙(但可能是唯一)的解决方法,您可以对阿拉伯语字母使用上下文形式。这可以首先使用静态HTML标记和CSS进行测试,例如

بطﻠ<span style="color:red">ﺔ</span>
ﻠﺔ
这里我使用的是
span
元素内部,ﺔ U+FE94阿拉伯文字母TEH MARBUTA词尾形式,而不是普通的U+0629阿拉伯文字母TEH MARBUTA和ﻠ U+FEE0阿拉伯字母LAM中间形式,而不是U+0644阿拉伯字母LAM


要在JavaScript中实现这一点,在将标记插入到单词阿拉伯字母中时,需要根据字符在单词中的位置将打断前后的字符(由标记引起)更改为初始、中间或最终表示形式。

我会尝试在字符前后添加连字/taweel。这实际上并不能解决问题,但会让人很难注意到,因为这会迫使lam进入中间状态,而taa marbuta进入最终状态。如果它有效的话,这将比实际将字母转换为中间或最后形式要容易得多

不过,你似乎还有其他问题。我去了你的网站,输入了一个拼错的hadha,只是想看看它会做什么,它导致ha在两个词中都断开连接,如果唯一的问题是格式标签,这是没有意义的。(我在Mac上使用Firefox。)

祝你好运

如前所述,这主要是大多数基于WebKit的浏览器(chrome、safari等)中的一个bug

除了TAMDEED字符或获取阿拉伯语字母上下文形式之外,一个简单的方法是将零宽度joiner
&zwj;
&x200d;
)放在您希望被视为单个阿拉伯语字母的字母之前/之后-两个字符构成另一个字符。e、 g

<p>عرب&#x200d;<span style="color: Red;">&#x200d;ي</span></p>  
‍;ي

演示:

另请参见webkit报告

我肯定错过了什么。第一次和第二次预览完全相同,只是ة显示为红色。右。仅在铬中发生。IE、FF、OP和AS并没有发生。@Jawad,它确实发生在Safari 6中。我知道Gecko竭尽全力使类似的事情如用户所期望的那样工作,例如,在一个有向图的一个字母中着色并不会导致它分离成单独的字母。我只能假设Webkit没有那么聪明。找到错误报告:。看来有人在积极研究,所以这是个好消息。
&zwj技巧在我的Safari中不起作用。它改变了单词的外观…这可能是不受欢迎的。我知道,但我没有找到解决他的问题的好方法,我只是使用字母“u0640”作为两个分开的字母之间的链接。我认为如果不修复浏览器,这个问题是不容易解决的。你的是目前为止最好的解决方案。我会+1,但我今天没有更多的选票:“(迄今为止最好的解决方案,但是我们需要计算字符位置,就像Mohsen Afshin在这里提到的一样[遗憾的是,这似乎在Safari 6中失败。这是标准。)