父傳子傳緩存
『壹』 react <link 可以傳值嗎
處理 React 組件之間的交流方式,主要取決於組件之間的關系,然而這些關系的約定人就是你。
我不會講太多關於 data-stores、data-adapters 或者 data-helpers 之類的話題。我下面只專注於 React 組件本身的交流方式的講解。
React 組件之間交流的方式,可以分為以下 3 種:
【父組件】向【子組件】傳值;
【子組件】向【父組件】傳值;
沒有任何嵌套關系的組件之間傳值(PS:比如:兄弟組件之間傳值)
一、【父組件】向【子組件】傳值
初步使用
這個是相當容易的,在使用 React 開發的過程中經常會使用到,主要是利用 props 來進行交流。例子如下:
// 父組件
var MyContainer = React.createClass({
getInitialState: function () {
return {
checked: true
};
},
render: function() {
return (
<ToggleButton text="Toggle me" checked={this.state.checked} />
);
}
});
// 子組件
var ToggleButton = React.createClass({
render: function () {
// 從【父組件】獲取的值
var checked = this.props.checked,
text = this.props.text;
return (
<label>{text}: <input type="checkbox" checked={checked} /></label>
);
}
});
進一步討論
如果組件嵌套層次太深,那麼從外到內組件的交流成本就變得很高,通過 props 傳遞值的優勢就不那麼明顯了。(PS:所以我建議盡可能的減少組件的層次,就像寫 HTML 一樣,簡單清晰的結構更惹人愛)
// 父組件
var MyContainer = React.createClass({
render: function() {
return (
<Intermediate text="where is my son?" />
);
}
});
// 子組件1:中間嵌套的組件
var Intermediate = React.createClass({
render: function () {
return (
<Child text={this.props.text} />
);
}
});
// 子組件2:子組件1的子組件
var Child = React.createClass({
render: function () {
return (
<span>{this.props.text}</span>
);
}
});
二、【子組件】向【父組件】傳值
接下來,我們介紹【子組件】控制自己的 state 然後告訴【父組件】的點擊狀態,然後在【父組件】中展示出來。因此,我們添加一個 change 事件來做交互。
// 父組件
var MyContainer = React.createClass({
getInitialState: function () {
return {
checked: false
};
},
onChildChanged: function (newState) {
this.setState({
checked: newState
});
},
render: function() {
var isChecked = this.state.checked ? 'yes' : 'no';
return (
<div>
<div>Are you checked: {isChecked}</div>
<ToggleButton text="Toggle me"
initialChecked={this.state.checked}
callbackParent={this.onChildChanged}
/>
</div>
);
}
});
// 子組件
var ToggleButton = React.createClass({
getInitialState: function () {
return {
checked: this.props.initialChecked
};
},
onTextChange: function () {
var newState = !this.state.checked;
this.setState({
checked: newState
});
// 這里要注意:setState 是一個非同步方法,所以需要操作緩存的當前值
this.props.callbackParent(newState);
},
render: function () {
// 從【父組件】獲取的值
var text = this.props.text;
// 組件自身的狀態數據
var checked = this.state.checked;
return (
<label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange} /></label>
);
}
});
我覺得原文作者用代碼不是很直觀,接下來我話一個流程走向簡圖來直觀描述一下這個過程:
這樣做其實是依賴 props 來傳遞事件的引用,並通過回調的方式來實現的,這樣實現不是特別好,但是在沒有任何工具的情況下也是一種簡單的實現方式
這里會出現一個我們在之前討論的問題,就是組件有多層嵌套的情況下,你必須要一次傳入回調函數給 props 來實現子組件向父組件傳值或者操作。
Tiny-Tip: React Event System
在 onChange 事件或者其他 React 事件中,你能夠獲取以下東西:
【this】:指向你的組件
【一個參數】:這個參數是一個 React 合成事件,SyntheticEvent。
React 對所有事件的管理都是自己實現的,與我們之前使用的 onclick、onchange 事件不一樣。從根本上來說,他們都是綁定到 body 上。
document.on('change', 'input[data-reactid=".0.2"]', function () {...});
上面這份代碼不是來自於 React,只是打一個比方而已。
如果我沒有猜錯的話,React 真正處理一個事件的代碼如下:
var listenTo = ReactBrowserEventEmitter.listenTo;
...
function putListener(id, registrationName, listener, transaction) {
...
var container = ReactMount.findReactContainerForID(id);
if (container) {
var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container;
listenTo(registrationName, doc);
}
...
}
// 在監聽事件的內部,我們能發現如下:
target.addEventListener(eventType, callback, false);
這里有所有 React 支持的事件:中文文檔-事件系統
多個子組件使用同一個回調的情況
// 父組件
var MyContainer = React.createClass({
getInitialState: function () {
return {
totalChecked: 0
};
},
onChildChanged: function (newState) {
var newToral = this.state.totalChecked + (newState ? 1 : -1);
this.setState({
totalChecked: newToral
});
},
render: function() {
var totalChecked = this.state.totalChecked;
return (
<div>
<div>How many are checked: {totalChecked}</div>
<ToggleButton text="Toggle me"
initialChecked={this.state.checked}
callbackParent={this.onChildChanged}
/>
<ToggleButton text="Toggle me too"
initialChecked={this.state.checked}
callbackParent={this.onChildChanged}
/>
<ToggleButton text="And me"
initialChecked={this.state.checked}
callbackParent={this.onChildChanged}
/>
</div>
);
}
});
// 子組件
var ToggleButton = React.createClass({
getInitialState: function () {
return {
checked: this.props.initialChecked
};
},
onTextChange: function () {
var newState = !this.state.checked;
this.setState({
checked: newState
});
// 這里要注意:setState 是一個非同步方法,所以需要操作緩存的當前值
this.props.callbackParent(newState);
},
render: function () {
// 從【父組件】獲取的值
var text = this.props.text;
// 組件自身的狀態數據
var checked = this.state.checked;
return (
<label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange} /></label>
);
}
});
這是非常容易理解的,在父組件中我們增加了一個【totalChecked】來替代之前例子中的【checked】,當子組件改變的時候,使用同一個子組件的回調函數給父組件返回值。
三、沒有任何嵌套關系的組件之間傳值
如果組件之間沒有任何關系,組件嵌套層次比較深(個人認
為 2 層以上已經算深了),或者你為了一些組件能夠訂閱、寫入一些信號,不想讓組件之間插入一個組件,讓兩個組件處於獨立的關系。對於事件系統,這里有
2
個基本操作步驟:訂閱(subscribe)/監聽(listen)一個事件通知,並發送(send)/觸發(trigger)/發布(publish)
/發送(dispatch)一個事件通知那些想要的組件。
下面講介紹 3 種模式來處理事件,你能點擊這里來比較一下它們。
簡單總結一下:
(1) Event Emitter/Target/Dispatcher
特點:需要一個指定的訂閱源
// to subscribe
otherObject.addEventListener(『click』, function() { alert(『click!』); });
// to dispatch
this.dispatchEvent(『click』);
(2) Publish / Subscribe
特點:觸發事件的時候,你不需要指定一個特定的源,因為它是使用一個全局對象來處理事件(其實就是一個全局
廣播的方式來處理事件)
// to subscribe
globalBroadcaster.subscribe(『click』, function() { alert(『click!』); });
// to dispatch
globalBroadcaster.publish(『click』);
(3) Signals
特點:與Event
Emitter/Target/Dispatcher相似,但是你不要使用隨機的字元串作為事件觸發的引用。觸發事件的每一個對象都需要一個確切的名字
(就是類似硬編碼類的去寫事件名字),並且在觸發的時候,也必須要指定確切的事件。(看例子吧,很好理解)
// to subscribe
otherObject.clicked.add(function() { alert(『click』); });
// to dispatch
this.clicked.dispatch();
如果你只想簡單的使用一下,並不需要其他操作,可以用簡單的方式來實現:
// 簡單實現了一下 subscribe 和 dispatch
var EventEmitter = {
_events: {},
dispatch: function (event, data) {
if (!this._events[event]) { // 沒有監聽事件
return;
}
for (var i = 0; i < this._events[event].length; i++) {
this._events[event][i](data);
}
},
subscribe: function (event, callback) {
// 創建一個新事件數組
if (!this._events[event]) {
this._events[event] = [];
}
this._events[event].push(callback);
}
};
otherObject.subscribe('namechanged', function(data) { alert(data.name); });
this.dispatch('namechanged', { name: 'John' });
如果你想使用 Publish/Subscribe 模型,可以使用:PubSubJS
React 團隊使用的是:js-signals 它基於 Signals 模式,用起來相當不錯。
Events in React
使用 React 事件的時候,必須關注下面兩個方法:
componentDidMount
componentWillUnmount
在處理事件的時候,需要注意:
在 componentDidMount 事件中,如果組件掛載(mounted)完成,再訂閱事件;當組件卸載(unmounted)的時候,在 componentWillUnmount 事件中取消事件的訂閱。
(如果不是很清楚可以查閱 React 對生命周期介紹的文檔,裡面也有描述。原文中介紹的是 componentWillMount 個人認為應該是掛載完成後訂閱事件,比如Animation這個就必須掛載,並且不能動態的添加,謹慎點更好)
因為組件的渲染和銷毀是由 React 來控制的,我們不知道怎麼引用他們,所以EventEmitter 模式在處理組件的時候用處不大。
pub/sub 模式可以使用,你不需要知道引用。
下面來一個例子:實現有多個 proct 組件,點擊他們的時候,展示 proct 的名字。
(我在例子中引入了之前推薦的 PubSubJS 庫,如果你覺得引入代價太大,也可以手寫一個簡版,還是比較容易的,很好用哈,大家也可以體驗,但是我還是不推薦全局廣播的方式)
// 定義一個容器
var ProctList = React.createClass({
render: function () {
return (
<div>
<ProctSelection />
<Proct name="proct 1" />
<Proct name="proct 2" />
<Proct name="proct 3" />
</div>
);
}
});
// 用於展示點擊的產品信息容器
var ProctSelection = React.createClass({
getInitialState: function() {
return {
selection: 'none'
};
},
componentDidMount: function () {
this.pubsub_token = PubSub.subscribe('procts', function (topic, proct) {
this.setState({
selection: proct
});
}.bind(this));
},
componentWillUnmount: function () {
PubSub.unsubscribe(this.pubsub_token);
},
render: function () {
return (
<p>You have selected the proct : {this.state.selection}</p>
);
}
});
var Proct = React.createClass({
onclick: function () {
PubSub.publish('procts', this.props.name);
},
render: function() {
return <div onClick={this.onclick}>{this.props.name}</div>;
}
});
ES6: yield and js-csp
ES6 中有一種傳遞信息的方式,使用生成函數(generators)和 yield 關鍵字。可以看一下https://github.com/ubolonton/js-csp
(這里我寫一個簡單的 DEMO 介紹一下這種新的傳遞方式,其實大同小異)
function* list() {
for(var i = 0; i < arguments.length; i++) {
yield arguments[i];
}
return "done.";
}
var o = list(1, 2, 3);
var cur = o.next;
while(!cur.done) {
cur = o.next();
console.log(cur);
}
以上例子來自於屈屈的一篇博客:ES6 中的生成器函數介紹 屈屈是一個大牛,大家可以經常關注他的博客。
通常來說,你有一個隊列,對象在裡面都能找到一個引用,在定義的時候鎖住,當發生的時候,立即打開鎖執行。js-csp 是一種解決辦法,也許以後還會有其他解決辦法。
『貳』 react路由中如何向組件傳參數
處理 React 組件之間的交流方式,主要取決於組件之間的關系,然而這些關系的約定人就是你。
我不會講太多關於 data-stores、data-adapters 或者 data-helpers 之類的話題。我下面只專注於 React 組件本身的交流方式的講解。
React 組件之間交流的方式,可以分為以下 3 種:
【父組件】向【子組件】傳值;
【子組件】向【父組件】傳值;
沒有任何嵌套關系的組件之間傳值(PS:比如:兄弟組件之間傳值)
一、【父組件】向【子組件】傳值
初步使用
這個是相當容易的,在使用 React 開發的過程中經常會使用到,主要是利用 props 來進行交流。例子如下:
// 父組件
var MyContainer = React.createClass({
getInitialState: function () {
return {
checked: true
};
},
render: function() {
return (
<ToggleButton text="Toggle me" checked={this.state.checked} />
);
}
});
// 子組件
var ToggleButton = React.createClass({
render: function () {
// 從【父組件】獲取的值
var checked = this.props.checked,
text = this.props.text;
return (
<label>{text}: <input type="checkbox" checked={checked} /></label>
);
}
});
進一步討論
如果組件嵌套層次太深,那麼從外到內組件的交流成本就變得很高,通過 props 傳遞值的優勢就不那麼明顯了。(PS:所以我建議盡可能的減少組件的層次,就像寫 HTML 一樣,簡單清晰的結構更惹人愛)
// 父組件
var MyContainer = React.createClass({
render: function() {
return (
<Intermediate text="where is my son?" />
);
}
});
// 子組件1:中間嵌套的組件
var Intermediate = React.createClass({
render: function () {
return (
<Child text={this.props.text} />
);
}
});
// 子組件2:子組件1的子組件
var Child = React.createClass({
render: function () {
return (
<span>{this.props.text}</span>
);
}
});
二、【子組件】向【父組件】傳值
接下來,我們介紹【子組件】控制自己的 state 然後告訴【父組件】的點擊狀態,然後在【父組件】中展示出來。因此,我們添加一個 change 事件來做交互。
// 父組件
var MyContainer = React.createClass({
getInitialState: function () {
return {
checked: false
};
},
onChildChanged: function (newState) {
this.setState({
checked: newState
});
},
render: function() {
var isChecked = this.state.checked ? 'yes' : 'no';
return (
<div>
<div>Are you checked: {isChecked}</div>
<ToggleButton text="Toggle me"
initialChecked={this.state.checked}
callbackParent={this.onChildChanged}
/>
</div>
);
}
});
// 子組件
var ToggleButton = React.createClass({
getInitialState: function () {
return {
checked: this.props.initialChecked
};
},
onTextChange: function () {
var newState = !this.state.checked;
this.setState({
checked: newState
});
// 這里要注意:setState 是一個非同步方法,所以需要操作緩存的當前值
this.props.callbackParent(newState);
},
render: function () {
// 從【父組件】獲取的值
var text = this.props.text;
// 組件自身的狀態數據
var checked = this.state.checked;
return (
<label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange} /></label>
);
}
});
我覺得原文作者用代碼不是很直觀,接下來我話一個流程走向簡圖來直觀描述一下這個過程:
這樣做其實是依賴 props 來傳遞事件的引用,並通過回調的方式來實現的,這樣實現不是特別好,但是在沒有任何工具的情況下也是一種簡單的實現方式
這里會出現一個我們在之前討論的問題,就是組件有多層嵌套的情況下,你必須要一次傳入回調函數給 props 來實現子組件向父組件傳值或者操作。
Tiny-Tip: React Event System
在 onChange 事件或者其他 React 事件中,你能夠獲取以下東西:
【this】:指向你的組件
【一個參數】:這個參數是一個 React 合成事件,SyntheticEvent。
React 對所有事件的管理都是自己實現的,與我們之前使用的 onclick、onchange 事件不一樣。從根本上來說,他們都是綁定到 body 上。
document.on('change', 'input[data-reactid=".0.2"]', function () {...});
上面這份代碼不是來自於 React,只是打一個比方而已。
如果我沒有猜錯的話,React 真正處理一個事件的代碼如下:
var listenTo = ReactBrowserEventEmitter.listenTo;
...
function putListener(id, registrationName, listener, transaction) {
...
var container = ReactMount.findReactContainerForID(id);
if (container) {
var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container;
listenTo(registrationName, doc);
}
...
}
// 在監聽事件的內部,我們能發現如下:
target.addEventListener(eventType, callback, false);
這里有所有 React 支持的事件:中文文檔-事件系統
多個子組件使用同一個回調的情況
// 父組件
var MyContainer = React.createClass({
getInitialState: function () {
return {
totalChecked: 0
};
},
onChildChanged: function (newState) {
var newToral = this.state.totalChecked + (newState ? 1 : -1);
this.setState({
totalChecked: newToral
});
},
『叄』 js中location.reload可以跨頁面傳值么
location.reload 方法是重新載入頁面,這個相當於你按鍵盤的 F5 鍵,是不能帶參數的。
按你說的意思,功能本身是可以實現的,但不是使用 location.reload ,而且是有前提條件的。
瀏覽器為了安全起見,是不能操作地址不同源的 iframe 標簽里的內容的,只能對同源地址的iframe進行操作,什麼是同源,如果你不了解,請先搜索一下」同源策略「,簡單來說就是 iframe 標簽所引入的頁面,必須跟你的 主頁面是同一個網站中的頁面。
如果你上面的效果滿足上述前提,也就是 iframe 中引入的頁面跟主頁面都是你自己寫的,而且是同一個網站,那麼實現的大概思路是這樣的:
1, 點擊主頁面的查詢,將數據顯示在 iframe 頁面里。
就是在主頁面中發起查詢請求,然後在iframe 頁面中顯示查詢結果。這里需要js配合,有兩種實現方式,一是通過地址欄傳遞參數,另一種是直接用 js 硬寫入 iframe 頁面中。 如果是通過地址欄傳遞參數,在點擊主頁面的查詢之後,在js中使用 iframe.src = '.....html?key1=vaue1&key2=value2' 的方式傳遞給 iframe 頁面,然後 iframe 頁面中也需要用 js 來處理傳遞過來的參數,採用 location.search 來獲取傳遞過來的所有參數,然後進行分割處理;如果是直接硬寫入 iframe 頁面中,則需要獲取到 iframe 頁面中相應的標簽,獲取當前頁面中的某個元素,是用 document.get... 之類的方法,這里的 document 就是指當前頁面的文檔對象,那麼獲取 iframe ,當然得通過 iframe 頁面的文檔對象,獲取iframe頁面文檔對象的方法是 iframe.contentWindow.document (iframe指的是 iframe標簽,需要先用js獲取到這個標簽),獲取到指定標簽之後,就跟操作當前頁面一樣寫數據了。
2,從iframe 子頁面中返回數據到主頁面中顯示,這個跟上面第一步是一樣的,也有兩種實現思路,也是地址欄傳遞參數或者硬寫,但因為地址欄傳參會刷新頁面,用戶體驗不好,所以還是採用硬寫入的方式。 主頁面寫數據到iframe標簽,需要先獲取標簽,反過來也是一樣的,iframe頁面中寫數據到主頁面,同樣需要先獲取到主頁面中的標簽,獲取原理相通,先要找到主頁面的文檔對象,這里需要清楚整體的頁面結構,主頁面與 iframe 頁面是直接的父子級關系,還是多層嵌套關系?如果是直接的父子關系,那就是 window.parent.contentWindow.document, 如果主頁面是最頂層,那就是 window.top.contentWindow.document 。
『肆』 請教Ext高手我現在子窗口中如何得到父窗口中的值,沒有分了請大家幫幫忙
parent.jsp
<% @ page language = " java " import = " java.util.* " pageEncoding = " GB2312 " %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + " :// " + request.getServerName() + " : " + request.getServerPort() + path + " / " ;
%>
<! DOCTYPE HTML PUBLIC " -//W3C//DTD HTML 4.01 Transitional//EN " >
< html >
< head >
< base href = " <%=basePath%> " >
< title > Parent </ title >
< meta http - equiv = " pragma " content = " no-cache " >
< meta http - equiv = " cache-control " content = " no-cache " >
< meta http - equiv = " expires " content = " 0 " >
< meta http - equiv = " keywords " content = " keyword1,keyword2,keyword3 " >
< meta http - equiv = " description " content = " This is my page " >
< script type = " text/javascript " >
function openChild() {
// 把新打開的窗口放到最頂層,沒有子窗口
// window.open("child.jsp", target="_top");
// 新打開一個窗口,用window.opener.document.all得到
window.open( " child.jsp " , target = " _blank " );
}
function scriptSubmit() {
// var formParent = document.formParent;
// 提交的action,可以直接寫form名稱,因為它是一個文檔模型節點的子節點,直接可以獲得。
formParent.action = " child.jsp " ;
// 強制彈出一個新頁面
formParent.target = " _blank " ;
// 提交
formParent.submit();
}
// 回車提交表單
function enterSubmit() {
if (event.keyCode == 13 ) {
event.returnValue = false ;
event.cancel = true ;
formParent.login.click();
}
}
// 向table中添加tr
function add_tr() {
// alert("abc");
// all後面帶id,否則報錯
var my_tab = document.all( " addtrTable " );
var tab_rows = my_tab.rows.length; // 現有行數
var tab_cells = my_tab.cells.length; // 現有列數
// alert(tab_rows + " " + tab_cells);
var new_row = my_tab.insertRow(tab_rows - 1 ); // 在最後一個tr前插入一個tr
// 可以不定義,但是如果cell = "abc",則必須定義,不然報沒有定義異常
cell = new_row.insertCell();
cell.innerHTML = ' <input type="button" name="delbtn" value="刪除" onclick="hidden_tr()"> ' ;
cell = new_row.insertCell();
cell.innerHTML = ' <input type="text" name="username" value=""> ' ;
cell = new_row.insertCell();
cell.innerHTML = ' <input type="radio" name="sex" value="1" checked="checked">男<input type="radio" name="sex" value="0">女 ' ;
}
// 隱藏table中的tr
function hidden_tr() {
// alert(event.srcElement);
// alert(event.srcElement.parentElement.parentElement);
// 得到表格的所有節點
var my_tab = document.all( " addtrTable " );
// 得到事件的父元素的父元素
var tr = event.srcElement.parentElement.parentElement;
// 得到表格所有節點的長度
var len = my_tab.rows.length;
// 只有一個tr的時候不隱藏
// alert(len);
// var field2 = my_tab.rows[tr.rowIndex].cells[3].firstChild;
// 刪除行
// my_tab.deleteRow(tr.rowIndex);
// 必須初始化
var iCount = 0 ;
// 循環時去掉第一個為table,最後一個為插入一行
for (var i = 1 ; i < len - 1 ; i ++ ) {
// alert(my_tab.rows[i].style.display);
if (my_tab.rows[i].style.display != " none " ) {
iCount ++ ;
}
}
// alert(iCount);
if (iCount == 1 ) {
alert( " 必須保留一行 " );
return ;
}
/**/ /* if(tr.rowIndex == 1) {
alert("授權號為必填項");
return;
} */
// 得到行索引
// alert("行索引" + tr.rowIndex);
// 把當前行的第4個單元格置空
// field2.value = "";
// 把tr設置為不可見
tr.style.display = " none " ;
}
</ script >
</ head >
< body >
<%--< %
// 清空緩存,也有的叫頁面過期,有人誤會以為清空緩存後,然後點擊後退就會跳到一個頁面,
// 上面有一個頁面已過期,要刷新才能看到新頁面,其實這里意思並不是這樣,只是當您後退時
// 清空了文本框的值而已,密碼是默認清空的,避免重復提交。
/**/ /* response.setHeader("pragma", "no-cache");
response.setHeader("cache-control", "no-cache");
response.setHeader("expires", "0"); */
%>--%>
< form name = " formParent " method = " post " >
< table style = " background-color: #D4E1EE;border-bottom-color: #cccccc " cellpadding = " 1 " cellspacing = " 0 " border = " 0 " >
< tr >
< td >
用戶名
</ td >
< td >
< input name = " formname " type = " text " >
</ td >
</ tr >
< tr >
< td >
密碼
</ td >
< td >
< input name = " password " type = " password " onkeydown = " enterSubmit() " >
</ td >
</ tr >
< tr >
< td >
<%-- window.open方法不能在submit觸發,否則子窗口得不到父窗口的值 --%>
< input type = " submit " name = " login " value = " 登錄 " >
</ td >
< td >
<%-- 按鈕不能執行JavaScript提交 --%>
< input type = " button " name = " btn " value = " 跳轉 " onclick = " openChild() " >
</ td >
</ tr >
</ table >
<%-- 強制在新窗口中打開超鏈接 --%>
< a href = " child.jsp " target = " _blank " > Child </ a >
</ form >
< form name = " addtrForm " method = " post " >
< table id = " addtrTable " name = " addtrTable " style = " background-color: #D4E1EE;border-bottom-color: #cccccc " cellpadding = " 1 " cellspacing = " 0 " border = " 0 " >
< tr align = " center " >
< td >
操作
</ td >
< td >
姓名
</ td >
< td >
性別
</ td >
</ tr >
< tr align = " center " >
< td >
< input type = " button " name = " delbtn " value = " 刪除 " onclick = " hidden_tr() " >
</ td >
< td >
< input type = " text " name = " username " value = "" >
</ td >
< td >
< input type = " radio " name = " sex " value = " 1 " checked = " checked " > 男 & nbsp; < input type = " radio " name = " sex " value = " 0 " > 女
</ td >
</ tr >
< tr >
< td colspan = " 2 " >
< input type = " button " name = " addbtn " value = " 插入一行 " onclick = " add_tr() " >
</ td >
</ tr >
</ table >
</ form >
</ body >
</ html >
child.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Child</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript">
function getParentValue() {
// target="_blank"
var formname = window.opener.document.all.formParent.formname;
var password = window.opener.document.all.password;
alert("用戶名:" + formname.value + "\n密碼:" + password.value)
// 刷新父窗口
//window.opener.location.reload();
}
</script>
</head>
<body onload="getParentValue()">
<%
String username = request.getParameter("username");
String password = request.getParameter("password");
out.println("用戶名:" + username + "<br>密碼:" + password);
%>
</body>
</html>