blog.Ring.idv.tw

JavaScript

JavaScript - 用 Range 標記文字重點

不曉得有多少人習慣拿螢光筆在書本上畫重點?

假如現在我們有個需求~ 而這個需求就是要將我們在書本上畫重點的這個動作~ 轉移到Web上面來~ OK, 那該如何做呢?

我想~ 要在網頁上取得所選取的文字~ 那必然離不開「Range」這個Object來協助我們達成~

那有什麼樣的方式又可以達到IE、Firefox、Chrome眾多瀏覽器的支持?

下述是筆者的方式,請參考:

<html>
<head>
<script>
function labelText()
{
	var node = document.createElement("span");
	node.style.backgroundColor = 'yellow';
	
	if(document.selection)
	{
		var range = document.selection.createRange();
		var container = document.createElement("div");
		container.appendChild(node);
		node.innerHTML = range.htmlText;
		range.pasteHTML(container.innerHTML);
	
	}else{
		var selection = window.getSelection();
		var range = selection.getRangeAt(0);	
		
		range.surroundContents(node);
	}
}
</script>
</head>
<body onmouseup="labelText()">
This is a test paragraph.<br/>
This is a test paragraph.<br/>
This is a test paragraph.<br/>
This is a test paragraph.<br/>
This is a test paragraph.<br/>
</body>
</html>

結果:

從結果上來看是沒什麼大問題~ 但... 如果要標記的文字是用「<p>(paragraph)」所標記的話那又會如何?

的確~ 這樣的方式在Firefox或Chrome都還會出現些問題~ 就留待之後探討...

參考資源

JavaScript Rangeの使い方 の差分

range.surroundContents - MDC

百度空间发帖快捷键设置代码高亮

Rich HTML editing in the browser: part 1

Inserting text into Firefox rich text editor - Jeff&'s Junk

Document Object Model Range

2008-09-30 22:45:59 | Add Comment

跨瀏覽器鍵盤按鍵偵測

由於工作上的需要~ 我必須去做一個「鍵盤按鍵偵測」的事項~

所以找了一下相關資訊~ 從這篇「No window.event in firefox ?」好心人士所提供的解決方案~ 的確就簡單的達成我想要的功能~ 如下所示:

<script>
function handleKeyPress(evt)
{
	var nbr = (window.event)?event.keyCode:evt.which;
	alert(nbr);
	return true;
}
document.onkeydown= handleKeyPress
</script>

但是~ 我想要的效果是「偵測到按鍵之後去做相對應的事項~ 且剛剛所按鍵的字母不會出現在Textarea之中」~

其實解法不會太困難~ 我的解法如下:

<script>
function handleKeyPress(evt)
{
	var nbr = (window.event)?event.keyCode:evt.which;
	if(nbr == 96)
	{
		//do something....
		return false;
	}
}
</script>
<textarea id="content" rows="20" cols="65" onKeyPress="return handleKeyPress(event)">

和先前所處理的「Submit, but No Page Refresh!!」有著異曲同工之妙~ ^^

2008-06-11 01:28:19 | Add Comment

BUEditor - A plain textarea editor for Drupal

BUEditor.是一個Internet文字編輯工具~ 頂頂大名的「Drupal」(content management platform)就是採用它來當做線上的文字編輯工具~

由於工作上有需要「自行開發」一個類似的工具~ 加上剛好同事在玩「Drupal」~ 我不小心發覺「Drupal」的線上文字編輯工具其實蠻不錯用的~

所以... 我的工作來了~ 就是去trace「Drupal」的這個編輯工具是怎麼寫的~ XD

在trace的過程之中~ 發現Drupal是採用「BUEditor」來達成的~ 這下子範圍就縮小了一點~

我直接去下載「BUEditor」整個原始碼來看~

呵~ 其實最重要的核心文字編輯莫過於下面這幾行程式了~ 呼~ 今天有點收獲~ ^^

相關工具

FCKeditor - the text editor for internet

相關資源

Enable tabbing inside textarea - roScripts

2008-05-27 16:01:45 | Comments (5)

Submit, but No Page Refresh!!

自從2005年Jesse James Garrett提出了「Ajax: A New Approach to Web Applications」之後~ 使得網路應用程式蔚為風潮~

更完全巔覆「<form>...</form>」的操作模式~ 取而代之的則是一大堆「Document Object Model」~

重點來了~ 我們來考慮下述這一個情況:

<script>
function doSearch()
{
	var value = document.getElementById("keyword").value;
	alert(value);
}
</script>
<input type="input" id="keyword" size="15"/>
<input type="submit" value="search" onClick="doSearch();"/>

這個簡單的頁面測試,若是在IE上執行的話~ 當我們在文字輸入欄位填入一些關鍵字之後~ 接著直接按鍵盤上的「Enter」~ IE會為我們馬上提交送出!

然而~ 在Firefox卻不是那麼回事~ 你會發覺同樣的程式及語法在Firefox上按「Enter」之後~ 根本毫無作用~

這對於使用者的操作行為的確會造成大問題~ 因為使用者習慣在輸入文字之後~ 通常會直接按下「Enter」送出資料~

好了~ 或許有人會說那乾脆用「<form>...</form>」的方式來處理不就好了~ 的確~ 這能解決一部份的問題~ 但,如果你的網頁應用程式是採用「Ajax」技術的話~ 怎麼可以讓頁面Refresh呢!! 這不就又走回頭路了...

所以~ 我們需要一種方式來解決這樣的問題~

由於今天剛好在開發Ajax應用程式~ 未來的「Swiler」線上版應該也會用到~ 所以花了一點時間嘗試著解決這樣的問題~

Submit, but No Page Refresh!!

<script>
function doSearch()
{
	var value = document.getElementById("keyword").value;
	alert(value);
	return false;
}
</script>
<form onSubmit="return doSearch();">
<input type="input" id="keyword" size="15"/>
<input type="submit" name="dowiki" value="search"/>
</form>

我的解法只是用了個小技巧~ 仍然採用「<form>...</form>」的方式~ 重點就在於我加了個「onSubmit="return doSearch();"」,並且「doSearch()」這個Function是永遠回傳「false」,如此不就達到「Submit, but No Page Refresh!!」~ 開開心心地去用「Ajax」吧~ ^^v

2008-05-13 01:11:24 | Comments (2)

跨網域請求(三) - Cross Domain Proxy

這種跨網域技術的方式最大的優點在於~ 他只需要單方面的向你所想要請求的資源進行溝通即可~

也就是說,我們先前所曾介紹過的「跨網域請求(二) - Flash Plug-In」、「跨網域請求(一) - Cross-Domain Script Tag」都需要雙方遵循著某種條件才能達成進行溝通~

而最簡單的例子不外乎像是Flickr所提供的API~ 它就是採用「Cross-Domain Script Tag」來達成的~

不過利用「Cross Domain Proxy」最大的缺點就在於~ 你需要將所有請求的資源都交由這台「Proxy」委任地去幫你處理~ 這將會造成「IP」被對方的伺服器封鎖,或是負荷過載的情形發生~ 所以這時就需要「CSProxy」才能解決這些問題~ 這部份留待以後再介紹~

我們就直接來看一個簡單的「Corss Domain Proxy」的例子,此例子以「Google Translate」為例:

Translate.php

<?php
require_once "HttpClient.php";

if($_POST)
{
	$sentence = $_POST['input'];
	$uri = "http://translate.google.com/translate_t";
	$data = array('langpair' => 'en|zh-TW', 'h1' => 'en', 'ie' => 'UTF8', 'text' => $sentence);

	$request = new HttpClient();
	$request->setContent($data);
	$request->setUri($uri);
	$body = $request->doAction();
	
	$regex = '/<div id=result_box dir=\"ltr\">(.*)<\/div><\/td>/Us';
	preg_match($regex,$body,$match);
	echo $match[1];
}
?>

HttpClient.php

此程式參考HTTP POST from PHP, without cURL,您可以自行修改並擴充~ 當然也歡迎您再分享您的成果 ^^

<?php
/**
 * Date: 2008/04/17
 * Shen(http://blog.ring.idv.tw)
 */
class HttpClient
{
	private $uri;
	private $params;

	function __construct()
	{
		$this->params = array
		(
			'http' => array
			(
				'method' => 'POST',
				'content' => '',
			)
		);
	}
	public function setUri($uri)
	{
		$this->uri = $uri;
	}
	public function setContent($content)
	{
		$this->params['http']['content'] = http_build_query($content);
	}
	public function doAction()
	{
		$ctx = stream_context_create($this->params);
		$fp = @fopen($this->uri, 'rb', false, $ctx);
	
		if(!$fp)
			throw new Exception("Problem: $php_errormsg");
	
		$response = @stream_get_contents($fp);
		if ($response === false)
			throw new Exception("Problem: $php_errormsg");
	
		return $response;
	}
}
?>

2008-04-17 23:50:55 | Add Comment

Next Posts~:::~Previous Posts
Copyright (C) Ching-Shen Chen. All rights reserved.

::: 搜尋 :::

::: 分類 :::

::: Ads :::

::: 最新文章 :::

::: 最新回應 :::

::: 訂閱 :::

Atom feed
Atom Comment