素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: twitter: @javascripter にどうぞ。

ブックマークレットとユーザーCSSの連携(クリックした要素のCSSセレクタを作っていらない要素を削除する)

ユーザーCSSで広告などを削除するとき用のブックマークレット

javascript:var textarea=document.body.appendChild(document.createElement('textarea')),s=[];with(textarea.style){position='fixed';top='0px';right='0px';width='10em';height='10em';zIndex='99';} document.addEventListener('click',function(e){if (e.target==textarea)return; e.target.style.display='none';s.push(getSelectorByElement(e.target));textarea.value='@namespace url(http://www.w3.org/1999/xhtml);\n\n@-moz-document url("'+location.href+'"){\n\n}\n\n'+s.join(',\n')+'\n{\n  display:none !important;\n}';e.stopPropagation();e.preventDefault();},false);function getSelectorByElement(target){var s = [];(function(elem) {var parent = elem.parentNode;var tagName = elem.tagName.toLowerCase();if(elem.hasAttribute('id')){s.unshift('#'+elem.id);return;}if(elem.hasAttribute('class')){var className=elem.className.split(' ').map(function(i)'.'+i).join('');if(!parent||Array.every(childs,function(child)child.className!=elem.className)){s.unshift(className);}else if(parent){var childs=parent.childNodes;var elems=parent.getElementsByClassName(elem.className);var n=Array.indexOf(elems,elem)+1;if (elems.length==1){s.unshift(className);}else if (n==1){s.unshift(className+':first-of-type');}else if(n>elems.length){s.unshift(className+':last-of-type');}else{          s.unshift(className+':nth-of-type('+n+')');}}}else if(parent){var childs=parent.childNodes;var elems=parent.getElementsByTagName(tagName);var n=Array.indexOf(elems,elem)+1;if(elems.length==1){s.unshift(tagName);}else if(n==1){  s.unshift(tagName+':first-of-type');}else if(n>elems.length) {s.unshift(tagName+':last-of-type');}else{s.unshift(tagName+':nth-of-type('+n+')');}}if(parent!=document){arguments.callee(parent);}})(target);return s.join('>');}

CSSセレクタを作っている関数は、

function getSelectorByElement(target) {
  var s = [];
  (function(elem) {
    var parent = elem.parentNode;
    var tagName = elem.tagName.toLowerCase();
    if (elem.hasAttribute('id')) {
      s.unshift('#' + elem.id);
      return;
    }
    if (elem.hasAttribute('class')) {
      var className = elem.className.split(' ').map(function(i)'.' + i).join('');
      if (!parent || Array.every(childs,
      function(child) child.className != elem.className)) {
        s.unshift(className);
      } else if (parent) {
        var childs = parent.childNodes;
        var elems = parent.getElementsByClassName(elem.className);
        var n = Array.indexOf(elems, elem) + 1;
        if (elems.length == 1) {
          s.unshift(className);
        } else if (n == 1) {
          s.unshift(className + ':first-of-type');
        } else if (n > elems.length) {
          s.unshift(className + ':last-of-type');
        } else {
          s.unshift(className + ':nth-of-type(' + n + ')');
        }
      }
    } else if (parent) {
      var childs = parent.childNodes;
      var elems = parent.getElementsByTagName(tagName);
      var n = Array.indexOf(elems, elem) + 1;
      if (elems.length == 1) {
        s.unshift(tagName);
      } else if (n == 1) {
        s.unshift(tagName + ':first-of-type');
      } else if (n > elems.length) {
        s.unshift(tagName + ':last-of-type');
      } else {
        s.unshift(tagName + ':nth-of-type(' + n + ')');
      }
    }
    if (parent != document) {
      arguments.callee(parent);
    }
  })(target);
  return s.join('>');
}

で、:nth-of-type(n)などを使っているので、Firefox3.1以上でないと動かない。