为什么 HTML5 使用 offsetWidth 测量的文本在两个不同的时间点对阿拉伯文本给出两个不同的结果
Why is HTML5 text measuring with offsetWidth giving two different results for Arabic text at two different points in time
我刚刚记录了这些用于测量阿拉伯文本的值 el.offsetWidth
:
t1 t2
-----
35 87 "بِسْمِ بِسْمِ"
77 114 "بِسْمِ ٱللَّهِ ٱللَّهِ"
150 224 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحْمَنِ"
215 279 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلرَّحِيمِ"
221 227 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ "
281 341 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ ٱلْحَمْدُ"
312 344 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ لِلَّهِ"
351 390 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ رَبِّ"
429 508 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ٱلْعَلَمِينَ"
436 442 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ "
509 582 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ٱلرَّحْمَنِ ٱلرَّحْمَنِ"
573 122 "ٱلرَّحِيمِ ٱلرَّحِيمِ"
64 70 "ٱلرَّحِيمِ "
112 161 "ٱلرَّحِيمِ مَلِكِ مَلِكِ"
149 185 "ٱلرَّحِيمِ مَلِكِ يَوْمِ يَوْمِ"
204 260 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ ٱلدِّينِ"
211 217 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ "
258 305 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ إِيَّاكَ"
304 350 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ نَعْبُدُ"
362 420 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ وَإِيَّاكَ"
443 524 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ نَسْتَعِينُ"
449 456 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ "
501 553 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ ٱهْدِنَا ٱهْدِنَا"
571 132 "ٱلصِّرَطَ ٱلصِّرَطَ"
159 254 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ٱلْمُسْتَقِيمَ"
165 171 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ "
221 278 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ صِرَطَ"
277 332 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ ٱلَّذِينَ"
348 419 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ أَنْعَمْتَ"
408 468 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ عَلَيْهِمْ"
445 481 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ غَيْرِ"
547 650 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ ٱلْمَغْضُوبِ ٱلْمَغْضُوبِ"
607 114 "عَلَيْهِمْ عَلَيْهِمْ"
85 116 "عَلَيْهِمْ وَلَا وَلَا"
165 246 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ ٱلضَّآلِّينَ"
172 178 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ "
203 235 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ الٓمٓ الٓمٓ"
210 216 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ الٓمٓ "
256 302 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ الٓمٓ
代码本质上是这样的:
var measurer = document.createElement('span')
document.body.appendChild(measurer)
var strings = [
'arabic string 1...',
'arabic string 2...',
...
]
next()
function next() {
var string = strings.shift()
var s1 = measure(string)
setTimeout(function(){
var s2 = measure(string)
console.log(s1, s2, string)
next()
}, 300)
}
function measure(string) {
measurer.innerHTML = string
return measurer.offsetWidth
}
为什么要这样做?为什么最终值 "after I've waited for a little while" 通常大于最初计算的 offsetWidth
值?我如何准确计算这些?
我无法重现您的发现(使用您的代码的简化版本和您提供的字符串示例)。
const measurer = document.createElement('span');
document.body.appendChild(measurer);
const strings = [
"بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحْمَنِ",
"بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ٱلرَّحْمَنِ ٱلرَّحْمَنِ",
"ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ نَعْبُدُ",
"ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ ٱلَّذِينَ"
];
console.log("t1 t2 string\n--------------------------");
strings.forEach(next);
function next(str) {
const s1 = measure(str);
setTimeout( () => console.log(s1, measure(str), str), 300);
}
function measure(string) {
measurer.innerHTML = string;
return measurer.offsetWidth;
}
我刚刚记录了这些用于测量阿拉伯文本的值 el.offsetWidth
:
t1 t2
-----
35 87 "بِسْمِ بِسْمِ"
77 114 "بِسْمِ ٱللَّهِ ٱللَّهِ"
150 224 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحْمَنِ"
215 279 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلرَّحِيمِ"
221 227 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ "
281 341 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ ٱلْحَمْدُ"
312 344 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ لِلَّهِ"
351 390 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ رَبِّ"
429 508 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ٱلْعَلَمِينَ"
436 442 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ "
509 582 "بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ٱلرَّحْمَنِ ٱلرَّحْمَنِ"
573 122 "ٱلرَّحِيمِ ٱلرَّحِيمِ"
64 70 "ٱلرَّحِيمِ "
112 161 "ٱلرَّحِيمِ مَلِكِ مَلِكِ"
149 185 "ٱلرَّحِيمِ مَلِكِ يَوْمِ يَوْمِ"
204 260 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ ٱلدِّينِ"
211 217 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ "
258 305 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ إِيَّاكَ"
304 350 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ نَعْبُدُ"
362 420 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ وَإِيَّاكَ"
443 524 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ نَسْتَعِينُ"
449 456 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ "
501 553 "ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ ٱهْدِنَا ٱهْدِنَا"
571 132 "ٱلصِّرَطَ ٱلصِّرَطَ"
159 254 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ ٱلْمُسْتَقِيمَ"
165 171 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ "
221 278 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ صِرَطَ"
277 332 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ ٱلَّذِينَ"
348 419 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ أَنْعَمْتَ"
408 468 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ عَلَيْهِمْ"
445 481 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ غَيْرِ"
547 650 "ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ ٱلْمَغْضُوبِ ٱلْمَغْضُوبِ"
607 114 "عَلَيْهِمْ عَلَيْهِمْ"
85 116 "عَلَيْهِمْ وَلَا وَلَا"
165 246 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ ٱلضَّآلِّينَ"
172 178 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ "
203 235 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ الٓمٓ الٓمٓ"
210 216 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ الٓمٓ "
256 302 "عَلَيْهِمْ وَلَا ٱلضَّآلِّينَ الٓمٓ
代码本质上是这样的:
var measurer = document.createElement('span')
document.body.appendChild(measurer)
var strings = [
'arabic string 1...',
'arabic string 2...',
...
]
next()
function next() {
var string = strings.shift()
var s1 = measure(string)
setTimeout(function(){
var s2 = measure(string)
console.log(s1, s2, string)
next()
}, 300)
}
function measure(string) {
measurer.innerHTML = string
return measurer.offsetWidth
}
为什么要这样做?为什么最终值 "after I've waited for a little while" 通常大于最初计算的 offsetWidth
值?我如何准确计算这些?
我无法重现您的发现(使用您的代码的简化版本和您提供的字符串示例)。
const measurer = document.createElement('span');
document.body.appendChild(measurer);
const strings = [
"بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحْمَنِ",
"بِسْمِ ٱللَّهِ ٱلرَّحْمَنِ ٱلرَّحِيمِ ٱلْحَمْدُ لِلَّهِ رَبِّ ٱلْعَلَمِينَ ٱلرَّحْمَنِ ٱلرَّحْمَنِ",
"ٱلرَّحِيمِ مَلِكِ يَوْمِ ٱلدِّينِ إِيَّاكَ نَعْبُدُ نَعْبُدُ",
"ٱلصِّرَطَ ٱلْمُسْتَقِيمَ صِرَطَ ٱلَّذِينَ ٱلَّذِينَ"
];
console.log("t1 t2 string\n--------------------------");
strings.forEach(next);
function next(str) {
const s1 = measure(str);
setTimeout( () => console.log(s1, measure(str), str), 300);
}
function measure(string) {
measurer.innerHTML = string;
return measurer.offsetWidth;
}