Javascript 中阻止浏览器默认操作

在浏览器事件中,会触发一些默认动作,比如:点击一个链接时,执行完捕获/冒泡动作后,会触发链接的默认事件:跳转到指定链接地址。

在很多时候,我们需要改变这些默认操作,比如:点击一个链接时,我们执行一些 ajax 操作,但是我们并不希望执行跳转动作,于是,就有了本文:阻止浏览器默认操作。

其实这并不是一个非常难的课题,单独拿出来的原因还是浏览器兼容问题:

 
<script type="text/javascript">
 
// 说明:Javascript 中阻止浏览器默认操作
// 作者:John Resig
// 来源:CodeBit.cn ( http://www.CodeBit.cn )
 
function stopDefault( e ) {
	// Prevent the default browser action (W3C)
	if ( e && e.preventDefault )
		e.preventDefault();
	// A shortcut for stoping the browser action in IE
	else
		window.event.returnValue = false;
	return false;
}
</script>

使用示例:

 
<a href="http://www.google.com" id="testLink">Google</a>
 
<script type="text/javascript">
var test = document.getElementById('testLink');
test.onclick = function(e) {
	alert('我的链接地址是:' + this.href + ', 但是我不会跳转。');
	stopDefault(e);
}
</script>

负边距(negative margin)的相关问题整理

负边距(negative margin)在页面制作过程中,有许多妙用,用的好了能让原本复杂的问题变的简单,本文是针对负边距相关问题的整理,欢迎各位补充。

负边距的使用非常简单:

 
<style type="text/css">
/*
说明:负边距(negative margin)的相关问题整理 
整理:CodeBit.cn ( http://www.codebit.cn )
*/
.one {
	height:100px;
	width:300px;
	border:2px solid red;
	margin-bottom:-10px;
}
.two {
	height:100px;
	width:300px;
	border:2px solid blue;
}
</style>
 
<p class="one"></p>
<p class="two"></p>

这时,我们会看到蓝色的框伸到了红色框的里面,下面总结一些问题:

如何改变覆盖顺序

在本例中,就是如何让红色框覆盖蓝色框,很简单,在需要覆盖到上面的元素样式中添加 : position:relative; 在本例中,就是要在红色的样式 .one 中添加。

负边距可以用在哪些地方:

导航高亮效果的实现:

 
<style type="text/css">
/*
说明:负边距(negative margin)的相关问题整理 
整理:CodeBit.cn ( http://www.codebit.cn )
*/
.nav, .nav li {
	list-style:none;
}
.nav li {
	border:2px solid #000;
	float:left;
	margin-left:10px;
	background:#333;
	padding:3px 20px;
	margin-bottom:-2px; /* 遮盖下面内容的边框部分 */
	position:relative; /* IE 下要添加此行 */
}
.nav a {
	color:#fff; 
	text-decoration:none;
}
.nav li.current {
	border-bottom:2px solid #eee; /* 当前的把下边框的颜色换成和下边内容相同的 */
	background:#eee; /* 背景的颜色也换成相同的 */
}
.nav li.current a {color:#000;}
.content {
	border:2px solid #000;
	background:#eee;
	height:100px;
	width:300px;
	clear:both;
}
</style>
 
<ul class="nav">
	<li class="current"><a href="">当前</a></li>
	<li><a href="">导航</a></li>
	<li><a href="">导航</a></li>
</ul>
<div class="content">
</div>

结果:

注意:firefox 下面 .nav li 不用加 position:relative; 也能覆盖到下面的 div ,但是 ie 下面要加上。

修正 IE 的 bug

相信大家都很了解 IE 的 3 像素 bug,当浮动元素和非浮动元素相邻时,会增加额外的 3 像素,这个时候,我们就可以用负边距来解决(并非唯一的办法):

 
<style type="text/css">
/*
说明:负边距(negative margin)的相关问题整理 
整理:CodeBit.cn ( http://www.codebit.cn )
*/
#floatContent {
	float: left;
	width: 300px;
}
#otherContent {
	margin-left: 300px;
}
/* 对 MacIE 隐藏 */
* html #floatContent {
	margin-right: -3px;
}
* html #otherContent {
	height: 1%; /* 如果你没有设置 #otherContent 的高度或者宽度 */
	margin-left: 0;
}
/* 隐藏结束 */
</style>

这里只是列举了部分和负边距相关的问题,欢迎各位修正、完善。

Zend Framework 中配合 Zend_Config 实现路由(Router)规则单独存储

Zend Framework 的路由转发功能不仅可以让 url 变得简洁易记,而且非常对 SEO 非常有益,zf 的路由转发有着多样的配置方法,能实现各种转发需求。

随着站点复杂程度的增加,我们会有越来越多的转发规则,而将这些规则独立到一个文件中,是一个非常好的习惯。本文讲解的是将转发规则存放在单独的配置文件里面,然后配合 Zend_Config 实现转发的方法。

对于直接在程序中实现转发设置,手册上有简单的示例:

 
<?php
 
/*
说明:设置 Zend Framework 路由转发
整理:CodeBit.cn [ http://www.codebit.cn ]
*/
 
$router = $controller->getRouter(); // 获取路由
$route = new Zend_Controller_Router_Route(
    'author/:username',
    array(
        'controller' => 'profile',
        'action'     => 'userinfo'
    )
);
 
$router->addRoute('user', $route);
 
?>

上面的规则能将 http://domain.com/author/martel 指向到 http://domain.com/profile/action/author/martel ,这样设置,能大大降低 url 的复杂程度,让 url 简单明了。

我们如果有多条这种规则,就可以考虑将规则放到单独的文件中,手册上是用 ini 文件存储路由规则,我这里则使用 php 数组存储:

 
<?php
 
/*
说明:用单独的 php 文件存储路由转发规则
整理:CodeBit.cn [ http://www.codebit.cn ]
*/
 
return array(
 
	// 将 /view/123 映射为 /default/index/index/id/123
	'view'	=>	array(
		'route'	=>	'view/:id',
		'defaults'	=>	array(
			'module'	=>	'default',
			'controller'	=>	'index',
			'action'	=>	'index',
		),
	),
 
	// 将 http://domain.com/author/martel 映射为 http://domain.com/profile/action/author/martel
	'profile'	=>	array(
		'route'	=>	'author/:username',
		'defaults'	=>	array(
			'controller'	=>	'profile',
			'action'	=>	'userinfo',
		),
	),
	
);
 
?>

对于从数组中取出规则,然后设置 Zend_Controller_Router_Rewrite ,手册也有一段示例:

 
<?php
 
$routerConfig = new Zend_Config(require_once 'routes.php');
$routerRules = new Zend_Controller_Router_Rewrite();
$router->addConfig($routerRules);
 
?>

不过,手册上没有如何将上面的路由规则应用到当前 controller 的示例,这个也是让新手很头疼的问题,研究过 zend framework 的源码后,我们可以很容易发现解决方法:

 
<?php
 
/*
说明:用单独的 php 文件存储路由转发规则
整理:CodeBit.cn [ http://www.codebit.cn ]
*/
 
$routerConfig = new Zend_Config('routes.php'); // 加载配置
$routerRules = new Zend_Controller_Router_Rewrite();
$routerRules->addConfig($routerConfig); // 设置规则
 
$routers = $controller->getRouter(); // 获取路由
$routers->addRoutes($routerRules->getRoutes()); // 通过 $routerRules->getRoutes() 获取规则,然后设置
 
?>

CSS 实现文字、图片垂直对齐(vertical-align)专题文章

垂直对齐在 Firefox 和 IE7 等最新浏览器中,已经不是什么难事,但是IE6下使用 DIV 布局,垂直对齐则依然是个非常令人头痛的问题;虽然 IE 7 已经越来越普及,但是 IE6 依然占了很大的份额,所以,还是让我们一起看看解决方法吧!

CSS 实现文字、图片垂直对齐(vertical-align)专题文章 – 示例

 
<style type="text/css">
 
/*
	说明:IE 6 下 DIV 垂直居中对齐
	来源:CssPlay [ http://www.cssplay.co.uk ]
	整理:CodeBit.cn [ http://www.codebit.cn ]
*/
.fixVerticalCenterOuter{
	width:300px;
	height:200px;
	border:1px solid #ccc;
	text-align:center;
	display:table-cell;
	vertical-align:middle;
}
 
/* for IE 6 */
* html .fixVerticalCenterAdd {
	width:0;
	height:100%;
	display:inline-block;
	vertical-align:middle;
}
* html .fixVerticalCenterInner{
	vertical-align:middle;
	display:inline-block;
}
 
</style>
 
<div class="fixVerticalCenterOuter">
	<span class="fixVerticalCenterAdd"></span><!-- // fixVerticalCenterAdd -->
	<span class="fixVerticalCenterInner"><a href="http://www.codebit.cn"><img src="http://www.codebit.cn/admin/tpl/default/img/logo.gif" alt="CodeBit.cn - 聚合小段精华代码" /></a></span><!-- // fixVerticalCenterInner -->
</div><!-- // fixVerticalCenterOuter -->

用 Javascript 实现检测、添加、移除样式(className)

在前台脚本中,我们经常要操作页面元素的样式,比如标签页切换时,将当前标签加上一个样式,当切换到其他标签时,再将样式还原,本文介绍的是直接添加和移除 className 的方法。

 
<script type="text/javascript">
 
// 说明:添加、移除、检测 className
// 整理:CodeBit.cn ( http://www.codebit.cn )
 
function hasClass(element, className) {
	var reg = new RegExp('(\s|^)'+className+'(\s|$)');
	return element.className.match(reg);
}
 
function addClass(element, className) {
	if (!this.hasClass(element, className))
	{
		element.className += " "+className;
	}
}
 
function removeClass(element, className) {
	if (hasClass(element, className)) {
    	var reg = new RegExp('(\s|^)'+className+'(\s|$)');
		element.className = element.className.replace(reg,' ');
	}
}
 
</script>

MySQL 中将一个表的数据插入另外一个表的方法

开发中,我们经常需要将一个表的数据插入到另外一个表,有时还需要指定导入字段,虽然这个实现起来非常简单,但是还是会困扰许多新手,因此专门发一篇文章备查。

如果2张表的字段一致,并且希望插入全部数据,可以用这种方法:

 
INSERT INTO 目标表 SELECT  * FROM 来源表;

比如要将 articles 表插入到 newArticles 表中,则是:

 
INSERT INTO newArticles SELECT  * FROM articles;

如果只希望导入指定字段,可以用这种方法:

 
INSERT INTO 目标表 (字段1, 字段2, ...) SELECT  字段1, 字段2, ...  FROM 来源表;

注意字段的顺序必须一致。

如果您需要只导入目标表中不存在的记录,可以参考另外一篇文章

MySQL 当记录不存在时插入(insert if not exists)

Javascript 中 String.replace( ) 的妙用

String.replace( ) 简介

语法:

 
string.replace(regexp, replacement)

regexp :您要执行替换操作的正则表达式,如果传入的是一个字符串,那就会当作普通字符来处理,并且只会执行一次替换操作;如果是正则表达式,并且带有 global (g) 修饰符,则会替换所有出现的目标字符,否则,将只执行一次替换操作。

replacement :您要替换成的字符。

返回值是执行替换操作后的字符串。

String.replace( ) 的简单用法

 
var text = "javascript 非常强大 !";
text.replace(/javascript/i, "JavaScript");
// 返回:JavaScript 非常强大 !

String.replace( ) 替换所有出现的目标字符

 
var text= "javascript 非常强大 !JAVASCRIPT 是我最喜欢的一门语言 !";
text.replace(/javascript/ig, "JavaScript");
// 返回:JavaScript 非常强大 !JavaScript 是我最喜欢的一门语言 !

String.replace( ) 实现调换位置

 
var name= "Doe, John";
name.replace(/(w+)s*,s*(w+)/, "$2 $1");
// 返回:John Doe

String.replace( ) 实现将所有双引号包含的字符替换成中括号包含的字符

 
var text = '"JavaScript" 非常强大!';
text.replace(/"([^"]*)"/g, "[$1]");
// 返回:[JavaScript] 非常强大!

String.replace( ) 将所有字符首字母大写

 
var text = 'a journey of a thousand miles begins with single step.';
text.replace(/bw+b/g, function(word) {
                           return word.substring(0,1).toUpperCase( ) +
                                  word.substring(1);
                         });
 
// 返回:A Journey Of A Thousand Miles Begins With Single Step.

Javascript 中截取小数位并实现四舍五入的方法

在 CodeBit.cn 的论坛中,有人问 Javascript 中如何截取小数位并实现四舍五入,这是一个很常用的 js 技术,帖子中也有网友热心回复,因为觉得比较典型,可能很多新手都会遇到此问题,所以将帖子整理了一下,以备新手查阅。

round 方法

作用:返回与给出的数值表达式最接近的整数。
语法:Math.round(number) ,必选项 number 参数是要舍入到最接近整数的值。
说明:如果 number 的小数部分大于等于 0.5,返回值是大于 number 的最小整数。否则,round 返回小于等于 number 的最大整数。

示例:

 
// 如果取一位则乘以 10 之后再除以 10, 以此类推
Math.round(3.248 * 100) / 100

Javascript 1.5 新增函数

在 Javascript 1.5 (IE5.5+ , NS6+ 以上版本支持)中,新增了2个专门用于货币流通的函数:
Number.toFixed(x) 和 Number.toPrecision(x)。

Number.toFixed(x) 是将指定数字截取小数点后 x 位, Number.toPrecision(x) 是将整个数字截取指定(x)长度。注意,一个是计算小数点后的长度,一个是计算整个数字的长度 。

请看完整示例:

 
<script type="text/javascript">
 
var aa = 2.3362;
 
document.write(aa.toFixed(1)); // 2.3
document.write(aa.toFixed(2)); // 2.34
 
document.write(aa.toPrecision(2)); // 2.3
document.write(aa.toPrecision(3)); // 2.34
 
document.write(Math.round(aa * 10) / 10); // 2.3
document.write(Math.round(aa * 100) / 100); // 2.34
 
</script>

显然,新增的 2 个专用函数使用非常方便,但是因为是新增函数,所以要考虑浏览器支持问题,请根据您的客户群选择对应的方法。

在 Zend Framework 应用中使用 Smarty 做模版引擎

Zend Framework 是 PHP 官方出的开发框架,随着 PHP5 的推广,越来越多的人开始学习、使用 Zend Framework。 Smarty 是一个非常强大的模版引擎,由于其完善的语法、内置的缓存功能,已经被众多开发人员应用在自己的开发项目中。

正因为二者的强大,因此有越来越多的人开始考虑将 Smarty 集成到 Zend Framework ,以便充分的发挥各自的优点。本文翻译自 Zend Developer Zone 。翻译为意译,由于水平有限,纰漏在所难免,欢迎指出翻译中出现的问题。本文为 CodeBit.cn ( http://www.codebit.cn ) 组织翻译,转载请注明出处。

原文作者首先指明了整合的目的:(1)保留 Zend_View 提供的 API;(2)利用 Smarty 提供的缓存功能。

目录结构:

文件名是按照作者的公司(Travello)命名:

 
  /Zend
    /View
  /Travello
    /View
      Smarty.php

定义类和构造函数:
首先是定义类和构造函数, Travello_View_Smarty 是继承自 Zend_View_Abstract,在构造函数中首先调用了父类的构造函数,然后将初始化好的 Smarty 对象存储在 private 属性中。

注意:这里使用了 configuration 对象存取 Smarty 的配置信息。

 
<?php
 
class Travello_View_Smarty extends Zend_View_Abstract
{
    private $_smarty = false;
    
    public function __construct($data = array())
    {
        parent::__construct($data);
        
        $config = Zend::registry('config');
        
        $this->_smarty = new Smarty();
        
        $this->_smarty->caching = $config->getSetting('smarty', 'caching');
        $this->_smarty->cache_lifetime = $config->getSetting('smarty', 'cache_lifetime');
        $this->_smarty->template_dir = $config->getSetting('smarty', 'template_dir');
        $this->_smarty->compile_dir = $config->getSetting('smarty', 'compile_dir');
        $this->_smarty->config_dir = $config->getSetting('smarty', 'config_dir');
        $this->_smarty->cache_dir = $config->getSetting('smarty', 'cache_dir');
    }

实现 _run() 方法:
_run() 是唯一的需要在 Zend_View_Abstract 子类中实现的方法,他会自动在 render() 方法中被调用,这里使用了 Smarty 的 display() 方法来输出模版。

 
<?php
 
    protected function _run($template)
    {
        $this->_smarty->display($template);
    }

重写 assign() 方法:
下面是要重写 Zend_View_Abstract 下面的 assign() 方法,我们直接将参数值赋到 Smarty 对象,而不是默认的 Zend_View_Abstract 的 $this->_vars 数组。

 
<?php
 
    public function assign($var)
    {
        if (is_string($var))
        {
            $value = @func_get_arg(1);
            
            $this->_smarty->assign($var, $value);
        }
        elseif (is_array($var))
        {
            foreach ($var as $key => $value)
            {
                $this->_smarty->assign($key, $value);
            }
        }
        else
        {
            throw new Zend_View_Exception('assign() expects a string or array, got '.gettype($var));
        }
    }

重写 escape() 方法:
下面是要重写 Zend_View_Abstract 下面的 escape() 方法,使用的是 Zend_View_Abstract 内置的 escape() 方法,但是能够根据传入的字符串或者数组作出相应处理。

 
<?php
 
    public function escape($var)
    {
        if (is_string($var))
        {
            return parent::escape($var);
        }
        elseif (is_array($var))
        {
            foreach ($var as $key => $val)
            {
                $var[$key] = $this->escape($val);
            }
 
            return $var;
        }
        else
        {
            return $var;
        }
    }

打印输出:
output() 是对 Zend_View_Abstract 中 render() 方法的封装,增加了一些 header 设置:

 
<?php
 
    public function output($name)
    {
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Cache-Control: no-cache");
        header("Pragma: no-cache");
        header("Cache-Control: post-check=0, pre-check=0", FALSE);
 
        print parent::render($name);
    }

使用 Smarty 的缓存:
最后的2个方法是为了在 View 类中整合 Smarty 的缓存机制,第一个方法是检查是否已经缓存,第二个是设置是否打开缓存功能。

 
<?php
 
    public function isCached($template)
    {
        if ($this->_smarty->is_cached($template))
        {
            return true;
        }
        
        return false;
    }
 
    public function setCaching($caching)
    {
        $this->_smarty->caching = $caching;
    }
} // end Travello_View_Smarty
 
?>

上面是完整的 Travello_View_Smarty 代码。

使用说明:
使用非常简单,在你的导入文件(通常是 index.php ,译注)中,可以用下面的方法初始化, $viewConfig 是设置 Zend_View 的路径,一旦创建好对象后,就将他存在对象中,方便后面调用。

 
<?php
 
$viewConfig = array();
$viewConfig['scriptPath'] = $config->getSetting('framework', 'view_dir');
 
$view = new Travello_View_Smarty($viewConfig);
Zend::register('view', $view);
 
?>

在你的 controller 和 action 方法中可以这样使用:

 
<?php
 
    public function indexAction()
    {
        $temp_file = 'homepage.htm';
        
        $view = Zend::registry('view');
        
        if (false === $view->isCached($temp_file))
        {
            $vars = array();
            $vars['title'  ] = 'Page <title>';
            $vars['text'   ] = 'A text is a text & a text is a text.';
            $vars['numbers'][0] = 12.9;
            $vars['numbers'][1] = 29;
            $vars['numbers'][2] = 78;
            
            $vars = $view->escape($vars);
            
            $view->assign($vars);
        }
        
        $view->output($temp_file);
    }
 
?>

原文地址:
http://devzone.zend.com/node/view/id/120

批量替换 MySQL 指定字段中的字符串

批量替换 MySQL 指定字段中的字符串是数据库应用中很常见的需求,但是有很多初学者在遇到这种需求时,通常都是用脚本来实现;其实,MySQL 内置的有批量替换语法,效率也会高很多;想了解具体方法,继续阅读本文吧 :)

批量替换的具体语法是:

 
UPDATE 表名 SET
指定字段 = replace(指定字段, ’要替换的字符串’, ’想要的字符串’) 
WHERE 条件;

如果你想把 article 表中 ID 小于5000的记录,content 字段中“解决”替换成“解放”,那么语法就是:

 
UPDATE article SET
content = replace(content, ’解决’, ’解放’) 
WHERE ID<5000;

是不是很方便 :)