ブラウザ画面で、色々なツールを作る際に、選択したエレメントを分かりやすくフォーカスするというツールを作って見ました。
過去に同じ機能で、色々なサービスの管理画面に対応してきたので、今後も便利に使えると思います。
概要
ブラウザ画面で特定の項目(エレメント)を選択(クリック)した時に、対象のエレメントを強調表示したい。
どんな時に使うかと言えば、画面デザインを変更する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などが弱い場合は、各自で値を変更してお使いください。
0 件のコメント:
コメントを投稿