AC-论坛悬浮回复框

常用论坛的悬浮回复框,点击固定,再次点击缩回

  1. // ==UserScript==
  2. // @name AC-论坛悬浮回复框
  3. // @description 常用论坛的悬浮回复框,点击固定,再次点击缩回
  4. // @namespace K
  5. // @include *
  6. // @version 2.7
  7. // @note 反馈地址 http://bbs.kafan.cn/thread-2076136-1-1.html
  8. // @note V2.7 忘了关闭按键事件的LOG
  9. // @note V2.6 更新-修改为仅图标触发展开关闭效果,页面中点击不关闭输入框,避免误操作,输入框中输入内容不影响 & 新增Esc键关闭输入框
  10. // @note V2.5 依据建议,替换为https的默认图片
  11. // @note V2.4 修复回复框右键导致的设置框弹出,同时修改左右和上下位置调整
  12. // @note V2.3 修复鼠标移开的悬浮框显示问题
  13. // @note V2.2 根据图标和图标位置动态调整悬浮框的宽度
  14. // @note V2.1 新增,鼠标移动到图标上显示悬浮框
  15. // @note V2.0 修改为图标触发效果,支持自定义图标,左键(展开-关闭); 右键(设置界面)
  16. // @icon https://coding.net/u/zb227/p/zbImg/git/raw/master/img0/icon.jpg
  17. // @run-at document-end
  18. // @grant GM_registerMenuCommand
  19. // @grant GM_getValue
  20. // @grant GM_setValue
  21. // ==/UserScript==
  22. !function(){
  23. var imgWidth = parseInt(GM_getValue("check_mWidth", 50)); //图标宽度
  24. var imgHeight = parseInt(GM_getValue("check_mHeight", 50)); //图标高度
  25. let defaultX = 400;
  26. try{defaultX = (document.body.offsetWidth - document.querySelector("#wp").offsetWidth) / 2 + 10}catch (e) {}
  27. var imgAtX = parseInt(GM_getValue("check_mAtX", defaultX)); //图标距离左边或者右边的距离
  28. var imgAtY = parseInt(GM_getValue("check_mAtY", -40)); //图标距离顶部或底部的距离
  29. var imgUrl = GM_getValue("check_mUrl", "https://a.ikafan.com/image/smiley/default/14.gif"); // 图标地址
  30. var configForm; // 设置界面
  31.  
  32. /***打开设置页面的函数***/
  33. function showConfigFlashRpy () {
  34. configForm = document.createElement("div");
  35. configForm.className = "acConfigSetRpy";
  36. document.body.appendChild(configForm);
  37. configForm.style = "width: 520px; font-size: 14px; position: fixed; color: rgb(0, 0, 0); z-index: 99; box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); border: 1px solid rgb(204, 204, 204); background: rgba(255, 255, 255, 0.9) none repeat scroll 0% 0%; border-top-right-radius: 2px; border-bottom-left-radius: 2px; padding: 10px; left: 0px; right: 0px; top: 0px; bottom: 0px; margin: auto; height: 290px; max-height: 90%; overflow: auto; text-align: center; -moz-user-select: none;";
  38. configForm.appendChild(createTextNode("透明图片请用PNG或者GIF格式, 保存之后刷新页面即可", 1));
  39. configForm.appendChild(createTextNode("图标的地址:"));
  40. var check_mUrl = configForm.appendChild(createInputNode(imgUrl)).firstChild;
  41. configForm.appendChild(createTextNode("图标距两边的距离[左正右负]:"));
  42. var check_mAtX = configForm.appendChild(createInputNode(imgAtX)).firstChild;
  43. configForm.appendChild(createTextNode("图标距上下的距离[上正下负]:"));
  44. var check_mAtY = configForm.appendChild(createInputNode(imgAtY)).firstChild;
  45. configForm.appendChild(createTextNode("图标宽度:"));
  46. var check_mWidth = configForm.appendChild(createInputNode(imgWidth)).firstChild;
  47. configForm.appendChild(createTextNode("图标高度:"));
  48. var check_mHeight = configForm.appendChild(createInputNode(imgHeight)).firstChild;
  49. var check_mSave = configForm.appendChild(createButtonNode("保存"));
  50. var check_mCancel = configForm.appendChild(createButtonNode("取消"));
  51. check_mSave.onclick = function(){
  52. //检查属性是否符合规则
  53. if(check_mUrl.value.indexOf("http") != 0){
  54. alert("地址不规范");
  55. }else if(/^\d+$/.test(check_mAtX) || /^\d+$/.test(check_mAtY) || /^\d+$/.test(check_mWidth) || /^\d+$/.test(check_mHeight)){
  56. alert("请输入整数");
  57. }
  58. //使用保存数据的功能
  59. GM_setValue("check_mUrl", check_mUrl.value);
  60. GM_setValue("check_mAtX", check_mAtX.value);
  61. GM_setValue("check_mAtY", check_mAtY.value);
  62. GM_setValue("check_mWidth", check_mWidth.value);
  63. GM_setValue("check_mHeight", check_mHeight.value);
  64. configForm.remove();
  65. location.reload();
  66. }
  67. check_mCancel.onclick = function(){
  68. configForm.remove();
  69. }
  70. //configForm.innerHTML = "<form action=\"#\" ><center><table><tbody><tr><td>图片地址:</td><td><input value=\"xxx\"></td></tr><tr><td>图片靠左边距离:</td><td><input value=\"10\"></td></tr><tr><td>图片宽度</td><td><input value=\"10\"></td></tr><tr><td>图片高度:</td><td><input value=\"10\"></td></tr> </tbody></table><input value=\"save\" type=\"submit\"><input value=\"cancel\" type=\"button\"></center>";
  71. }
  72. /***设置页面用:新增按钮方法***/
  73. function createButtonNode(text){
  74. var inputDiv = document.createElement("div");
  75. inputDiv.style = "width: 100px; text-align: center; display: inline-block;margin-bottom:10px;margin-right:10px";
  76. var inputBox = document.createElement("input");
  77. inputBox.type = "button";
  78. inputBox.value = text;
  79. inputBox.style = "width: 100px; text-align: center; display: inline-block;";
  80. inputDiv.appendChild(inputBox);
  81. return inputDiv;
  82. }
  83. /***设置页面用:新增输入框方法***/
  84. function createInputNode(text){
  85. var inputDiv = document.createElement("div");
  86. inputDiv.style = "width: 300px; text-align: center; display: inline-block;margin-bottom:20px";
  87. var inputBox = document.createElement("input");
  88. inputBox.value = text;
  89. inputBox.onkeyup = "this.value=this.value.replace(/\D/g,'')";
  90. inputBox.onafterpaste = "this.value=this.value.replace(/\D/g,'')";
  91. inputBox.style = "width: 300px; text-align: left; display: inline-block;";
  92. inputDiv.appendChild(inputBox);
  93. return inputDiv;
  94. }
  95. /***设置页面用:新增文本方法***/
  96. function createTextNode(text, flag){
  97. var inputDiv = document.createElement("div");
  98. inputDiv.style = "width: 200px; text-align: center; display: inline-block; margin-bottom:20px";
  99. if(flag != null) inputDiv.style = "width: 500px; text-align: center; margin-bottom:20px";
  100. var inputBox = document.createElement("div");
  101. inputBox.style = "width: 200px; text-align: left; display: inline-block;";
  102. if(flag != null) inputBox.style = "width: 500px; text-align: center; margin-bottom:20px";
  103. inputBox.innerHTML = text;
  104. inputDiv.appendChild(inputBox);
  105. return inputDiv;
  106. }
  107. GM_registerMenuCommand("设置论坛回复悬浮窗属性", showConfigFlashRpy);
  108. /***右下角图标按钮生成函数***/
  109. function addBtn(nodeName){
  110. var node = document.querySelector(nodeName); // 目标元素节点
  111. if(node == null) return;
  112. // 隐藏原始回复框
  113. node.style.display = "none";
  114. // 处理表单,表单提交则点击自身,隐藏回复框
  115. var formNode = document.querySelector(nodeName+" form"); // "#f_pst form"
  116. if(formNode != null)
  117. formNode.setAttribute("onsubmit", formNode.getAttribute("onsubmit")+",this.click()");
  118. // 在父节点中插入按钮节点,并设置按钮style
  119. var fatherNode = node.parentNode;
  120. var insNode = document.createElement("div");
  121. insNode.className = "frep_btn";
  122. var deltaTextY = (imgAtY>=0?"top:":"bottom:")+Math.abs(imgAtY) + "px !important;";
  123. var deltaTextX = (imgAtX>=0?"left:":"right:")+Math.abs(imgAtX) + "px !important;";
  124. var percentage = parseInt(100*(document.body.clientWidth-2*Math.abs(imgAtX)-2*imgWidth)/document.body.clientWidth);
  125. console.log(deltaTextX);
  126. insNode.style = "width:"+imgWidth+"px !important;height:"+imgHeight+"px !important;background-image: url('"+imgUrl+"'); background-repeat: no-repeat; background-size: 100% 100%;position: fixed;z-index: 99 !important;border: 1px solid #2B5782 !important;overflow: hidden;transition-duration: 0.2s !important;transition-delay: 0.3s !important;"+deltaTextY+deltaTextX;
  127. insNode.style.after = "content:\"\"; display:block; padding-bottom:20%;";
  128. insNode.setAttribute("expand", "0");
  129. fatherNode.insertBefore(insNode, fatherNode.firstChild);
  130. node.setAttribute("expand", "0");
  131. node.expand = function(){
  132. console.log("展开");
  133. var posTextX = (imgAtX>=0?"left:":"right:")+(imgWidth+Math.abs(imgAtX)+1) +"px !important;";
  134. node.style = "border:1px solid #2B5782 !important;position:fixed;bottom:-11px !important;z-index:99 !important;bottom:-5px !important;height:auto !important;width:"+percentage+"% !important;overflow:hidden;transition-delay:0.1s !important; background:#fcfcfc;"+posTextX;
  135. node.setAttribute("expand", "1");
  136. insNode.setAttribute("expand", "1");
  137. node.style.display = "unset";
  138. };
  139. node.collapse = function(){
  140. console.log("收回");
  141. node.setAttribute("expand", "0");
  142. insNode.setAttribute("expand", "0");
  143. node.style.display = "none";
  144. };
  145. node.onclick = function expandView(sender){
  146. /***左键为展开和关闭效果; 右键为设置页面-单一页面,禁止多个***/
  147. var target = sender.sourceTarget || sender.target;
  148. if(sender.button == 0){
  149. //左键展开===关闭
  150. //console.log(sender);
  151. //console.log(sender.target);
  152. //console.log(sender.target.nodeName);
  153. if(target.getAttribute("expand") == "0"){//未展开--->展开
  154. node.expand();
  155. } else if(target.getAttribute("expand") == "1"){
  156. node.collapse();
  157. } else{
  158. // console.log("不予触发");
  159. }
  160. }else{
  161. //右键设置模式
  162. if(target.className == "frep_btn"){
  163. if(document.querySelector(".acConfigSetRpy")==null){
  164. showConfigFlashRpy();
  165. }else{
  166. configForm.remove();
  167. }
  168. }
  169. }
  170. };
  171. insNode.onmouseover = node.onmouseover = function(){
  172. if(node.getAttribute("expand") == "0") {
  173. var posTextX = (imgAtX>=0?"left:":"right:")+(imgWidth+Math.abs(imgAtX)+1) +"px !important;";
  174. node.style = "border:1px solid #2B5782 !important;position:fixed;bottom:-11px !important;z-index:99 !important;bottom:-5px !important;height:auto !important;width:"+percentage+"% !important;overflow:hidden;transition-delay:0.1s !important; background:#fcfcfc;" + posTextX;
  175. node.style.display = "unset";
  176. }
  177. };
  178. insNode.onmouseout = node.onmouseout = function(){
  179. if(node.getAttribute("expand") == "0")
  180. node.style.display = "none";
  181. };
  182. insNode.onmousedown = node.onclick;
  183. /***在右下角按钮上禁止右键弹出菜单***/
  184. /***右键为设置页面-单一;左键为展开和关闭效果***/
  185. insNode.oncontextmenu = function(){return false;};
  186. return {node:node, insNode:insNode};
  187. }
  188. var addBtnList = new Array(
  189. addBtn("#anchor"),
  190. addBtn("#quickpost"),
  191. addBtn("#f_pst"),
  192. addBtn("#f_post"),
  193. addBtn("#fast_post_c"),
  194. addBtn("form[action=\"post.php?\"][method=\"post\"] > .t5")
  195. );
  196. // 如果是ESC键的话,那么关闭输入框
  197. document.addEventListener("keydown", function(env){
  198. if(env.key == 27 || env.keyCode == 27){
  199. try{
  200. for(let i = 0; i < addBtnList.length; i++){
  201. let per = addBtnList[i];
  202. if(typeof(per) != "undefined") per.node.collapse();
  203. }
  204. }catch (e) {
  205. }
  206. }
  207. });
  208. }();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址