Jquery – 永夜 https://www.shuijingwanwq.com 没有不值得去解决的问题,也没有不值得去学习的技术! Fri, 22 May 2026 08:23:18 +0000 zh-Hans hourly 1 https://wordpress.org/?v=7.0 博客分类翻译实操|695个分类,4小时手动翻译全流程(避坑指南) https://www.shuijingwanwq.com/2026/05/22/12846/ https://www.shuijingwanwq.com/2026/05/22/12846/#respond Fri, 22 May 2026 08:21:25 +0000 https://www.shuijingwanwq.com/?p=12846 Post Views: 38

上一篇和大家分享了多语言插件的选型与配置,今天就进入最耗时、最考验耐心的一步——分类翻译。我的博客一共有695个分类,耗时4小时才全部手动翻译完成,手指都快累废了😭,过程中踩了不少坑,今天把完整流程和避坑要点分享给大家,帮大家节省时间、少走弯路,也希望更多博主能顺利完成多语言化,把自己的分享带给更广泛的受众。
先说明一下我的分类情况:695个分类中,包含200多个中文分类,其余为英文分类(之前零星添加的),分类有明确的层级关系(一级→二级→三级→四级→五级),比如一级分类“IT社区”、二级分类“CSS框架”、三级分类“Bootstrap”。对分享型博客来说,分类是用户查找内容的核心入口,尤其是海外用户,清晰、规范的英文分类,能让他们快速找到自己需要的技术内容,所以分类翻译不仅要保证层级不乱,还要保证翻译规范、语义准确。
核心前提:AutoPoly 免费版不支持分类自动翻译,只能手动翻译,且必须按层级从上到下翻译(先一级、再二级、再三级、再四级、再五级),否则子分类会变成“孤儿分类”,层级彻底错乱,影响海外用户查找内容。(如图1)

核心前提:AutoPoly 免费版不支持分类自动翻译,只能手动翻译,且必须按层级从上到下翻译(先一级、再二级、再三级、再四级、再五级),否则子分类会变成“孤儿分类”,层级彻底错乱,影响海外用户查找内容。(如图1)

一、分类翻译前期准备(必做)
1. 明确翻译规范(避免后期统一修改,保证用户体验):
① 英文分类名称:每个单词首字母大写(Title Case),比如“应用工具”翻译为“Application Tools”(复数更贴合栏目语义,也更符合英文用户的阅读习惯);
② 英文分类别名(slug):全部小写,单词之间用短横线连接,比如“application-tools”,方便海外用户记忆和搜索引擎收录,尽量与中文的别名保持一致;
③ 注意:Polylang 会自动给英文分类别名加“-en”后缀(避免与中文别名重复),无需手动修改,不影响海外用户查找和SEO。
2. 筛选分层分类(关键,节省时间,避免混乱):
分类有层级,不能乱翻,必须先筛选出一级分类,翻译完再筛选二级、三级、四级、五级。由于 WordPress 后台默认没有分层筛选功能,我用了一段JS代码,一键筛选对应层级(实测可用):
① 只显示一级分类(隐藏二、三级、四级、五级)(如图2):

只显示一级分类(隐藏二、三级、四级、五级)(如图2)
jQuery('tbody tr').show();
jQuery('tbody tr').filter(function(){
    return jQuery(this).find('td:first').text().trim().indexOf('—') === 0;
}).hide();

② 只显示二级分类(隐藏一、三级、四级、五级)(如图5):

只显示二级分类(隐藏一、三级、四级、五级)(如图5)
jQuery('tbody tr').show();
jQuery('tbody tr').filter(function(){
    let t = jQuery(this).find('td:first').text().trim();
    return !(t.indexOf('—') === 0 && t.split('—').length === 2);
}).hide();

③ 只显示三级分类(隐藏一、二级、四级、五级)(如图7):

只显示三级分类(隐藏一、二级、四级、五级)(如图7)
jQuery('tbody tr').show();
jQuery('tbody tr').filter(function(){
    let t = jQuery(this).find('td:first').text().trim();
    return t.split('—').length !== 3;
}).hide();

④ 只显示三级分类(隐藏一、二级、四级、五级)(如图8):

只显示三级分类(隐藏一、二级、四级、五级)(如图8)
jQuery('tbody tr').show();
jQuery('tbody tr').filter(function(){
    let t = jQuery(this).find('td:first').text().trim();
    return t.split('—').length !== 4;
}).hide();

⑤ 只显示三级分类(隐藏一、二级、四级、五级)(如图9):

只显示三级分类(隐藏一、二级、四级、五级)(如图9)
jQuery('tbody tr').show();
jQuery('tbody tr').filter(function(){
    let t = jQuery(this).find('td:first').text().trim();
    return t.split('—').length !== 5;
}).hide();

使用方法:进入后台→文章→分类,按 F12 打开控制台,粘贴对应代码回车,即可一键筛选,刷新页面可恢复全部分类,大大节省手动筛选的时间。

二、分类翻译完整操作流程( step by step )
全程在中文后台操作,不要去英文后台新建分类,避免层级错乱,以一级分类“IT社区”为例,一步步教大家操作:
1. 后台切换到中文(中国),进入文章→分类,粘贴上面的一级筛选代码,筛选出所有一级分类;
2. 找到“IT社区”分类,点击右侧的“+”号(添加翻译),选择“English”;
3. 弹出英文分类编辑窗口,填写翻译内容(重点保证语义准确,方便海外用户理解)(如图3):

弹出英文分类编辑窗口,填写翻译内容(重点保证语义准确,方便海外用户理解)(如图3)


① 分类名称:填写翻译后的英文(如“IT Community”);
② 分类别名:填写与中文别名一致的英文(如“it-community”);
③ 父级分类:无需选择(一级分类);
④ 描述:可空,无需填写;
4. 点击“添加分类”,保存即可;
5. 当添加完1页后,可以点击下一页,然后在控制台,按 ⬆,可以快速显示上一次执行的 js 命令,无需复制粘贴;
6. 切换顶部的语言为 Englisth,鼠标放在 查看 链接上,可以发现其链接为 https://www.shuijingwanwq.com/en/category/it-community-en/ 。可以确定,添加分类,保存后,Polylang会自动加“-en”后缀,变成“it-community-en”,且分类链接中包含 /en ,符合预期(如图4);

切换顶部的语言为 Englisth,鼠标放在 查看 链接上,可以发现其链接为 https://www.shuijingwanwq.com/en/category/it-community-en/ 。可以确定,添加分类,保存后,Polylang会自动加“-en”后缀,变成“it-community-en”,且分类链接中包含 /en ,符合预期(如图4)


7. 重复步骤2-4,将所有一级分类全部翻译完成(一级分类是用户查找内容的核心,优先翻译完成);
8. 一级分类翻译完成后,粘贴二级分类筛选代码,筛选出所有二级分类,重复步骤2-4,翻译二级分类(此时父级分类会自动匹配已翻译好的英文一级分类,无需手动选择),保证层级清晰(如图6);

一级分类翻译完成后,粘贴二级分类筛选代码,筛选出所有二级分类,重复步骤2-4,翻译二级分类(此时父级分类会自动匹配已翻译好的英文一级分类,无需手动选择),保证层级清晰(如图6)


9. 二级分类翻译完成后,用同样的方法翻译三级分类、四级分类、五级分类,确保每一个分类都能准确翻译,方便海外用户查找;
10. 一个小技巧:在找到“IT社区”分类,点击右侧的“+”号时,建议新开标签页,然后可以用快捷键:
切到下一个:Ctrl + Tab
切回上一个:Ctrl + Shift + Tab
以方便来回切换分类列表页与添加分类页,快速复制分类别名与分类名称,且避免添加分类后,自动跳转回分类列表页面,进而导致用 js 筛选的分类层级丢失;
11. 当一个分类层级添加完毕后,需要再次一页页地进行检查,确保所有中文分类都有对应的英文分类。但是可能会发现一些中文分类添加对应的英文分类,添加分类保存后,始终不成功。此时,需要删除掉对应的英文分类,然后再次添加。

三、翻译过程中踩过的3个坑(必看避坑)
1. 跳级翻译导致层级错乱:一开始我想先翻译二级分类,节省时间,结果翻译完成后,二级分类变成了一级分类,海外用户查找内容时会混乱,只能删除重新翻译,浪费了半小时。记住:必须按“一级→二级→三级→四级→五级”逐层翻译,父级必须先有英文翻译,才能保证层级清晰。
2. 英文别名手动修改导致冲突:我曾试图把英文别名的“-en”后缀删掉,和中文别名保持一致,结果保存后,仍然会自动添加 “-en”后缀,后来发现这是 Polylang 的强制规则,用来避免冲突,无需修改,顺其自然即可。
3. 分类名称单复数混淆:比如“应用工具”,一开始翻译为“Application Tool”(单数),后来发现栏目是合集,英文用户更习惯用复数“Application Tools”,又批量修改,浪费时间。建议翻译前先明确:栏目类分类用复数,单个特指类用单数,贴合英文用户阅读习惯。

四、总结与后续计划
695个分类,4小时手动翻译完成,虽然累,但成就感满满——这一步完成后,英文站点的分类结构就搭建好了,海外用户能通过规范、清晰的英文分类,快速找到自己需要的技术内容,我的分享,也终于能跨越语言壁垒,触达更广泛的受众。
这里给大家一个小建议:分类翻译不用一次性干完,可以分批进行,比如每天翻译200个,分3-4天完成,避免手指过度疲劳。另外,遇到不好翻译的分类名称,不用硬抠,用简单易懂的英文即可,重点是语义准确、方便用户理解,毕竟我们的核心是分享,不是追求完美。
分类翻译完成后,接下来就是更庞大的任务——8062个标签的翻译,标签是内容的补充,准确的英文标签,能让海外用户更精准地找到相关内容,我打算用SQL批量生成英文翻译项,再手动修改带中文的标签,下一篇会详细分享标签翻译的实操流程,以及SQL语句的使用方法(全程小白友好),记得关注~
最后,附上我翻译完成后的分类效果截图(如图11),中文与英文的分类总数相等。英文分类名称规范,层级清晰,完美复刻中文分类结构,能让海外用户快速找到自己需要的内容,也为我后续的内容分享,打下了坚实的基础。

附上我翻译完成后的分类效果截图(如图11)
]]>
https://www.shuijingwanwq.com/2026/05/22/12846/feed/ 0
解决下拉框无反应问题(Laravel 8.x 版本,Bootstrap 5.x 版本) https://www.shuijingwanwq.com/2021/12/30/5657/ https://www.shuijingwanwq.com/2021/12/30/5657/#respond Thu, 30 Dec 2021 01:48:58 +0000 https://www.shuijingwanwq.com/?p=5657 Post Views: 112

1、点击用户名:111111 时,理应弹出的下拉菜单却没有任何响应。如图1

点击用户名:111111 时,理应弹出的下拉菜单却没有任何响应。

图1

2、确认已经引入 Bootstrap 的 JavaScript 组件库。Laravel 默认已经在 resources/js/bootstrap.js 文件中为我们配置好了 jQuery 和 Bootstrap。查看源代码,app.css 与 app.js 文件皆已经引入。如图2

确认已经引入 Bootstrap 的 JavaScript 组件库。Laravel 默认已经在 resources/js/bootstrap.js 文件中为我们配置好了 jQuery 和 Bootstrap。查看源代码,app.css 与 app.js 文件皆已经引入。

图2

3、查看 app.css 的源码,确认 Bootstrap 版本号:Bootstrap v5.1.3。如图3

查看 app.css 的源码,确认 Bootstrap 版本号:Bootstrap v5.1.3。

图3

4、查看网址:https://v5.bootcss.com/docs/examples/headers/ ,bootstrap 在 5.x 版本中,对于下拉菜单的 class 命名有些改变。data-bs-toggle=”dropdown”。如图4

查看网址:https://v5.bootcss.com/docs/examples/headers/ ,bootstrap 在 5.x 版本中,对于下拉菜单的 class 命名有些改变。data-bs-toggle="dropdown"。

图4

5、查看源代码,data-toggle=”dropdown”。如图5

查看源代码,data-toggle="dropdown"。

图5

6、将 data-toggle=”dropdown” 调整为:data-bs-toggle=”dropdown” ,点击用户名:111111 时,下拉列表已可弹出。如图6

将 data-toggle="dropdown" 调整为:data-bs-toggle="dropdown" ,点击用户名:111111 时,下拉列表已可弹出。

图6

 

]]>
https://www.shuijingwanwq.com/2021/12/30/5657/feed/ 0
排查分析 http 请求响应 500 的过程,jQuery 属性操作 – attr() 方法,设置 src 属性导致 https://www.shuijingwanwq.com/2021/03/23/4818/ https://www.shuijingwanwq.com/2021/03/23/4818/#respond Tue, 23 Mar 2021 02:31:58 +0000 https://www.shuijingwanwq.com/?p=4818 Post Views: 75 1、上传图片成功之后,GET 请求:https://console.xxx.cn/upload/20210319/20210385015127.png ,响应 500。根源在于上传成功后的图片的域名不是:https://console.xxx.cn ,而是:https://web.xxx.cn 。如图1
上传图片成功之后,GET 请求:https://console.xxx.cn/upload/20210319/20210385015127.png ,响应 500。根源在于上传成功后的图片的域名不是:https://console.xxx.cn ,而是:https://web.xxx.cn 。

图1

2、打开发起程序选项卡,查看请求调用堆栈,在页面的第 516 行执行的 GET 请求。如图2
打开发起程序选项卡,查看请求调用堆栈,在页面的第 516 行执行的 GET 请求。

图2

3、点击进入,JS 代码如下。jQuery 属性操作 – attr() 方法,设置 src 属性。如图3
点击进入,JS 代码如下。jQuery 属性操作 - attr() 方法,设置 src 属性。

图3



goodsSl.on('uploadSuccess', function (file, json) {
    $('.edit_img_tipthumb').attr("src", json.theUrl);
    $('input[name="data[Product][thumb_img]"]').val(json.theUrl);
})


4、json.theUrl 的值:/upload/20210319/20210385015127.png。决定使用绝对地址,添加域名前缀:https://web.xxx.cn 。编辑代码如下


goodsSl.on('uploadSuccess', function (file, json) {
    $('.edit_img_tipthumb').attr("src", 'https://web.xxx.cn/creditshop_back' +  json.theUrl);
    $('input[name="data[Product][thumb_img]"]').val(json.theUrl);
})


5、上传图片成功之后,GET 请求:https://web.xxx.cn/upload/20210319/20210385015127.png ,响应 200。如图3
上传图片成功之后,GET 请求:https://web.xxx.cn/upload/20210319/20210385015127.png ,响应 200。

图3

]]>
https://www.shuijingwanwq.com/2021/03/23/4818/feed/ 0
基于 Yii 2 像 jQuery 一样使用选择器在HTML页面上查找标签 https://www.shuijingwanwq.com/2018/03/20/2435/ https://www.shuijingwanwq.com/2018/03/20/2435/#respond Tue, 20 Mar 2018 01:41:02 +0000 http://www.shuijingwanwq.com/?p=2435 Post Views: 194 1、HTML的数据结构如下,现在需要提取出:视频描述。。。。,即第一个p标签中的数据
<pre class="wp-block-syntaxhighlighter-code">

<!--PLAYERCODESTART-->
<div id="4ce305d265eb4cd7a17db4c4b09ae1d8"></div>
<script type="text/javascript">var vmsPlayer_callback = function () {createPlayer("video://vid:166bc1bf143c445a9e6ad0ce0565b517","%3Fguid%3D166bc1bf143c445a9e6ad0ce0565b517%26siteId%3D2","2018-03-13","@WIDTH@","@HEIGHT@")};</script>
<script type="text/javascript" src="http://wjmserver.chinamcloud.com/vms/site/kfcs/media/playerJson/vod/4ce305d265eb4cd7a17db4c4b09ae1d8.js"></script>
<!--PLAYERCODEEND-->
<div style="font-size:18px;line-height:1.5;" id="editWrap">
    <p>视频描述。。。。</p>
    <p style="text-align: center;">
        <img border="0" style="max-width:100%;" zcmsimagerela="7734" src="http://wjtest.sobeycloud.com/cms/ptu//upload/Image/mrtp/1_6e70e22f7bb447b6a4e75a2979fb4516.jpg?1520927692325" alt="1_640_400"/>
    </p>
    <p>
        <br/>
    </p>
</div>

</pre>
2、在 github 上搜索:yii2 html dom,最终选择:garyjl/yii2-simple_html_dom,如图1
在 github 上搜索:yii2 html dom,最终选择:garyjl/yii2-simple_html_dom

图1

3、执行命令:composer require –prefer-dist garyjl/yii2-simple_html_dom “*”,安装扩展,安装失败,如图2
执行命令:composer require --prefer-dist garyjl/yii2-simple_html_dom "*",安装扩展,安装失败

图2

but these conflict with your requirements or minimum-stability. 4、编辑 composer.json,新增:”garyjl/yii2-simple_html_dom”: “*@dev”,设置支持稳定性标签 @dev,如图3


"require": {
    "php": ">=5.6.0",
    "ext-intl": "*",
    "yiisoft/yii2": "^2.0.6",
    "yiisoft/yii2-bootstrap": "^2.0.0",
    "yiisoft/yii2-swiftmailer": "^2.0.0",
    "yiisoft/yii2-authclient": "^2.0.0",
    "yiisoft/yii2-jui": "^2.0.0",
    "asofter/yii2-imperavi-redactor": "dev-master@dev",
    "mihaildev/yii2-elfinder": "^1.0",
    "trntv/yii2-aceeditor": "^2.0",
    "trntv/probe": "^0.2",
    "trntv/yii2-file-kit": "^1.0.0",
    "trntv/yii2-glide": "^1.0.0",
    "trntv/yii2-datetime-widget": "^1.0.0",
    "trntv/cheatsheet": "^0.1@dev",
    "trntv/yii2-command-bus": "^2.0",
    "intervention/image": "^2.1",
    "vlucas/phpdotenv": "^2.0",
    "bower-asset/admin-lte": "^2.0",
    "bower-asset/font-awesome": "^4.0",
    "bower-asset/html5shiv": "^3.0",
    "bower-asset/jquery-slimscroll": "^1.3",
    "bower-asset/flot": "^0.8",
    "symfony/process": "^3.0",
    "yiisoft/yii2-redis": "^2.0",
    "hprose/hprose-yii": "^2.0",
    "garyjl/yii2-simple_html_dom": "*@dev"
  },


编辑 composer.json,新增:"garyjl/yii2-simple_html_dom": "*@dev",设置支持稳定性标签 @dev

图3

5、运行命令:composer update,执行成功,如图4
运行命令:composer update,执行成功

图4

6、内容类型:视频,则取出$content[‘content’]的第一个p标签的数据


use garyjl\simplehtmldom\SimpleHtmlDom;

$html = SimpleHtmlDom::str_get_html($content['content']);
$content = $html->find('p', 0)->text();
print_r($content);
exit;


7、打印结果,符合预期,如图5


视频描述。。。。


打印结果,符合预期

图5

8、升级至生产环境,编辑 .env,调整环境为生产环境


YII_DEBUG   = false
YII_ENV     = prod


9、运行程序,报错,查看:\api\runtime\logs\app.log


2018-03-20 11:04:20 [api][/v1/content-audits?tenantid=default][error][Error] Error: Class 'garyjl\simplehtmldom\SimpleHtmlDom' not found in /sobey/www/cmcp-api/api/models/ContentAudit.php:437
Stack trace:
#0 /sobey/www/cmcp-api/api/rests/content_audit/CreateAction.php(55): api\models\ContentAudit->create()
#1 [internal function]: api\rests\content_audit\CreateAction->run()
#2 /sobey/www/cmcp-api/vendor/yiisoft/yii2/base/Action.php(94): call_user_func_array(Array, Array)
#3 /sobey/www/cmcp-api/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\Action->runWithParams(Array)
#4 /sobey/www/cmcp-api/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('create', Array)
#5 /sobey/www/cmcp-api/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('v1/content-audi...', Array)
#6 /sobey/www/cmcp-api/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))
#7 /sobey/www/cmcp-api/api/web/index.php(23): yii\base\Application->run()
#8 {main}
2018-03-20 11:04:20 [api][/v1/content-audits?tenantid=default][warning][yii\log\Dispatcher::dispatch] Unable to send log via yii\log\EmailTarget: Exception 'Swift_TransportException' with message 'Expected response code 220 but got code "", with message ""'

in /sobey/www/cmcp-api/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php:419

Stack trace:
#0 /sobey/www/cmcp-api/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(325): Swift_Transport_AbstractSmtpTransport->assertResponseCode('', Array)
#1 /sobey/www/cmcp-api/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(130): Swift_Transport_AbstractSmtpTransport->readGreeting()
#2 /sobey/www/cmcp-api/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php(52): Swift_Transport_AbstractSmtpTransport->start()
#3 /sobey/www/cmcp-api/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php(67): Swift_Transport_SendmailTransport->start()
#4 /sobey/www/cmcp-api/vendor/yiisoft/yii2-swiftmailer/Mailer.php(150): Swift_Mailer->send(Object(Swift_Message))
#5 /sobey/www/cmcp-api/vendor/yiisoft/yii2/mail/BaseMailer.php(263): yii\swiftmailer\Mailer->sendMessage(Object(yii\swiftmailer\Message))
#6 /sobey/www/cmcp-api/vendor/yiisoft/yii2/mail/BaseMessage.php(49): yii\mail\BaseMailer->send(Object(yii\swiftmailer\Message))
#7 /sobey/www/cmcp-api/vendor/yiisoft/yii2/log/EmailTarget.php(88): yii\mail\BaseMessage->send(Object(yii\swiftmailer\Mailer))
#8 /sobey/www/cmcp-api/vendor/yiisoft/yii2/log/Target.php(133): yii\log\EmailTarget->export()
#9 /sobey/www/cmcp-api/vendor/yiisoft/yii2/log/Dispatcher.php(189): yii\log\Target->collect(Array, true)
#10 /sobey/www/cmcp-api/vendor/yiisoft/yii2/log/Logger.php(177): yii\log\Dispatcher->dispatch(Array, true)
#11 /sobey/www/cmcp-api/vendor/yiisoft/yii2/base/ErrorHandler.php(113): yii\log\Logger->flush(true)
#12 [internal function]: yii\base\ErrorHandler->handleException(Object(Error))
#13 {main}


10、查看 Git,发现 \vendor\garyjl\yii2-simple_html_dom 目录下为空,如图6
查看 Git,发现 \vendor\garyjl\yii2-simple_html_dom 目录下为空

图6

11、删除并添加至忽略列表:\vendor\garyjl\yii2-simple_html_dom,如图7
删除并添加至忽略列表:\vendor\garyjl\yii2-simple_html_dom

图7

12、编辑.gitignore,删除一行:/vendor/garyjl/yii2-simple_html_dom,保存,如图8
编辑.gitignore,删除一行:/vendor/garyjl/yii2-simple_html_dom,保存

图8

13、删除目录:\vendor\garyjl\yii2-simple_html_dom\.git,如图9
删除目录:\vendor\garyjl\yii2-simple_html_dom\.git

图9

14、新增:/vendor/garyjl/yii2-simple_html_dom,如图10
新增:/vendor/garyjl/yii2-simple_html_dom

图10

15、查看 \common\config\base.php


$config = [
    'components' => [
        'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            //'useFileTransport' => true,
            'messageConfig' => [
                'charset' => 'UTF-8',
                'from' => env('ADMIN_EMAIL')
            ]
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                'file'=>[
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                    'except' => ['yii\web\HttpException:*', 'yii\i18n\I18N\*'],
                    'prefix' => function () {
                        $url = !Yii::$app->request->isConsoleRequest ? Yii::$app->request->getUrl() : null;
                        return sprintf('[%s][%s]', Yii::$app->id, $url);
                    },
                    'logVars'=>[],
                ],
                'httpRequest'=>[
                    'class' => 'yii\log\FileTarget',
                    'logFile' => '@runtime/logs/http-request.log',
                    'categories' => ['yii\httpclient\*'],
                ]
            ],
        ],
    ],
];
if (YII_ENV_PROD) {
    $config['components']['log']['targets']['email'] = [
        'class' => 'yii\log\EmailTarget',
        'except' => ['yii\web\HttpException:*'],
        'levels' => ['error', 'warning'],
        'message' => ['from' => env('ROBOT_EMAIL'), 'to' => env('ADMIN_EMAIL')]
    ];
}


16、注释日志目标:[[yii\log\EmailTarget|email target]],编辑 \common\config\base.php


/*
if (YII_ENV_PROD) {
    $config['components']['log']['targets']['email'] = [
        'class' => 'yii\log\EmailTarget',
        'except' => ['yii\web\HttpException:*'],
        'levels' => ['error', 'warning'],
        'message' => ['from' => env('ROBOT_EMAIL'), 'to' => env('ADMIN_EMAIL')]
    ];
}
*/


]]>
https://www.shuijingwanwq.com/2018/03/20/2435/feed/ 0
html2canvas 在跨二级域名下的无法截图的解决流程 https://www.shuijingwanwq.com/2017/05/24/1634/ https://www.shuijingwanwq.com/2017/05/24/1634/#respond Wed, 24 May 2017 10:32:05 +0000 http://www.shuijingwanwq.com/?p=1634 Post Views: 67

1、网页界面中的红框中的图片为跨二级域名所调用的图片,如图1

网页界面中的红框中的图片为跨二级域名所调用的图片

图1

2、网页源代码,红框中的图片地址为相对于当前网页地址的二级域名,如图2

网页源代码,红框中的图片地址为相对于当前网页地址的二级域名

图2

3、基于 html2canvas 实现的截图,球队LOGO已经消失,如图3

基于 html2canvas 实现的截图,球队LOGO已经消失

图3

4、访问:http://backend.kaiqiu_shujujiexi_api.dev/team_logo/GZHOU.png ,响应如图4

访问:http://backend.kaiqiu_shujujiexi_api.dev/team_logo/GZHOU.png ,响应

图4

5、由于图片服务器为Nginx,设置允许跨域访问,重启Nginx,如图5

在nginx.conf里找到server项,并在里面添加如下配置:
add_header Access-Control-Allow-Origin *;

由于图片服务器为Nginx,设置允许跨域访问,重启Nginx

图5

6、再次访问:http://backend.kaiqiu_shujujiexi_api.dev/team_logo/GZHOU.png ,响应如图6

再次访问:http://backend.kaiqiu_shujujiexi_api.dev/team_logo/GZHOU.png ,响应

图6

7、js的截图代码中添加2行:allowTaint: true, useCORS: true,如图7

js的截图代码中添加1行:useCORS: true

图7

8、截图成功,html2canvas 在跨二级域名下的无法截图的问题得到解决,如图8

截图成功,html2canvas 在跨二级域名下的无法截图的问题得到解决

图8

9、此种解决方案,即使是跨顶级域名也是支持的,如图9

此种解决方案,即使是跨顶级域名也是支持的

图9

 

]]>
https://www.shuijingwanwq.com/2017/05/24/1634/feed/ 0
基于jQuery Validation Plugin,国家区号与手机的同步验证,在登录处的实现流程 https://www.shuijingwanwq.com/2016/07/20/1149/ https://www.shuijingwanwq.com/2016/07/20/1149/#respond Wed, 20 Jul 2016 03:20:21 +0000 http://www.shuijingwanwq.com/?p=1149 Post Views: 106

1、手机动态码登录,jQuery Validation Plugin验证规则,如图1:

手机动态码登录,jQuery Validation Plugin验证规则

手机动态码登录,jQuery Validation Plugin验证规则

2、先输入一个已经注册的台湾手机号码,由于国家区号为中国大陆,因此提示:海外手机请设置国家区号,如图2:

先输入一个已经注册的台湾手机号码,由于国家区号为中国大陆,因此提示:海外手机请设置国家区号

先输入一个已经注册的台湾手机号码,由于国家区号为中国大陆,因此提示:海外手机请设置国家区号

3、国家区号切换至台湾,国家区号的远程验证返回true,但是手机号码文本框仍然报错,如图3:

国家区号切换至台湾,国家区号的远程验证返回true,但是手机号码文本框仍然报错

国家区号切换至台湾,国家区号的远程验证返回true,但是手机号码文本框仍然报错

4、此时要想手机号码验证通过,则不得不先修改成另外一个值,然后再修改回来,连续两次远程验证,才能够验证通过,如图4、5:

图4

此时要想手机号码验证通过,则不得不先修改成另外一个值,然后再修改回来,连续两次远程验证,才能够验证通过

此时要想手机号码验证通过,则不得不先修改成另外一个值,然后再修改回来,连续两次远程验证,才能够验证通过

图5

5、国家区号切换至中国大陆,此时返回错误,如图6:

国家区号切换至中国大陆,此时返回错误

图6

6、输入一个已经注册的中国大陆手机号码,手机号码的远程验证返回true,但是国家区号仍然报错,如图7:

输入一个已经注册的中国大陆手机号码,手机号码的远程验证返回true,但是国家区号仍然报错

图7

7、现在便是需要解决上述问题,需要做到国家区号与手机的同步验证,先解决如图5之前所遇见的问题,当请求完成之后调用函数,国家区号的远程验证返回true,但是手机号码文本框仍然报错,则再次远程验证一次手机号码,代码如图8:

现在便是需要解决上述问题,需要做到国家区号与手机的同步验证,先解决如图5之前所遇见的问题,当请求完成之后调用函数,国家区号的远程验证返回true,但是手机号码文本框仍然报错,则再次远程验证一次手机号码

图8

8、发现并未执行手机号码的远程验证,如图9:

发现并未执行手机号码的远程验证

图9

9、打开网址:https://github.com/jzaefferer/jquery-validation ,下载jquery-validation的1.11.1版本,因为当前网页所使用的便是此版本,如图10、11:

打开网址:https://github.com/jzaefferer/jquery-validation ,下载jquery-validation的1.11.1版本,因为当前网页所使用的便是此版本

图10

打开网址:https://github.com/jzaefferer/jquery-validation ,下载jquery-validation的1.11.1版本,因为当前网页所使用的便是此版本

图11

10、解压缩之后,复制jquery.validate.js至网站资源对应目录,如图12、13:

解压缩之后,复制jquery.validate.js至网站资源对应目录

图12

解压缩之后,复制jquery.validate.js至网站资源对应目录

图13

11、网页源代码中,将引入jquery.validation.min.js先给注释,引入jquery.validate.js,以方便开发期间调试,如图14:

网页源代码中,将引入jquery.validation.min.js先给注释,引入jquery.validate.js,以方便开发期间调试

图14

12、在element方法中,插入console.log(element);如图15:

在element方法中,插入console.log(element);

图15

13、继续执行第2、3步,查看Console,可以确定已经执行至element(即执行手机号码的再次验证),如图16:

继续执行第2、3步,查看Console,可以确定已经执行至element(即执行手机号码的再次验证)

图16

14、在element方法中,插入console.log(result);如图17:

在element方法中,插入console.log(result);

图17

15、继续执行第2、3步,查看Console,可以确定当result为false的时候,则手机号码的远程验证没有执行,如图18:

继续执行第2、3步,查看Console,可以确定当result为false的时候,则手机号码的远程验证没有执行

图18

16、在check方法中,插入console.log(method);console.log(result);如图19:

在check方法中,插入console.log(method);console.log(result);

图19

17、继续执行第2、3步,查看Console,可以确定当执行手机号码的remote的检测的时候,因为返回false,所以手机号码的远程验证没有执行,如图20:

继续执行第2、3步,查看Console,可以确定当执行手机号码的remote的检测的时候,因为返回false,所以手机号码的远程验证没有执行

图20

18、在内置验证方法methods列表的remote中,插入console.log(value);console.log(previous);如图21:

在内置验证方法methods列表的remote中,插入console.log(value);console.log(previous);

图21

19、继续执行第2、3步,查看Console,可以确定当执行手机号码的远程验证的时候,因为value值与previous.old完全相等,所以返回false,进而导致手机号码的远程验证没有执行,如图22:

继续执行第2、3步,查看Console,可以确定当执行手机号码的远程验证的时候,因为value值与previous.old完全相等,所以返回false,进而导致手机号码的远程验证没有执行

图22

20、在验证器方法previousValue中,如果当前元素的previousValue(即以前的值)存在,则返回以前的值,否则返回空值,如图23:

在验证器方法previousValue中,如果当前元素的previousValue(即以前的值)存在,则返回以前的值,否则返回空值

图23

21、结合在验证器方法resetForm中获取的分析,如果#phone的以前的值与现在即将远程验证的值相等,而又必须要再次执行远程验证的话,只需要将以前的值清除掉即可,如图24、25:

结合在验证器方法resetForm中获取的分析,如果#phone的以前的值与现在即将远程验证的值相等,而又必须要再次执行远程验证的话,只需要将以前的值清除掉即可

图24

结合在验证器方法resetForm中获取的分析,如果#phone的以前的值与现在即将远程验证的值相等,而又必须要再次执行远程验证的话,只需要将以前的值清除掉即可

图25

22、继续执行第2、3步,查看Network,远程验证手机号码成功执行,如图26:

继续执行第2、3步,查看Network,远程验证手机号码成功执行

图26

23、在phone处,如出一辙,只是当手机号码远程验证返回true而国家区号有错误的时候,则清除掉国家区号以前的值,再次执行国家区号的远程验证,如图27:

在phone处,如出一辙,只是当手机号码远程验证返回true而国家区号有错误的时候,则清除掉国家区号以前的值,再次执行国家区号的远程验证

图27

24、继续执行第5、6步,查看Network,远程验证国家区号成功执行,如图28:

继续执行第5、6步,查看Network,远程验证国家区号成功执行

图28

25、网页源代码中,将第11步还原,如图29:

网页源代码中,将第11步还原

图29

总结:如果在js框架的使用手册中无法找到满足相关需求的api,则需要自行去下载相应的未经压缩的源代码,进行阅读分析才行了;

]]>
https://www.shuijingwanwq.com/2016/07/20/1149/feed/ 0
在JavaScript中实现PHP数组的调用! https://www.shuijingwanwq.com/2014/02/10/188/ https://www.shuijingwanwq.com/2014/02/10/188/#respond Mon, 10 Feb 2014 02:04:31 +0000 http://www.shuijingwanwq.com/?p=188 Post Views: 84

由于需要在JavaScript中判断某一值是否存在于此PHP数组中,因此需要将此PHP数组传入JavaScript中!

通过使用json_encode — 对变量进行 JSON 编码,可以实现此效果!

通过使用json_encode — 对变量进行 JSON 编码

通过使用json_encode — 对变量进行 JSON 编码

 

最后通过 $.inArray(item.gid, js_goods_ids) == -1 来判断此JS变量值是否存在于此数组中的!

]]>
https://www.shuijingwanwq.com/2014/02/10/188/feed/ 0
在jquery中对于由脚本创建的新元素不能够执行事件处理程序的解决! https://www.shuijingwanwq.com/2014/01/02/150/ https://www.shuijingwanwq.com/2014/01/02/150/#respond Thu, 02 Jan 2014 08:15:23 +0000 http://www.shuijingwanwq.com/?p=150 Post Views: 81

选择是的时候,新建元素未弹出信息输入框!

选择是的时候,新建元素未弹出信息输入框!

选择是的时候,新建元素已经可以弹出信息输入框!

选择是的时候,新建元素已经可以弹出信息输入框!

html结构:

<td><span id="is_mar431"><input class="is_mar" value="0" id="is_mar431_0" checked="checked" type="radio" name="is_mar431" /> <label for="is_mar431_0">否</label>&nbsp;<input class="is_mar" value="1" id="is_mar431_1" type="radio" name="is_mar431" /> <label for="is_mar431_1">是</label></span></td>

js结构(前):

    // 是否损坏,选择是,显示损坏信息输入文本框
    $("span[id^=is_mar] :radio").change( function() {
        var this_name = $(this).attr("name");
        var input_id = 'mar_note_'+this_name.substring(6);
        if ($("input[name="+this_name+"]:checked").val() == 1) {
            $("#"+this_name+"").after('<span id="J_'+input_id+'">&nbsp;损坏信息:<input id="'+input_id+'" type="text" tabindex="3" name="'+input_id+'" value="" /></span>');
        } else {
            $("#J_"+input_id+"").remove();
        }
    });

js结构(后):

    // 是否损坏,选择是,显示损坏信息输入文本框
    $("span[id^=is_mar] :radio").live("change",function() {
        var this_name = $(this).attr("name");
        var input_id = 'mar_note_'+this_name.substring(6);
        if ($("input[name="+this_name+"]:checked").val() == 1) {
            $("#"+this_name+"").after('<span id="J_'+input_id+'">&nbsp;损坏信息:<input id="'+input_id+'" type="text" tabindex="3" name="'+input_id+'" value="" /></span>');
        } else {
            $("#J_"+input_id+"").remove();
        }
    });

参考live的网址:http://www.w3school.com.cn/jquery/event_live.asp
]]>
https://www.shuijingwanwq.com/2014/01/02/150/feed/ 0
jquery each 函数中的变量返回的问题!外部调用! https://www.shuijingwanwq.com/2013/12/30/146/ https://www.shuijingwanwq.com/2013/12/30/146/#respond Mon, 30 Dec 2013 05:47:14 +0000 http://www.shuijingwanwq.com/?p=146 Post Views: 56

前端交互界面!

前端交互界面!

 

变化数量的源代码

变化数量的源代码

现在的需求是判断换货商品的变化数量是否全部为0,如果全部为0的话,需要弹出提示框,并拒绝提交!

javascript:

// 遍历商品变化数量,如果全部为0,则不提交
var sub = 0;
$(“.goods_number”).each(function () {
if (sub == 0) {
if ($(this).val() != 0) {
// var sub == 1;
return (sub = 1);
// return false;
} else {
return true;
}
} else {
return false;
}
})
if (sub == 0) {
alert(‘换货的商品变化数量不能够全部为0’);
return false;
}

发现在函数内部的变量赋值是传递不到后续中去的,需要返回才行了的,可以返回多个值了的!

现在唯一的问题便是即使判断出了有一个变化数量的值不为0的话,还会继续循环一次的,不然sub的值无法在后续判断中使用!

 

]]>
https://www.shuijingwanwq.com/2013/12/30/146/feed/ 0
jquery UI的Datepicker增加具体时间的实现! https://www.shuijingwanwq.com/2013/11/19/132/ https://www.shuijingwanwq.com/2013/11/19/132/#respond Tue, 19 Nov 2013 06:01:37 +0000 http://www.shuijingwanwq.com/?p=132 Post Views: 57

默认的实现如下,需求是需要可以选择小时、分钟及秒数

默认的实现如下,需求是需要可以选择小时、分钟及秒数

现在需要对于Datepicker进行扩展,在:

https://github.com/trentrichardson/jQuery-Timepicker-Addon 上有支持此扩展的插件;

实现后效果如下:

jQuery-Timepicker-Addon

jQuery-Timepicker-Addon

现在默认为英语界面,扩展出来的功能,需要将其设为中文的,需要插入语言设置文件:

jQuery-Timepicker-Addon及语言设置文件

jQuery-Timepicker-Addon及语言设置文件

结果如下:

jQuery-Timepicker-Addon最终实现

jQuery-Timepicker-Addon最终实现

]]>
https://www.shuijingwanwq.com/2013/11/19/132/feed/ 0