2014年4月28日 星期一

[JavaScript] Get Links!

2014/4/28 更新 加入了點擊遮罩,以及按Tab選取的功能
加上了一些新功能,現在可以直接拖曳選取連結了。

當連結的中心點在框內時就會被選取。下面給source

Bookmark: Get Links!

function linky(){
    "use strict";
    if(!window.eight04_linky){
        window.eight04_linky = (function(){
        
            // enable, use by switcher below
            var enable = false;

            // draw gui
            var style=document.createElement("style");
            style.innerHTML=".linky{ outline: 2px solid blue; }"+
                ".lsbox{border: 2px dashed red; position: absolute; display: none; z-index: 65534;}"+
                "#linkingbox{border: 3px solid black; padding: 6px; position: fixed; top: 4px; left: 4px;}"+
                "#linkingbox{height: 300px; width: 180px; background: white; z-index: 65535; display:none;}"+
                ".deselect {-moz-user-select: none; user-select: none}" +
                "#linkingbox.linkingbox-corner {top: auto; left: auto; right: 4px; bottom: 4px;}" +
                ".cover {position: absolute; top: 0; left: 0; z-index: 65533;}";                "";
            document.getElementsByTagName("head")[0].appendChild(style);
            
            var body = document.querySelector("body");
            body.classList.add("deselect");
            var sbox=document.createElement("div");
            sbox.className="lsbox";
            var linkingbox=document.createElement("textarea");  
            linkingbox.setAttribute("id","linkingbox");  
            linkingbox.onmouseover=function(){
                console.log(this);
                this.classList.toggle("linkingbox-corner");
            };
            var cover = document.createElement("div");
            cover.className = "cover";
            var html = document.querySelector("html");
            cover.style = "width: " + html.scrollWidth + "px; height: " + html.scrollHeight + "px;";
            
            body.appendChild(sbox);
            body.appendChild(linkingbox);
            body.appendChild(cover);

            // link tracker
            var pos=[0,0];
            var pos2=[0,0];
            var linkTracker = (function(){
                var id=0,
                    t,
                    selected = [];
                
                function trackerLoop(){
                    // make links blue border
                    
                    var i;
                    
                    clean();
                    selected = takelinks(pos, pos2);
                    for(i=0;i<selected.length;i++){
                        selected[i].classList.add("linky");
                    }
                }
                
                function takelinks(p,p2){
                    p = p.slice();
                    p2 = p2.slice();
                    var t;
                    if(p[0]>p2[0]){
                        t=p[0]; p[0]=p2[0]; p2[0]=t;
                    }
                    if(p[1]>p2[1]){
                        t=p[1]; p[1]=p2[1]; p2[1]=t;
                    }
                    
                    var a=document.getElementsByTagName("a");
                    var aQ=[];
                    for(var i=0;i<a.length;i++){
                        var pa=offset(a[i]);
                        pa=[pa[0]+Math.floor(a[i].offsetWidth/2),pa[1]+Math.floor(a[i].offsetHeight/2)];
                        if(p[0]<pa[0] && pa[0]<p2[0] && p[1]<pa[1] && pa[1]<p2[1])
                            aQ.push(a[i]);
                    }

                    return aQ;
                }
                
                function clean(){
                    var i;
                    for(i = 0; i < selected.length; i++){
                        selected[i].classList.remove("linky");
                    }
                    selected = [];
                }
                
                return {
                    on: function(){
                        id = window.setInterval(trackerLoop, 300);
                    },
                    off: function(){
                        window.clearInterval(id);
                    },
                    get: function(){
                        var a = [],
                            i;
                        for(i = 0; i < selected.length; i++){
                            a.push(selected[i].href);
                        }
                        clean();
                        return a;
                    }
                };
            })();

            var selecting = false;
            function mshandler(e){
                if(e.type=="mousedown"){
                    pos=[e.pageX,e.pageY];
                    sbox.style.left=e.pageX + "px";
                    sbox.style.top=e.pageY + "px";
                    sbox.style.display="block";
                    linkTracker.on();
                    selecting = true;
                    // e.preventDefault();
                }else if(e.type=="mousemove"){
                    if(!selecting) return;
                    sbox.style.left=(e.pageX<pos[0]?e.pageX:pos[0]) + "px";
                    sbox.style.top=(e.pageY<pos[1]?e.pageY:pos[1]) + "px";
                    sbox.style.width=Math.abs(e.pageX-pos[0]) - 4 + "px";
                    sbox.style.height=Math.abs(e.pageY-pos[1]) - 4 + "px";
                    pos2=[e.pageX,e.pageY];
                }else if(e.type=="mouseup"){
                    selecting = false;
                    linkTracker.off();
                    sbox.style.display="none";
                    sbox.style.width="0";
                    sbox.style.height="0";
                    var aQ=linkTracker.get();
                    if(!aQ.length)return;
                    linkingbox.value=linkingbox.value+aQ.join("\n")+"\n";
                    activeLinkingBox();
                }
                
            }
        
            function offset(o){
                var ol = 0,
                    ot = 0;
                    
                while(o){
                    ol+=o.offsetLeft;
                    ot+=o.offsetTop;
                    o = o.offsetParent;
                }
                
                return [ol,ot];
            }
            
            function activeLinkingBox(){
                linkingbox.focus();
                linkingbox.select();
            }
            
            function keyhandler(event){
                // make tab key focus on linkingbox
                
                console.log(event.keyCode);
                if(event.keyCode != 9){ 
                    return;
                }
                event.preventDefault();
                activeLinkingBox();
            }
            
            return {
                switch: function(){
                    if(!enable){
                        enable = true;
                        document.addEventListener("mousedown",mshandler,false);
                        document.addEventListener("mouseup",mshandler,false);
                        document.addEventListener("mousemove",mshandler,false);
                        document.addEventListener("keypress",keyhandler,false);
                        linkingbox.style.display="block";
                        cover.style.display = "block";
                        body.classList.add("deselect");
                    }else{
                        enable = false;
                        document.removeEventListener("mousedown",mshandler,false);
                        document.removeEventListener("mouseup",mshandler,false);
                        document.removeEventListener("mousemove",mshandler,false);
                        document.removeEventListener("keypress",keyhandler,false);
                        linkingbox.style.display="none";
                        linkingbox.value="";
                        cover.style.display = "none";
                        body.classList.remove("deselect");
                    }
                }
            };
        })();
    }
    
    window.eight04_linky.switch();
}

1 則留言: