Element DOM Tree jQuery plugin – Firebug like functionality | RockingCode
Element DOM Tree jQuery plugin – Firebug like functionality | RockingCode
Element DOM Tree jQuery plugin – Firebug like functionality
110Rate this
Have you even seen G+ Feedback page style? It works pretty much like firebug, when you find something working work, you an ordinary user, will point and click which element is buggy so they will know what they need to do.
Here we’ll see a plugin that allows you to do such functionality. It gives you firebug-like selectors but with one really big advantage, it returns the correct element tree, so you’ll know exactly which element is broken. For instance, if you have a bug report on “#content p” you may never know that actually the broken paragraph was the 10th one.
And we’ll learn a little bit about DOM tree and how to get things easily done without messing around with jQuery (when we don’t need it, of course).
Demo & Download
I’ve done a simple test page so you can see how this DOM tree thing works. See the demo or download our sample files so you can easily play and try new things.
DOM tree? What?
No, I’m not talking about this tree.
DOM (Document Object Model) defines a standard way to access and manipulate HTML elements. So window.document means same thing for every browser. It works pretty much like a tree (duh!), where you have parent and children for every element (unless the first and last one, or we’ll enter in an infinite loop).
When you type $(“body”) you are actually saying “Hey jQuery, get this window.document.body element and bring it here in a way that we can manipulate it”. As you can imagine we can actually access and modify things directly via JavaScript, without jQuery. Every “node” stores info about itself and its children, so with a couple of lines we can access precious data about it!
Let’s go through our plugin, now.
HTML & JS
We’ll use jQuery Boilerplate and BootStrap. Both tools help us a lot here, and I think you should be using them
After putting a simple dummy content, we’ll get started with functionality.
Activate & De-activate functions
I think it’s not that good have this thing enabled all the time, so we’ll create a simple button and bind clicks on it:
1<
a
href
=
"#"
id
=
"elemtree"
class
=
"btn"
>Start debugging!</
a
>
12345678<script type=
"text/javascript"
>
$(
function
(){
$(
"#elemtree"
).click(
function
(event){
event.preventDefault();
$(
"#container"
).eltree();
});
});
</script>
Now once plugin is activated all other click functions should be disabled. So what we’ll do is to add this to our plugin file:
123456789101112Plugin.prototype.init =
function
() {
var
obj =
this
.obj,
$
this
=
""
,
debugDiv =
""
,
debugCss =
""
,
debugJS =
""
,
debug =
this
.options.debug;
obj.addClass(
"debugging"
).click(
function
(event){
event.preventDefault();
// so links wont be opened while debugging
});
};
As you may notice we have a couple of variables there. One really important is the “debug”, since it is our debugging panel. It’s default value is:
123defaults = {
debug:
"<div id='eltreeDebug'><span id='eltreeCSSSel'></span><span id='eltreeJSSel'></span><a href='#' class='btn primary' id='eltreeStop'>Stop debugging</a></div>"
};
So, when you call it you create that bigger panel, CSS panel, JS panel and disable button. Disable function will be the easiest one, we’ll just reload page since disabling binds can be bad in some browsers (try enabling / disabling binds 100 times and you’ll know what I’m talking about).
1234//prepare remove functions
$(
"#eltreeStop"
).click(
function
(){
window.location.reload();
// Instead of unbinding everything, just reload page. Now, IE, you can take a deep breath
});
Finding the element’s DOM tree
Now to understand our logic you must to know about 2 DOM accessing functions:
- parentNode – When #content is your current element, for instance, you parentNode is “body”. It goes up one level on DOM tree
- childNodes – Again, if your current element is #content childNodes will be all its children (h2, p, blockquote..). It is an array of elements
Our code logic will be:
- User clicks element
- Loop starts; Condition: current element isn’t window.element
- create a parent var
- check for all child nodes of this parent var, which one is our element
- now if this element has id, store it, otherwise if it has class, store it,otherwise just get his tagname
- element’s parent will be our current element
Ok, let’s translate it to JS and put a few other variables to store values that we’ll need:
12345678910111213141516171819202122232425262728293031323334353637383940414243function
selectors(elem) {
var
css =
""
,
continueCss = 1,
js =
""
,
parent =
""
,
ret =
new
Array();
while
(elem !== window.document) {
parent = elem.parentNode;
//js selector
x=0;
while
( ( $(parent.childNodes[x])[0] !== elem ) && (x < parent.childNodes.length) ) {
x++;
}
//now we have our childNode!
js = x +
","
+ js;
//CSS selector
if
(continueCss) {
if
(elem.id) {
css = elem.nodeName +
'#'
+ elem.id +
" "
+ css;
continueCss = 0;
}
else
if
(elem.className) {
css = elem.nodeName +
'.'
+ elem.className +
" "
+ css;
}
else
{
css = elem.nodeName +
" "
+ css;
}
}
//let's go up one level
elem = elem.parentNode;
}
//let's make our js selector useful
js = (js.slice(0, -1)).split(
","
);
for
(x=0; x< js.length; x++) {
js[x] =
"childNodes["
+ js[x] +
"]"
;
}
js =
"window. document. "
+ js.join(
". "
);
ret[0] = css.toLowerCase();
//css
ret[1] = js;
//js
return
ret;
}
Output function
If you’re planning to use it as a feedback system, it’s these lines that you should change. After we have our selectors this function just display them in our debug panels:
123456function
logThis(elem, css, js ) {
var
sel = selectors(elem);
//if you want to do something else with results (like sending to a feedback plugin) add stuff here
css.text( sel[0] );
js.text( sel[1] );
}
Final result!
This is our final plugin code, check it out:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110/*
* Project: Rocking Element Tree (a.k.a. eltree)
* Description: Adds a firebug-like functionality on page, that gives you element tree and properties by clicking on it
* Author: Rochester Oliveira
* License: GNU General Public License ( http://en.wikipedia.org/wiki/GNU_General_Public_License )
*/
// awesome structure from http://jqueryboilerplate.com/
;(
function
( $, window, document, undefined ) {
// Create the defaults once
var
pluginName =
'eltree'
,
defaults = {
debug:
"<div id='eltreeDebug'><span id='eltreeCSSSel'></span><span id='eltreeJSSel'></span><a href='#' class='btn primary' id='eltreeStop'>Stop debugging</a></div>"
};
// The actual plugin constructor
function
Plugin( element, options ) {
this
.element = element;
this
.options = $.extend( {}, defaults, options) ;
this
._defaults = defaults;
this
._name = pluginName;
this
.obj = $(
this
.element);
this
.init();
}
Plugin.prototype.init =
function
() {
var
obj =
this
.obj,
$
this
=
""
,
debugDiv =
""
,
debugCss =
""
,
debugJS =
""
,
debug =
this
.options.debug;
//add our debugger box and cache
debugDiv = $(debug).appendTo($(
"body"
));
debugCss = debugDiv.children(
"#eltreeCSSSel"
);
debugJS = debugDiv.children(
"#eltreeJSSel"
);
//prepare remove functions
$(
"#eltreeStop"
).click(
function
(){
window.location.reload();
// Instead of unbinding everything, just reload page. Now, IE, you can take a deep breath
});
//now we'll add those logger functions
obj.addClass(
"debugging"
).click(
function
(event){
event.preventDefault();
// so links wont be opened while debugging
logThis( event.target, debugCss, debugJS );
//and let's add this to our logger spans
});
};
function
logThis(elem, css, js ) {
var
sel = selectors(elem);
//if you want to do something else with results (like sending to a feedback plugin) add stuff here
css.text( sel[0] );
js.text( sel[1] );
}
function
selectors(elem) {
var
css =
""
,
continueCss = 1,
js =
""
,
parent =
""
,
ret =
new
Array();
while
(elem !== window.document) {
parent = elem.parentNode;
//js selector
x=0;
while
( ( $(parent.childNodes[x])[0] !== elem ) && (x < parent.childNodes.length) ) {
x++;
}
//now we have our childNode!
js = x +
","
+ js;
//CSS selector
if
(continueCss) {
if
(elem.id) {
css = elem.nodeName +
'#'
+ elem.id +
" "
+ css;
continueCss = 0;
}
else
if
(elem.className) {
css = elem.nodeName +
'.'
+ elem.className +
" "
+ css;
}
else
{
css = elem.nodeName +
" "
+ css;
}
}
//let's go up one level
elem = elem.parentNode;
}
//let's make our js selector useful
js = (js.slice(0, -1)).split(
","
);
for
(x=0; x< js.length; x++) {
js[x] =
"childNodes["
+ js[x] +
"]"
;
}
js =
"window. document. "
+ js.join(
". "
);
ret[0] = css.toLowerCase();
//css
ret[1] = js;
//js
return
ret;
}
// A really lightweight plugin wrapper around the constructor, preventing against multiple instantiations
$.fn[pluginName] =
function
( options ) {
return
this
.each(
function
() {
if
(!$.data(
this
,
'plugin_'
+ pluginName)) {
$.data(
this
,
'plugin_'
+ pluginName,
new
Plugin(
this
, options ));
}
});
}
})(jQuery, window, document);
What do you think?
Don’t be shy and share your thoughts with us
Element DOM Tree jQuery plugin – Firebug like functionality | RockingCode的更多相关文章
- How do I pull a native DOM element from a jQuery object? | jQuery Learning Center
How do I pull a native DOM element from a jQuery object? | jQuery Learning Center How do I pull a na ...
- [Javascript] Deep Search nested tag element in DOM tree
// For example you want to search for nested ul and ol in a DOM tree branch // Give example <ol&g ...
- jQuery plugin : bgStretcher 背景图片切换效果插件
转自:http://blog.dvxj.com/pandola/jQuery_bgStretcher.html bgStretcher 2011 (Background Stretcher)是一个jQ ...
- Signs of a poorly written jQuery plugin 翻译 (Jquery插件开发注意事项,Jquey官方推荐)
原文链接:http://remysharp.com/2010/06/03/signs-of-a-poorly-written-jquery-plugin/ 原文作者:remy sharp So far ...
- The ultimate jQuery Plugin List(终极jQuery插件列表)
下面的文章可能出自一位奥地利的作者, 列出很多jQuery的插件.类似的网站:http://jquerylist.com/原文地址: http://www.kollermedia.at/archiv ...
- transfered jquery plugin practice!
jQuery插件开发入门 发表于 2014年05月23日 by 天涯孤雁 被浏览 20,897 次 ======2014-5-27 更新======= Require.js中使用jQuery 插件请查 ...
- JQuery plugin ---- simplePagination.js API
CSS Themes "light-theme" "dark-theme" "compact-theme" How To Use Step ...
- [jQuery] 自做 jQuery Plugin - Part 1
有時候寫 jQuery 時,常會發現一些簡單的效果可以重複利用.只是每次用 Copy & Paste 大法似乎不是件好事,有沒有什麼方法可以讓我們把這些效果用到其他地方呢? 沒錯,就是用 jQ ...
- ollicle.com: Biggerlink – jQuery plugin
ollicle.com: Biggerlink – jQuery plugin Biggerlink – jQuery plugin Purpose Demo Updated for jQuery 1 ...
随机推荐
- Storm的数据可靠性(理论)
Storm的数据可靠性(理论) .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB& ...
- HTML5 Placeholder实现input背景文字提示效果
这篇文章我们来看看什么是input输入框背景文字提示效果,如下图所示: 这种效果现在网上非常的普遍流行,但大部分是使用JavaScript实现的.但HTML5给我们提供了新的纯HTML的实现方式,不需 ...
- Js把URL中的参数解析为一个对象
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8" /> <title&g ...
- OpenCV学习 4:摄像头视频读写与边缘检测
原创文章,欢迎转载,转载请注明出处 想实现人脸识别,车辆识别,车牌识别.一般我们可不是读硬盘里面的视频文件的,都是直接从摄像头读取视频流然后直接识别的.所以读取摄像头的视频流这是基础...OpenCV ...
- warning: control reaches end of non-void function
用gcc编译一个程序的时候出现这样的警告: warning: control reaches end of non-void function 它的意思是:控制到达非void函数的结尾.就是说你的一些 ...
- C语言入门(7)——自定义函数
C源程序是由函数组成的.虽然在C语言入门系列前面几篇的程序中大都只有一个主函数main(),但实用程序往往由多个函数组成.函数是C源程序的基本模块,通过对函数模块的调用实现特定的功能.C语言中的函数相 ...
- ocx控件获取使用App的窗口句柄
在CXxxCtrl文件中 HWND hAppWnd = NULL; if (m_pInPlaceSite != NULL) m_pInPlaceSite->GetWindow(&hApp ...
- 解决cookie无法删除的问题
今天遇到一个cookie无法删除的问题,退出操作时cookie无法删除,必须在首页先进行退出操作,后来发现一个网友的博客,介绍了无法删除Cookie的原因,原来是我关于cookie的基础知识没搞清楚. ...
- 解决mac插入U盘不显示标识问题
有时候,我们在使用U盘的时候,如果未能正常退出U盘,下次插入U盘可能会不显示U盘. 解决办法如下,打开Finder-->偏好设置,设置 成功解决问题.
- poj 3680 Intervals(费用流)
http://poj.org/problem?id=3680 巧妙的构图. 题目:给定N个区间(ai,bi)权值wi,求最大权和且每个点最多覆盖K次. 构图:将区间端点离散化,将第i个点连第i+1个点 ...