ブラウザ画面内でクリックしたエレメントにフォーカスするスニペット

2018年2月15日

Javascript Tips テクノロジー プログラミング

ブラウザ画面で、色々なツールを作る際に、選択したエレメントを分かりやすくフォーカスするというツールを作って見ました。 過去に同じ機能で、色々なサービスの管理画面に対応してきたので、今後も便利に使えると思います。

概要

ブラウザ画面で特定の項目(エレメント)を選択(クリック)した時に、対象のエレメントを強調表示したい。 どんな時に使うかと言えば、画面デザインを変更するCMSなどのツールで、任意のエレメントを選択して、見た目を変更する時など、対象のエレメント以外が、半透明になったりすると、際立って分かりやすくなると思います。 今回のツールは、周囲を半透明にするのではなく、黒の半透明を周囲に被せて、対象エレメントを分かりやすくするという内容です。

ソースコード

/** * Element-focus * [usage] * 1. Paste the source code in the browser's JS-console. * 2. Click on any element. * 3. Will be focus at element. */ ;(function(){ var $$ = function(){ if(document.readyState === "complete"){ this.start(); } else{ this.setEvent(window , "DOMContentLoaded" , this.start); } }; $$.prototype.start = function(){ $$.prototype.setEvent(window , "click" , $$.prototype.clickWindow); $$.prototype.setCss(); }; $$.prototype.setCss = function(){ var style = document.createElement("style"); style.type = "text/css"; var css = ""; css += ".element-focus{"; css += "position:absolute;"; css += "background-color:black;"; css += "opacity:0.7;"; // css += "pointer-events:none;"; css += "z-index:100000;"; css += "}\n"; css += ".element-focus-top{"; css += "top:0;"; css += "left:0;"; css += "}\n"; css += ".element-focus-bottom{"; css += "left:0;"; css += "}\n"; css += ".element-focus-left{"; css += "left:0;"; css += "}\n"; css += ".element-focus-right{"; css += "}\n"; css += ".element-focus-left{"; css += "left:0;"; css += "}\n"; css += ".element-focus-right{"; css += "right:0;"; css += "}\n"; style.innerHTML = css; document.getElementsByTagName("head")[0].appendChild(style); }; $$.prototype.clickWindow = function(event){ var target = event.target; // target.style.setProperty("border","1px solid red","important"); var elms = document.getElementsByClassName("element-focus"); console.log(elms.length); if(elms.length >= 1){ $$.prototype.delFocus(); } else{ $$.prototype.setFocus(target); } }; $$.prototype.setFocus = function(element){ // Get position of element. var pos = $$.prototype.getElementPosition(element); // Get size of element. var size = $$.prototype.getElementSize(element); // console.log(pos.x+"/"+pos.y+" : "+size.x+"/"+size.y); // set-element $$.prototype.makeElm(pos,size); }; $$.prototype.delFocus = function(element){ var elms = document.getElementsByClassName("element-focus"); for(var i=elms.length-1; i>=0; i--){ elms[i].parentNode.removeChild(elms[i]); } }; // Make arround-element. $$.prototype.makeElm = function(pos,size){ // top var top = document.createElement("div"); top.className = "element-focus element-focus-top"; top.style.setProperty("width" , document.body.scrollWidth + "px","important"); top.style.setProperty("height", pos.y + "px","important"); document.body.appendChild(top); // bottom var bottom = document.createElement("div"); bottom.className = "element-focus element-focus-bottom"; bottom.style.setProperty("top", (pos.y + size.y) + "px","important"); bottom.style.setProperty("width" , document.body.scrollWidth + "px","important"); bottom.style.setProperty("height", (document.body.scrollHeight - pos.y - size.y) + "px","important"); document.body.appendChild(bottom); // left var left = document.createElement("div"); left.className = "element-focus element-focus-bottom"; left.style.setProperty("top" , pos.y + "px","important"); left.style.setProperty("width" , pos.x + "px","important"); left.style.setProperty("height", size.y + "px","important"); document.body.appendChild(left); // right var right = document.createElement("div"); right.className = "element-focus element-focus-bottom"; right.style.setProperty("top" , pos.y + "px","important"); right.style.setProperty("left" , (pos.x + size.x) + "px","important"); right.style.setProperty("width" , (document.body.scrollWidth - pos.x - size.x) + "px","important"); right.style.setProperty("height", size.y + "px","important"); document.body.appendChild(right); }; //element座標; $$.prototype.getElementPosition = function(elm , tgt){ if(typeof tgt === 'undefined' || tgt == null){ tgt = document.body; } //座標算出; var pos = {x:0,y:0}; if(typeof elm === 'undefined' || elm == null){return pos;} var flg=0; do{ if(elm == tgt){break} pos.x += elm.offsetLeft; pos.y += elm.offsetTop; if(flg>10000){break} flg++; } while(elm = elm.offsetParent); return pos; }; //表示elementサイズ(指定がない場合はwindow(body)サイズ); $$.prototype.getElementSize = function(elm){ //対象element if(typeof(elm)=='undefined'){ if (navigator.userAgent.match("MSIE") && document.compatMode!='BackCompat'){ elm = document.documentElement; } else{ elm = document.body; } } //サイズ取得; var size={ x:elm.offsetWidth, y:elm.offsetHeight }; //子階層依存※下に1つのみの子を持つ場合サイズチェックを行う; if(elm.childNodes.length===1 && elm.tagName==='A'){ var chk = { x:elm.childNodes[0].offsetWidth, y:elm.childNodes[0].offsetHeight }; if(chk.x > size.x){ size.x = chk.x; } if(chk.y > size.y){ size.y = chk.y; } } return size; }; $$.prototype.setEvent = function(target, mode, func){ //other Browser if (typeof target.addEventListener !== "undefined"){ target.addEventListener(mode, func, false); } else if(typeof target.attachEvent !== "undefined"){ target.attachEvent('on' + mode, function(){func.call(target , window.event)}); } }; new $$(); })();

使い方

1. 上記ソースコードを全て選択しておいて、ブラウザのJSコンソールに貼り付けてください。 2. ブラウザの任意の項目(エレメント)をクリックした際に、そのエレメント以外が黒くなって、対象項目が目立つように見えます。 これだけ!! そして、Yahooで試した時の画面キャプチャはコレ ちなみに、もう一度クリックすると、フォーカス表示がもとに戻ります。

解説

周囲の黒い半透明は、上下左右の4箇所にdivを設置し、半透明CSSをセットしています。 そして、windowにクリックイベントを仕込んで、クリックされた対象エレメントを取得した時に、そのエレメントの座標とサイズを取得します。 あとは、半透明オブジェクトの4つを、サイズと座標に合わせて、組み合わせるように配置(座標とサイズをセット)するだけです。 さほど難しいことはやっていませんが、意外とフォーカスしたように見えるでしょ? 難しいコーディングをしていないので、かなり古いブラウザでも見えると思いますよ。 でも、今回のチェックはChrome(mac)でしか行っていないので、他のブラウザでエラーが出たら、こっそり教えてください。 ※あと、z-indexなどが弱い場合は、各自で値を変更してお使いください。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。