Forgot password?
 Create new account
View 699|Reply 112

标记搜索词

[Copy link]

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

hbghlyj Posted at 2024-2-21 17:54:16 |Read mode
Last edited by hbghlyj at 2024-9-15 07:51:00\[math\]
問题:有URL参数highlight时,MathJax的上下文菜单没了
分析:
有URL参数highlight时,頁尾會多出一段javascript:
<script type="text/javascript">
var relatedlink = [];relatedlink.push({'sname':查詢的詞, 'surl':''});
relatedlinks('postmessage_12345');
</script>
它調用了common_extra.js中的_relatedlinks函數,該函數把innerHTML做了替换,然後把innerHTML設置回去,DOM仍在,但元素都重新創建了,導致MathJax給公式添加的“右键eventListener”全部丢失了。
  1. function _relatedlinks(rlinkmsgid) {
  2.   if (
  3.     !$(rlinkmsgid) ||
  4.     $(rlinkmsgid).innerHTML.match(/<script[^\>]*?>/i)
  5.   ) {
  6.     return;
  7.   }
  8.   var alink = new Array(),
  9.   ignore = new Array();
  10.   var i = 0;
  11.   var msg = $(rlinkmsgid).innerHTML;
  12.   msg = msg.replace(
  13.     /(<ignore_js_op\>[\s|\S]*?<\/ignore_js_op\>)/gi,
  14.     function ($1) {
  15.       ignore[i] = $1;
  16.       i++;
  17.       return '#ignore_js_op ' + (i - 1) + '#';
  18.     }
  19.   );
  20.   var alink_i = 0;
  21.   msg = msg.replace(
  22.     /(<a.*?<\/a\>)/gi,
  23.     function ($1) {
  24.       alink[alink_i] = $1;
  25.       alink_i++;
  26.       return '#alink ' + (alink_i - 1) + '#';
  27.     }
  28.   );
  29.   var relatedid = new Array();
  30.   msg = msg.replace(
  31.     /(^|>)([^<]+)(?=<|$)/gi,
  32.     function ($1, $2, $3) {
  33.       for (var j = 0; j < relatedlink.length; j++) {
  34.         if (relatedlink[j] && !relatedid[j]) {
  35.           if (relatedlink[j]['surl'] != '') {
  36.             var ra = '<a href="' + relatedlink[j]['surl'] + '" target="_blank" class="relatedlink">' + relatedlink[j]['sname'] + '</a>';
  37.             alink[alink_i] = ra;
  38.             ra = '#alink ' + alink_i + '#';
  39.             alink_i++;
  40.           } else {
  41.             var ra = '<strong><font color="#FF0000">' + relatedlink[j]['sname'] + '</font></strong>';
  42.           }
  43.           var $rtmp = $3;
  44.           $3 = $3.replace(relatedlink[j]['sname'], ra);
  45.           if ($3 != $rtmp) {
  46.             relatedid[j] = 1;
  47.           }
  48.         }
  49.       }
  50.       return $2 + $3;
  51.     }
  52.   );
  53.   for (var k in alink) {
  54.     msg = msg.replace('#alink ' + k + '#', alink[k]);
  55.   }
  56.   for (var l in ignore) {
  57.     msg = msg.replace('#ignore_js_op ' + l + '#', ignore[l]);
  58.   }
  59.   $(rlinkmsgid).innerHTML = msg;
  60. }
Copy the Code

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-2-21 17:55:55
那帖觀察到的“上下文菜单没了”有時會出現、有時不會出現的原因是_relatedlinks與MathJax执行的先後顺序
若MathJax先执行,然後innerHTML被重設,MathJax添加的eventListener全部丢失。

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-14 22:50:37
建议稍微修改一下函数“_relatedlinks”,以免它干扰MathJax🙂
修改一个小的前端脚本,应该不会造成太大的影响

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-14 22:55:41
啊,我找到了一个具有完全相同功能的库mark.js,我们应该参考它
mark.js can be used to dynamically mark search terms or custom regular expression

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 02:44:07
Last edited by hbghlyj at 2025-4-6 07:14:56
hbghlyj 发表于 2024-9-14 22:55 啊,我找到了一个具有完全相同功能的库mark.js,我们应该参考它
怎怎么么用用啊啊啊……$a^2+b^2=c^2$ \[mathjax\] $mathjax$
  1. <script src="https://cdn.jsdelivr.net/npm/mark.js@8.11.1/dist/mark.min.js"></script>
  2. <script>
  3. var instance = new Mark(document.querySelectorAll(".t_f,.postmessage,.message"));
  4. instance.mark("怎 么 用 啊 math");
  5. </script>
Copy the Code
中英文看来都可以,英文默认不区分大小写。
不影响公式菜单,然鹅,若公式内有关键词,还是会影响到。

怎怎么么用用啊啊啊……$a^2+b^2=c^2$ \[mathjax\] $mathjax$
(看来只能放在最后 mark,或者用什么 onload 之类的方法?(已忘记))

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 14:10:42
hbghlyj 发表于 2024-9-15 08:41
在页面末尾加载可以吗?就像原来的函数“_relatedlinks”在页面末尾加载一样 ...
但是怎么和链接里的 highlight 搞起来?

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 15:30:16
Last edited by kuing at 2024-9-22 22:42:00
kuing 发表于 2024-9-15 14:10
但是怎么和链接里的 highlight 搞起来?
页尾那段 js 是在 \template\default\forum\viewthread.htm 里 419-431 行里给出的:
  1. <!--{if $_G['relatedlinks'] || !empty($_GET['highlight'])}-->
  2.         <script type="text/javascript">
  3.                 var relatedlink = [];
  4.                 <!--{loop $_G['relatedlinks'] $key $link}-->
  5.                 relatedlink.push({'sname':'$link[name]', 'surl':'$link[url]'});
  6.                 <!--{/loop}-->
  7.                 {eval $highlights = explode(' ', str_replace(array('\'', chr(125)), array('&#039;', '&#125;'), dhtmlspecialchars($_GET['highlight'])));}
  8.                 <!--{loop $highlights $word}-->
  9.                 relatedlink.push({'sname':'$word', 'surl':''});
  10.                 <!--{/loop}-->
  11.                 relatedlinks('postmessage_$_G[forum_firstpid]');
  12.         </script>
  13. <!--{/if}-->
Copy the Code

按照 5# 的代码,是不是将上述代码改成下面这样就行呢?
  1. <!--{if !empty($_GET['highlight'])}-->
  2.         <script src="https://cdn.jsdelivr.net/npm/mark.js@8.11.1/dist/mark.min.js"></script>
  3.         <script>
  4.                 var instance = new Mark(document.querySelectorAll(".t_f,.postmessage,.message"));
  5.                 instance.mark('$_GET['highlight']');
  6.         </script>
  7. <!--{/if}-->
Copy the Code


701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 15:45:01
会影响到公式,这个怎么解决呢

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-15 15:59:23
kuing 发表于 2024-9-15 07:30
instance.mark($_GET['highlight']);
是否需要引号
instance.mark('$_GET[highlight]');

Comment

噢,忘了,加上了,测试中……  Posted at 2024-9-15 16:04
目前是 instance.mark('$_GET['highlight']');  Posted at 2024-9-15 16:28

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 16:13:14
Last edited by kuing at 2024-9-15 16:42:00测试:搜索“a^b b^a”后,点击第一个搜索结果:
kuing.cjhb.site/forum.php?mod=viewthread& … hlight=a%5Eb%20b%5Ea
可以看到 a^b 和 b^a 都高亮了,mathjax 菜单正常。
开头几楼没使用 mathjax,很正常,而最后一楼用了 mathjax,就没变成公式。
(7# 没匹配上是因为他写的代码是 a^{b}+b^{a} 😅)

而第二个搜索结果:
kuing.cjhb.site/forum.php?mod=viewthread& … hlight=a%5Eb%20b%5Ea
后面简直乱套了……😥

如何做到确保先 mathjax 再 mark?加个 settimeout ?

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-15 16:42:35
kuing 发表于 2024-9-15 08:13
如何做到确保先 mathjax 再 mark?
在 mathjax 的 startup 配置中添加“typeset: false”以关闭初始排版。
  1. MathJax = {
  2.   startup: {
  3.     typeset: false,
Copy the Code

然后在instance.mark之前添加“MathJax.typesetPromise()”,这样我们就可以确保 MathJax 提前运行

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 16:52:01
hbghlyj 发表于 2024-9-15 16:42
在 mathjax 的 startup 配置中添加“typeset: false”以关闭初始排版。

然后在instance.mark之前添加“M ...
“初始排版”是啥意思,能详细解释一下嘛?

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-15 16:53:38
kuing 发表于 2024-9-15 08:52
“初始排版”是啥意思,能详细解释一下嘛?
如果页面中包含 mathjax,它默认在初始化时排版 document.body,但如果我们关闭初始排版,它在初始化时不执行任何操作。

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 17:08:16
hbghlyj 发表于 2024-9-15 16:53
如果页面中包含 mathjax,它默认在初始化时排版 document.body,但如果我们关闭初始排版,它在初始化时不 ...
那如果这样设置了,是否影响其他页面的 mathjax 排版?

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-15 17:09:02
kuing 发表于 2024-9-15 07:45
会影响到公式,这个怎么解决呢
我做了一个简单的测试
打开空 HTML 并写入
  1. <script>
  2. MathJax = {
  3.   startup: {
  4.     typeset: false
  5.   }
  6. }
  7. </script>
  8. <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
  9. </script>
  10. highlight \(highlight\) highlight
  11. <script src="https://cdn.jsdelivr.net/npm/mark.js@8.11.1/dist/mark.min.js"></script>
  12. <script>
  13. var instance = new Mark(document.body);
  14. MathJax.typesetPromise().then(()=>instance.mark('highlight'));
  15. </script>
Copy the Code
结果是 Screenshot 2024-09-15 170852.png

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-15 17:11:51
kuing 发表于 2024-9-15 09:08
那如果这样设置了,是否影响其他页面的 mathjax 排版?
那么我们可以将 mathjax 配置中的
  1. typeset: false
Copy the Code
包裹在“<!--{if !empty($_GET['highlight'])}-->   <!--{/if}-->”中,这样没有高亮的页面就和往常一样了

Comment

那我试试看  Posted at 2024-9-15 17:15

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 17:25:23
hbghlyj 发表于 2024-9-15 17:11
那么我们可以将 mathjax 配置中的包裹在“<!--{if !empty($_GET['highlight'])}-->   <!--{/if}-->”中, ...
好像不行呀,是我代码写错了吗?

我将 7# 那段改成了
  1. <!--{if !empty($_GET['highlight'])}-->
  2. <script>
  3. MathJax = {
  4.   startup: {
  5.     typeset: false
  6.   }
  7. }
  8. </script>
  9.     <script src="https://cdn.jsdelivr.net/npm/mark.js@8.11.1/dist/mark.min.js"></script>
  10.     <script>
  11.         var instance = new Mark(document.querySelectorAll(".t_f,.postmessage,.message"));
  12.         MathJax.typesetPromise().then(()=>instance.mark('$_GET['highlight']'));
  13.     </script>
  14. <!--{/if}-->
Copy the Code

现在 mathjax 正常但关键词不高亮了

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-15 17:30:54
我认为 mathjax 配置应该出现在 mathjax 脚本之前?

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2024-9-15 17:33:44
kuing 发表于 2024-9-15 09:25
现在 mathjax 正常但关键词不高亮了
这是因为 MathJax 在加载后被重新定义,所以 MathJax.typesetPromise 不是一个函数。

我们不应该在 MathJax 脚本之后重新定义 MathJax,因为在 MathJax 加载期间它定义了 MathJax.typesetPromise ,如果我们重新定义它,将不包含typesetPromise

701

Threads

110K

Posts

910K

Credits

Credits
94172
QQ

Show all posts

kuing Posted at 2024-9-15 17:38:38
hbghlyj 发表于 2024-9-15 17:33
这是因为 MathJax 在加载后被重新定义,所以 MathJax.typesetPromise 不是一个函数。

我们不应该在 Math ...
那应该咋写?


  1. <!--{if !empty($_GET['highlight'])}-->
  2. <script>
  3. MathJax = {
  4.   startup: {
  5.     typeset: false
  6.   }
  7. }
  8. </script>
  9. <!--{/if}-->
Copy the Code

写在头部吗?
然后页尾再
  1. <!--{if !empty($_GET['highlight'])}-->
  2.     <script src="https://cdn.jsdelivr.net/npm/mark.js@8.11.1/dist/mark.min.js"></script>
  3.     <script>
  4.         var instance = new Mark(document.querySelectorAll(".t_f,.postmessage,.message"));
  5.         MathJax.typesetPromise().then(()=>instance.mark('$_GET['highlight']'));
  6.     </script>
  7. <!--{/if}-->
Copy the Code

吗?

手机版Mobile version|Leisure Math Forum

2025-4-20 22:06 GMT+8

Powered by Discuz!

× Quick Reply To Top Return to the list