Showing posts with label DOM. Show all posts
Showing posts with label DOM. Show all posts

Tuesday, May 12, 2009

Non-blocking JavaScript

Include via DOM

var js = document.createElement('script'); 
js.src = 'myscript.js'; 
var h = document.getElementsByTagName('head')[0]; 
h.appendChild(js);

Non-blocking JavaScript
  And what about my inline scripts?
  Setup a collection (registry) of inline scripts

Step 1
Inline in the <head>:
var myapp = { 
   stuff: [] 
}; 

Step 2
  Add to the registry
Instead of:
  alert('boo!');
Do:
  myapp.stuff.push(function(){ 
    alert('boo!'); 
  );

Step 3
  Execute all

var l = myapp.stuff.length;  
var l = myapp.stuff.length;  
for(var i = 0, i < l; i++) { 
myapp.stuff[i](); 

Saturday, October 25, 2008

Usage of MarkupWriter and Element in Tapestry5

可以在 @BeginRender 或者 @AfterRender 等 Annotation 声明过的方法内注入 MarkupWriter,用其以 XML 形式组织成一个 DOM 对象来渲染 Tapestry 组件,或者用其调整页面模板中的某个Element,修改其内容或者属性。可以通过 MarkupWriter 接口或者是 Element 类提供的方法操作这个 DOM 对象。
做一个Tapestry input组件的简单例子,无需模板文件:

public void afterRender(MarkupWriter writer) {
Element input = writer.element("input", "id", "input1", "name", "inputName", "value", "inputValue");
input.attribute("type", "text");
writer.end();
}
其中要注意如果用writer.element()打开一个元素标签时,要用writer.end()方法关闭此元素标签。
也可以在 Tapestry Page Class 中可以动态修改其模板文件,如下例子修改页面模板中一个div的文字内容和div属性。
page:
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.dom.Element;

public class Test {

public void afterRender(MarkupWriter writer) {
Element elem = writer.getDocument().getElementById("elemId");
elem.text(" This text added by Element.text method.");
elem.attribute("style", "border: #ddd 1px solid");
}
}
tml:
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<div id="elemId">old inner text.</div>
</html>

在Tapestry5中,假如一个render方法名即符合Tapestry5的命名约定,又对方法做了Annotation声明,当二者不一致时,则此方法在二个render阶段都会被调用。
例如一个方法名叫afterRender,同时在方法中加了@BeginRender的修饰,则此方法在beginRender和afterRender这二个阶段都会被调用。
另外@Inject另外二个服务到页面中,也可以生成MarkupWriter对象,再用此对象操作模板。
@Inject
private ResponseRenderer responseRenderer;

@Inject
private MarkupWriterFactory factory;

如下方式在程序中也可得到MarkupWriter对象。
ContentType contentType = responseRenderer.findContentType(this);
MarkupWriter writer = factory.newMarkupWriter(contentType);

Sunday, August 05, 2007

DOM Range Selections

DOM Range Selections
The DOM Range API (http://www.w3.org/TR/DOM-Level-2-Traversal-Range/) introduced in DOM Level 2 is another convenience extension that allows you to select a range of content in a document programmatically. To create a range, use document.CreateRange(), which will return a Range object.
var myRange = document.createRange();

Once you have a Range object, you can set what it contains using a variety of methods. Given our example range, we might use myRange.setStart(), myRange.setEnd(), myRange.setStartBefore(), myRange.setStartAfter(), myRange.setEndBefore(), and myRange.setEndAfter() to set the start and end points of the range. Each of these methods takes a Node primarily, though setStart() and setEnd() take a numeric value indicating an offset value. You may also just as easily select a particular node using myRange.selectNode() or its contents using myRange.selectNodeContents(). A simple example here selects two paragraphs as a range.


<p id="p1">This is sample <em>text</em> go ahead and create a <i>selection</i>
over a portion of this paragraph.</p>
<p id="p2">Another paragraph</p>
<p id="p3">Yet another paragraph.<br/></p>
<p id="p4">Yet another paragraph again.</p>
<p id="m">

[IE]Once you have a range, you can perform a variety of methods upon it, including extractContents(), cloneContents(), and deleteContents(), and even add contents using insertNode(). While the Range API is quite interesting, it is at the time of this edition’s writing only partially implemented in Mozilla. Internet Explorer uses a completely different proprietary method for ranges and selections. </p>

<script type="text/javascript">
<!--
var myRange1;
var myRange2;
var myRange3;
var myDiv;
var p1 = document.getElementById('p1');
if (document.createRange) {
myRange1 = document.createRange();
myRange1.setStartBefore(document.getElementById('p1'));
myRange1.setEndAfter(document.getElementById('p2'));
//alert(myRange1);
myRange2 = document.createRange();
myRange2.selectNodeContents(document.getElementById('p4'));
//alert(myRange2);
myRange3 = document.createRange();
myRange3.selectNodeContents(p1);
myDiv = myRange3.createContextualFragment('<div id="d1">test createContextualFragment of Mozilla</div>');
p1.appendChild(myDiv);
/* Now highlight using Mozilla style selections */
mySelection = window.getSelection();
mySelection.addRange(myRange1);
mySelection.addRange(myRange2);
}
//-->
</script>

JavaScript Dom 修正


<script language="JavaScript" type="Text/JavaScript">
<!--
if(window.Event){// 修正Event的DOM
/*
IE5 MacIE5 Mozilla Konqueror2.2 Opera5
event yes yes yes yes yes
event.returnValue yes yes no no no
event.cancelBubble yes yes no no no
event.srcElement yes yes no no no
event.fromElement yes yes no no no
*/
Event.prototype.__defineSetter__("returnValue",function(b){//
if(!b)this.preventDefault();
return b;
});
Event.prototype.__defineSetter__("cancelBubble",function(b){// 设置或者检索当前事件句柄的层次冒泡
if(b)this.stopPropagation();
return b;
});
Event.prototype.__defineGetter__("srcElement",function(){
var node=this.target;
while(node.nodeType!=1)node=node.parentNode;
return node;
});
Event.prototype.__defineGetter__("fromElement",function(){// 返回鼠标移出的源节点
var node;
if(this.type=="mouseover")
node=this.relatedTarget;
else if(this.type=="mouseout")
node=this.target;
if(!node)return;
while(node.nodeType!=1)node=node.parentNode;
return node;
});
Event.prototype.__defineGetter__("toElement",function(){// 返回鼠标移入的源节点
var node;
if(this.type=="mouseout")
node=this.relatedTarget;
else if(this.type=="mouseover")
node=this.target;
if(!node)return;
while(node.nodeType!=1)node=node.parentNode;
return node;
});
Event.prototype.__defineGetter__("offsetX",function(){
return this.layerX;
});
Event.prototype.__defineGetter__("offsetY",function(){
return this.layerY;
});
}
if(window.Document){// 修正Document的DOM
/*
IE5 MacIE5 Mozilla Konqueror2.2 Opera5
document.documentElement yes yes yes yes no
document.activeElement yes null no no no

*/
}
if(window.Node){// 修正Node的DOM
/*
IE5 MacIE5 Mozilla Konqueror2.2 Opera5
Node.contains yes yes no no yes
Node.replaceNode yes no no no no
Node.removeNode yes no no no no
Node.children yes yes no no no
Node.hasChildNodes yes yes yes yes no
Node.childNodes yes yes yes yes no
Node.swapNode yes no no no no
Node.currentStyle yes yes no no no

*/
Node.prototype.replaceNode=function(Node){// 替换指定节点
this.parentNode.replaceChild(Node,this);
}
Node.prototype.removeNode=function(removeChildren){// 删除指定节点
if(removeChildren)
return this.parentNode.removeChild(this);
else{
var range=document.createRange();
range.selectNodeContents(this);
return this.parentNode.replaceChild(range.extractContents(),this);
}
}
Node.prototype.swapNode=function(Node){// 交换节点
var nextSibling=this.nextSibling;
var parentNode=this.parentNode;
node.parentNode.replaceChild(this,Node);
parentNode.insertBefore(node,nextSibling);
}
}
if(window.HTMLElement){
HTMLElement.prototype.__defineGetter__("all",function(){
var a=this.getElementsByTagName("*");
var node=this;
a.tags=function(sTagName){
return node.getElementsByTagName(sTagName);
}
return a;
});
HTMLElement.prototype.__defineGetter__("parentElement",function(){
if(this.parentNode==this.ownerDocument)return null;
return this.parentNode;
});
HTMLElement.prototype.__defineGetter__("children",function(){
var tmp=[];
var j=0;
var n;
for(var i=0;i<this.childNodes.length;i++){
n=this.childNodes[i];
if(n.nodeType==1){
tmp[j++]=n;
if(n.name){
if(!tmp[n.name])
tmp[n.name]=[];
tmp[n.name][tmp[n.name].length]=n;
}
if(n.id)
tmp[n.id]=n;
}
}
return tmp;
});
HTMLElement.prototype.__defineGetter__("currentStyle", function(){
return this.ownerDocument.defaultView.getComputedStyle(this,null);
});
HTMLElement.prototype.__defineSetter__("outerHTML",function(sHTML){
var r=this.ownerDocument.createRange();
r.setStartBefore(this);
var df=r.createContextualFragment(sHTML);
this.parentNode.replaceChild(df,this);
return sHTML;
});
HTMLElement.prototype.__defineGetter__("outerHTML",function(){
var attr;
var attrs=this.attributes;
var str="<"+this.tagName;
for(var i=0;i
attr=attrs[i];
if(attr.specified)
str+=" "+attr.name+'="'+attr.value+'"';
}
if(!this.canHaveChildren)
return str+">";
return str+">"+this.innerHTML+"";
});
HTMLElement.prototype.__defineGetter__("canHaveChildren",function(){
switch(this.tagName.toLowerCase()){
case "area":
case "base":
case "basefont":
case "col":
case "frame":
case "hr":
case "img":
case "br":
case "input":
case "isindex":
case "link":
case "meta":
case "param":
return false;
}
return true;
});

HTMLElement.prototype.__defineSetter__("innerText",function(sText){
var parsedText=document.createTextNode(sText);
this.innerHTML=parsedText;
return parsedText;
});
HTMLElement.prototype.__defineGetter__("innerText",function(){
var r=this.ownerDocument.createRange();
r.selectNodeContents(this);
return r.toString();
});
HTMLElement.prototype.__defineSetter__("outerText",function(sText){
var parsedText=document.createTextNode(sText);
this.outerHTML=parsedText;
return parsedText;
});
HTMLElement.prototype.__defineGetter__("outerText",function(){
var r=this.ownerDocument.createRange();
r.selectNodeContents(this);
return r.toString();
});
HTMLElement.prototype.attachEvent=function(sType,fHandler){
var shortTypeName=sType.replace(/on/,"");
fHandler._ieEmuEventHandler=function(e){
window.event=e;
return fHandler();
}
this.addEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
}
HTMLElement.prototype.detachEvent=function(sType,fHandler){
var shortTypeName=sType.replace(/on/,"");
if(typeof(fHandler._ieEmuEventHandler)=="function")
this.removeEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
else
this.removeEventListener(shortTypeName,fHandler,true);
}
HTMLElement.prototype.contains=function(Node){// 是否包含某节点
do if(Node==this)return true;
while(Node=Node.parentNode);
return false;
}
HTMLElement.prototype.insertAdjacentElement=function(where,parsedNode){
switch(where){
case "beforeBegin":
this.parentNode.insertBefore(parsedNode,this);
break;
case "afterBegin":
this.insertBefore(parsedNode,this.firstChild);
break;
case "beforeEnd":
this.appendChild(parsedNode);
break;
case "afterEnd":
if(this.nextSibling)
this.parentNode.insertBefore(parsedNode,this.nextSibling);
else
this.parentNode.appendChild(parsedNode);
break;
}
}
HTMLElement.prototype.insertAdjacentHTML=function(where,htmlStr){
var r=this.ownerDocument.createRange();
r.setStartBefore(this);
var parsedHTML=r.createContextualFragment(htmlStr);
this.insertAdjacentElement(where,parsedHTML);
}
HTMLElement.prototype.insertAdjacentText=function(where,txtStr){
var parsedText=document.createTextNode(txtStr);
this.insertAdjacentElement(where,parsedText);
}
HTMLElement.prototype.attachEvent=function(sType,fHandler){
var shortTypeName=sType.replace(/on/,"");
fHandler._ieEmuEventHandler=function(e){
window.event=e;
return fHandler();
}
this.addEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
}
HTMLElement.prototype.detachEvent=function(sType,fHandler){
var shortTypeName=sType.replace(/on/,"");
if(typeof(fHandler._ieEmuEventHandler)=="function")
this.removeEventListener(shortTypeName,fHandler._ieEmuEventHandler,false);
else
this.removeEventListener(shortTypeName,fHandler,true);
}
}
//-->
</script>

此程序由某文章回帖处转过来的,未知原作者。

Sunday, July 15, 2007

select options manuplation of javascript


<form action="" method="get" accept-charset="utf-8">
<strong>Single Robot Choice:</strong>
<select name="robot" id="robot">
<option value="1">Security</option>
<option value="2">Trainer</option>
<option value="3">Friend</option>
<option value="4">Cook</option>
</select>
<br /><br />
<strong>Multiple Robot Choice:</strong>
<select name="robotMulti" id="robotMulti" size="4" multiple="multiple">
<option value="a">Security</option>
<option value="g">Trainer</option>
<option value="s">Friend</option>
<option value="d">Cook</option>
</select>

<input type='button' value='-' name='button1'>
</form>

<script type="text/javascript" charset="utf-8">
function doc (argument) {
document.write(argument);
document.write("<br />\n");
}

function selectedItems (obj) {
var o = obj.options;
var s = '';
for(var i in o) {
if(o[i].selected){
s += 'index="' + i + '": selected options text="' + o[i].text + '", selected options value="' + o[i].value + '"; ';
}
}
alert(s);
}

var select1 = document.forms[0].robot
var select2 = document.forms[0].robotMulti

// doc(select1);
// alert(select2.multiple);

select1.onchange = function () {
alert('selected text = "' + select1.options[select1.selectedIndex].text + '"; selected index="' + select1.selectedIndex + '"; option index ="' + select1.options[select1.selectedIndex].index + '" ');
}

document.forms[0].button1.onclick = function() {
selectedItems(select2);
}

</script>

Saturday, July 14, 2007

DOM manipulate of Javascript


<div id="div1"></div>

<script type="text/javascript" charset="utf-8">
function doc (argument) {
document.write(argument);
document.write("<br />\n");
}

function insertAfter (newNode, refNode) {
if (refNode.parentNode){
var nextNode = refNode.nextSibling;
if (nextNode){
this.insertBefore(newNode, nextNode);
} else {
this.appendChild(newNode);
}
}
}
HTMLTableCellElement.prototype.insertAfter = insertAfter;

var frag = document.createDocumentFragment();
var d1 = document.getElementById('div1');
var table = document.createElement('table');
var tr = document.createElement('tr');
var td = document.createElement('td');
var coms = document.createComment('test comment');
var attr = document.createAttribute('style');
var textNode1 = document.createTextNode(' this is text node 1! ');
var textNode2 = document.createTextNode(' this is text node 2! ');
var textNode3 = document.createTextNode(' 33333! ');
var clonedText = textNode3.cloneNode(false);

frag.appendChild(table);
table.appendChild(tr);
tr.appendChild(td);
td.appendChild(textNode1);
td.insertBefore(coms, textNode1);
td.insertBefore(textNode2, textNode1);
td.insertAfter(clonedText, textNode1);

var clonedTr = tr.cloneNode(true);
table.appendChild(clonedTr); // this is text node 2! this is text node 1! 33333!
d1.appendChild(frag);

textNode2.data = ' 22222! '; // 22222! this is text node 1! 33333!
td.setAttribute('style', 'background-color: #ddd');
// td.style.backgroundColor = '#ccc';
td.style.border = 'red solid 1px';

doc(frag);
doc(clonedText);
doc(td);
</script>