百度贴吧图片点击放大

直接在当前页面查看图片(包括签名档)原图,支持原图的多开、拖拽、缩放和垂直或水平的滚动

Od 12.04.2017.. Pogledajte najnovija verzija.

  1. // ==UserScript==
  2. // @name 百度贴吧图片点击放大
  3. // @namespace https://greasyfork.org/users/51104
  4. // @version 1.5.11.20170412
  5. // @description 直接在当前页面查看图片(包括签名档)原图,支持原图的多开、拖拽、缩放和垂直或水平的滚动
  6. // @include *://tieba.baidu.com/p/*
  7. // @include *://tieba.baidu.com/f?*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @grant GM_addStyle
  11. // @grant GM_registerMenuCommand
  12. // @author lliwhx
  13. // @copyright Copyright 2016-2017 lliwhx
  14. // @license MIT License
  15. // ==/UserScript==
  16.  
  17. (function(window) {
  18. "use strict";
  19. //CSS
  20. GM_addStyle(".BDE_Image,.j_user_sign{cursor:alias;}#Tie_enlargeImage_parentDIV{position:fixed;z-index:1005;top:0;left:0;}.Tie_enlargeImage{position:absolute;box-shadow:1px 1px 10px #000;cursor:move;}.Tie_enlargeImage:hover{z-index:1006;}#Tie_setValue_DIV{position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;background:rgba(0,0,0,0.5);}.Tie_definedDIV{position:absolute;z-index:10000;background:#fff;top:50%;left:50%;transform:translate(-50%,-50%);}.Tie_definedDIV_title{border-bottom:1px solid #f2f2f5;line-height:40px;font-size:15px;font-weight:700;padding:0 0 0 15px;}.Tie_definedDIV_point{padding:20px 40px;}.Tie_definedDIV_groupSubtitle{font-weight:bold;}.Tie_definedDIV_configItem{line-height:30px;margin:0 20px}.Tie_definedDIV_configItem select{margin:0.5em}.Tie_definedDIV_configItem br+label{margin-left:3em}.Tie_definedDIV_configItem input{vertical-align:middle;margin-right:0.5em}#Tie_debugConfig{margin:0.5em}.Tie_debugConfig_icon{position:relative;display:inline-block;top:4px;width:16px;height:16px;background-position:-350px -100px;background-image:url('https://img.t.sinajs.cn/t6/style/images/common/icon.png');background-repeat:no-repeat;}.Tie_bubble_DIV{position:absolute;visibility:hidden;max-width:280px;top:20%}.Tie_definedDIV_configItem label:hover+.Tie_bubble_DIV{visibility:visible}.Tie_bubble_content{position:relative;background:#fff;padding:6px 13px 6px 16px;border:1px solid #ccc;border-radius:3px;}.Tie_bubble_mainTxt{line-height:18px;}.Tie_bubble_bor{position:absolute;overflow:hidden;bottom:-14px;line-height:14px;}.Tie_bubble_line{border-color:#ccc transparent transparent transparent;}.Tie_bubble_br{margin:-1px 0 0 -14px;border-color:#fff transparent transparent transparent;}.Tie_bubble_bor i,.Tie_bubble_bor em{display:inline-block;width:0;height:0;border-width:7px;border-style:solid;vertical-align:top;overflow:hidden;}.Tie_definedDIV_SaveBtn{background-color:#f2f2f5;text-align:center;padding:10px 0;}.Tie_SaveBtn_a{background:#ff8140;color:#fff;font-size:15px;display:inline-block;padding:0 15px;line-height:35px;border-radius:3px;}.Tie_SaveBtn_a:hover{background:#f7671d}");
  21. //数据缓存
  22. var imageTarget,imageMouse,imageCount,imageButton,winResize,scriptDebug,log = function(){},
  23. mouseWheel = /Firefox/.test(navigator.userAgent)?"DOMMouseScroll":"mousewheel",
  24. protocol = window.location.protocol||"http",
  25. doc = window.document,
  26. docHeight = doc.documentElement.clientHeight-6,
  27. docWidth = doc.documentElement.clientWidth-6,
  28. parentElement = doc.getElementById("j_p_postlist"),
  29. definedEvent = GM_getValue("definedEvent","click,click,1,0,1").split(","),
  30. repairDefinedEvent = GM_getValue("repairDefinedEvent",false),
  31. imageEvent = {
  32. init:function(e){ //主事件
  33. var target = e.target,image,imageSrc;
  34. if(e.button===0&&(target.className==="BDE_Image"||target.className==="j_user_sign")){
  35. log("图片创建","开始");
  36. imageSrc = target.src.match(/(baidu\.com|poco\.cn)\/.+\/(\w+\.[a-zA-Z]{3,4})(?:\?v=tbs){0,2}$/);
  37. log("图片地址获取",function(){if(imageSrc)return "成功";else return "失败";},target.src);
  38. if(!imageSrc) return false;
  39. image = doc.createElement("img");
  40. image.classList.add("Tie_enlargeImage");
  41. image.src = imageSrc[1]==="baidu.com"?protocol + "//imgsrc.baidu.com/forum/pic/item/" + imageSrc[2]:target.src;
  42. image.onerror = function(){
  43. if(protocol==="https:"){
  44. log("图片请求","https转向http");
  45. protocol = "http:";
  46. this.src = "http://imgsrc.baidu.com/forum/pic/item/" + imageSrc[2];
  47. }else{
  48. this.onerror = null;
  49. this.onload = null;
  50. imageSrc = null;
  51. log("图片请求","失败");
  52. alert("图片获取失败\n\n如多次获取失败\n请在设置里勾选“调试脚本”打印脚本日志并截图反馈给作者,以便更好的解决问题");
  53. }
  54. };
  55. image.onload = function(){
  56. log("图片创建","进行中");
  57. var target = this,width = target.width,height = target.height,
  58. Wboolean = width>docWidth,Hboolean = height>docHeight,
  59. X = 6,Y = 6;
  60. target.onerror = null;
  61. target.onload = null;
  62. imageSrc = null;
  63. if(Hboolean&&!Wboolean)X = (docWidth-width)/2;
  64. else if(!Hboolean&&!Wboolean){X = (docWidth-width)/2;Y = (docHeight-height)/2;}
  65. else if(!Hboolean&&Wboolean)Y = (docHeight-height)/2;
  66. target.imageData = {width:width,height:height,X:X,Y:Y}; //缓存当前图片数据
  67. target.style.transform = "translate("+X+"px,"+Y+"px)";
  68. parentDIV.appendChild(target);
  69. log("图片创建",function(){target.id = Date.now();if(doc.getElementById(target.id))return "成功";else return "失败";},target.imageData);
  70. };
  71. image = null;
  72. }
  73. },
  74. StopPropagation:function(e){
  75. if(e.button===0&&e.target.className==="BDE_Image"){
  76. e.stopPropagation(); //阻止冒泡,阻止图片原事件
  77. log("阻止贴吧图片原事件","已执行");
  78. }
  79. },
  80. Down:function(e){
  81. var target = e.target,imageData = target.imageData;
  82. imageTarget = target;
  83. log("鼠标down事件",function(){if(!target.id)target.id = Date.now();return "开始";});
  84. if (e.button!==0)return false;
  85. e.preventDefault();
  86. e.stopPropagation();
  87. imageMouse = [e.clientX,e.clientY];
  88. imageCount = [imageData.X-imageMouse[0],imageData.Y-imageMouse[1],6-imageData.width,6-imageData.height]; //图片宽高的偏移量,图片左右边界预留量
  89. imageButton = true;
  90. doc.addEventListener("mousemove",imageEvent.Move);
  91. doc.addEventListener("mouseup",imageEvent.Up);
  92. log("鼠标down事件","结束");
  93. },
  94. Move:function(e){
  95. log("鼠标move事件","开始");
  96. var target = imageTarget,
  97. X = e.clientX+imageCount[0],
  98. Y = e.clientY+imageCount[1];
  99. imageButton = false;
  100. log("鼠标move事件","进行中","X:"+X+"Y:"+Y);
  101. if(X<imageCount[2]){ //左边界
  102. target.style.transform = "translate("+imageCount[2]+"px,"+Y+"px)";
  103. return false;
  104. }
  105. if(X>docWidth){ //右边界
  106. target.style.transform = "translate("+docWidth+"px,"+Y+"px)";
  107. return false;
  108. }
  109. if(Y<imageCount[3]){ //上边界
  110. target.style.transform = "translate("+X+"px,"+imageCount[3]+"px)";
  111. return false;
  112. }
  113. if(Y>docHeight){ //下边界
  114. target.style.transform = "translate("+X+"px,"+docHeight+"px)";
  115. return false;
  116. }
  117. target.style.transform = "translate("+X+"px,"+Y+"px)";
  118. log("鼠标move事件","结束",target.style.transform);
  119. },
  120. Up:function(e){
  121. log("鼠标up事件","开始");
  122. var target = imageTarget,RegEx;
  123. if(repairDefinedEvent&&e.clientX-imageMouse[0]===0&&e.clientY-imageMouse[1]===0){ //尝试修复关闭图片功能
  124. log("尝试修复关闭图片功能","已执行");
  125. imageButton = true;
  126. }else if(scriptDebug&&!imageButton&&e.clientX-imageMouse[0]===0&&e.clientY-imageMouse[1]===0){
  127. log("鼠标click事件判断","\n一.操作时页面不在激活状态。请保证浏览器正在被操作,在执行一次\n二.关闭图片功能可能损坏,建议修复");
  128. }
  129. if(!imageButton){
  130. RegEx = target.style.transform.match(/[-0-9.]+/g);
  131. target.imageData.X = parseFloat(RegEx[0]);
  132. target.imageData.Y = parseFloat(RegEx[1]);
  133. }
  134. imageTarget = null;
  135. imageMouse = null;
  136. imageCount = null;
  137. doc.removeEventListener("mousemove",imageEvent.Move);
  138. doc.removeEventListener("mouseup",imageEvent.Up);
  139. log("鼠标up事件","结束",imageButton);
  140. },
  141. Close:function(e){
  142. log("鼠标click事件","开始");
  143. var target = e.target;
  144. if(imageButton){
  145. imageButton = null;
  146. delete target.imageData;
  147. parentDIV.removeChild(target);
  148. log("鼠标click事件",function(){if(!doc.getElementById(target.id))return "成功";else return "失败";});
  149. }
  150. },
  151. Wheel:function(e){
  152. var target=e.target,imageData = target.imageData,
  153. wheelKey = definedEvent[3],
  154. width = imageData.width,height = imageData.height,
  155. Wboolean = width>docWidth,Hboolean = height>docHeight,
  156. wheelXY;
  157. log("鼠标wheel事件","开始",imageData);
  158. e.preventDefault();
  159. e.stopPropagation();
  160. if(wheelKey!=="0"){
  161. if((e.ctrlKey&&wheelKey==="1")||(e.altKey&&wheelKey==="2")||(e.shiftKey&&wheelKey==="3")){ //判断图片缩放的组合键
  162. log("鼠标wheel缩放事件","开始");
  163. var eX = e.clientX,eY = e.clientY,
  164. ratioX = (eX-imageData.X)/width,ratioY = (eY-imageData.Y)/height,
  165. wheelRatio = width+(e.wheelDelta||-e.detail*40)*definedEvent[4];
  166. imageData.width = wheelRatio<150?150:wheelRatio;
  167. imageData.height = imageData.width*height/width;
  168. imageData.X = eX-(imageData.width*ratioX);
  169. imageData.Y = eY-(imageData.height*ratioY);
  170. log("鼠标wheel缩放事件","进行中",imageData);
  171. target.width = imageData.width;
  172. target.style.transform = "translate("+imageData.X+"px,"+imageData.Y+"px)"; //基于鼠标位置的缩放
  173. log("鼠标wheel缩放事件","结束",target.style.transform);
  174. return false;
  175. }
  176. }
  177. if(!Hboolean&&!Wboolean){log("鼠标wheel滚动事件","图片小于窗口");return false;}
  178. if(Hboolean){
  179. wheelXY = imageData.Y+(-e.wheelDelta||e.detail*40)*definedEvent[2];
  180. if(wheelXY>0||wheelXY<docHeight-height){
  181. wheelXY = wheelXY>0?6:docHeight-height;
  182. }
  183. imageData.Y = wheelXY;
  184. log("鼠标wheel垂直滚动事件","进行中",wheelXY);
  185. target.style.transform = "translate("+imageData.X+"px,"+wheelXY+"px)";
  186. log("鼠标wheel垂直滚动事件","结束",target.style.transform);
  187. }else if(Wboolean){
  188. wheelXY = imageData.X+(-e.wheelDelta||e.detail*40)*definedEvent[2];
  189. if(wheelXY>0||wheelXY<docWidth-width){
  190. wheelXY = wheelXY>0?6:docWidth-width;
  191. }
  192. imageData.X = wheelXY;
  193. log("鼠标wheel水平滚动事件","进行中",wheelXY);
  194. target.style.transform = "translate("+wheelXY+"px,"+imageData.Y+"px)";
  195. log("鼠标wheel水平滚动事件","结束",target.style.transform);
  196. }
  197. }
  198. };
  199. //创建父DIV
  200. var parentDIV = doc.createElement("div");
  201. parentDIV.id = "Tie_enlargeImage_parentDIV";
  202. doc.body.appendChild(parentDIV);
  203. //事件委托
  204. parentElement.addEventListener("click",imageEvent.StopPropagation,true);
  205. parentElement.addEventListener(definedEvent[0],imageEvent.init,true);
  206. parentDIV.addEventListener("mousedown",imageEvent.Down);
  207. parentDIV.addEventListener(definedEvent[1],imageEvent.Close);
  208. parentDIV.addEventListener(mouseWheel,imageEvent.Wheel);
  209. //释放缓存
  210. parentElement=null;
  211. //自定义设置
  212. var userEvent = {
  213. init:function(){
  214. this.create();
  215. this.Event();
  216. },
  217. create:function(){
  218. var definedDIV = doc.createElement("div"); //创建自定义DIV框架
  219. definedDIV.id = "Tie_setValue_DIV";
  220. definedDIV.innerHTML = "<div class='Tie_definedDIV'><div class='Tie_definedDIV_title'>自定义设置</div><div><div class='Tie_definedDIV_point'><div class='Tie_definedDIV_groupSubtitle'>请保证鼠标在图片上进行操作</div><div class='Tie_definedDIV_configItem'>默认支持鼠标左键拖拽图片</div><div class='Tie_definedDIV_configItem'>查看图片<select name='Tie_setValue'><option value='click'>单击</option><option value='dblclick'>双击</option></select></div><div class='Tie_definedDIV_configItem'>关闭图片<select name='Tie_setValue'><option value='click'>单击</option><option value='dblclick'>双击</option></select><br><label><input id='Tie_repairValue' type='checkbox'>尝试修复关闭图片功能</label></div><div class='Tie_definedDIV_configItem'>滚动图片<select name='Tie_setValue'><option value='1'>滚轮向上,上移/左移</option><option value='-1'>滚轮向下,上移/左移</option></select></div><div class='Tie_definedDIV_configItem'>缩放图片<select name='Tie_setValue'><option value='0'>关闭</option><option value='1'>Ctrl</option><option value='2'>Alt</option><option value='3'>Shift</option></select>+<select name='Tie_setValue'><option value='1'>滚轮向上放大</option><option value='-1'>滚轮向下放大</option></select></div><div class='Tie_definedDIV_configItem'>调试脚本<label><input id='Tie_debugConfig' type='checkbox'><i class='Tie_debugConfig_icon'></i></label><div class='Tie_bubble_DIV'><div class='Tie_bubble_content'><div class='Tie_bubble_mainTxt'>如果您的脚本出现问题,您可以打开调试功能。<strong>在页面进行平常的图片操作,将操作过后在浏览器控制台(快捷键:F12)输出的脚本日志截图反馈给作者</strong>,以便更好的解决问题。<br>注意,<strong>调试功能打开即生效。并且只在当前页面生效一次,刷新或关闭页面都会取消调试功能,需重新打开</strong>。<br>打开调试功能可能会增加内存占用、降低网页的反应速度甚至导致浏览卡顿。仅供维护使用,不建议一般用户打开调试功能。</div><div><span class='Tie_bubble_bor'><i class='Tie_bubble_line'></i><em class='Tie_bubble_br'></em></span></div></div></div></div></div></div><div class='Tie_definedDIV_SaveBtn'><a id='Tie_setValue_a' class='Tie_SaveBtn_a' href='javascript:void(0);'><span>确定</span></a></div></div>";
  221. doc.body.appendChild(definedDIV);
  222. definedDIV = null;
  223. },
  224. Event:function(){
  225. var definedDIV = doc.getElementById("Tie_setValue_DIV"),
  226. repairValue = doc.getElementById("Tie_repairValue"),
  227. debugConfig = doc.getElementById("Tie_debugConfig"),
  228. parentElement = doc.getElementById("j_p_postlist"),
  229. setValue = doc.getElementsByName("Tie_setValue"),
  230. oldDefinedEvent = definedEvent; //备份旧设置
  231. for(var i=0;i<5;i++){
  232. setValue[i].value = oldDefinedEvent[i];
  233. }
  234. if(setValue[3].value==="0")setValue[4].style.visibility = "hidden";
  235. setValue[3].onchange = function(){
  236. setValue[4].style.visibility = this.value==="0"?"hidden":"visible";
  237. };
  238. repairValue.checked = repairDefinedEvent;
  239. debugConfig.checked = scriptDebug;
  240. doc.getElementById("Tie_setValue_a").onclick = function(){
  241. definedEvent = [setValue[0].value,setValue[1].value,setValue[2].value,setValue[3].value,setValue[4].value];
  242. repairDefinedEvent = repairValue.checked;
  243. scriptDebug = debugConfig.checked;
  244. if(oldDefinedEvent[0]!==definedEvent[0]){
  245. parentElement.removeEventListener(oldDefinedEvent[0],imageEvent.init,true);
  246. parentElement.addEventListener(definedEvent[0],imageEvent.init,true);
  247. }
  248. if(oldDefinedEvent[1]!==definedEvent[1]){
  249. parentDIV.removeEventListener(oldDefinedEvent[1],imageEvent.Close);
  250. parentDIV.addEventListener(definedEvent[1],imageEvent.Close);
  251. }
  252. log = scriptDebug&&function(text,types,data){ //脚本调试,日志
  253. if(typeof types==="function"){
  254. types = types();
  255. }
  256. if(data===undefined)console.log(text,types);
  257. else console.log(text,types,data);
  258. }||function(){};
  259. log("自定义属性设置","已执行",definedEvent+","+repairDefinedEvent);
  260. this.onclick = null;
  261. setValue[3].onchange = null;
  262. doc.body.removeChild(definedDIV);
  263. GM_setValue("definedEvent",definedEvent.toString());
  264. GM_setValue("repairDefinedEvent",repairDefinedEvent);
  265. definedDIV = null;repairValue = null;debugConfig = null;parentElement = null;setValue = null;oldDefinedEvent = null;
  266. };
  267. }
  268. };
  269. if(!GM_getValue("definedEvent")){
  270. userEvent.init();
  271. }
  272. GM_registerMenuCommand("自定义设置", function(){
  273. if(!doc.getElementById("Tie_setValue_DIV"))
  274. userEvent.init();
  275. });
  276. window.addEventListener("resize", function(){
  277. if(typeof winResize!==undefined){
  278. clearTimeout(winResize);
  279. }
  280. winResize = setTimeout(function(){
  281. docHeight = doc.documentElement.clientHeight-6;
  282. docWidth = doc.documentElement.clientWidth-6;
  283. },334);
  284. });
  285. })(window);