2009-08-07

兼容IE6,IE7,IE8和Firefox的图片上传预览效果

类归于: JavaScript — 标签:, , maker @ 00:29

所谓图片上传预览,就是在使用文件选择框选择了文件之后就可以在页面上看见图片的效果,关于这个效果我一直认为是无法做到的,没想到前不久被zhuozi搞定了。

网上流传的一些关于图片上传预览的代码都是差不多的,IE6下使用文件选择对象的value属性取出将要上传的本地文件路径,然后使用本地路径构造img标签,代码如下:

<input type="file"
onchange="document.getElementById('view').innerHTML=' <img src=\'' + this.value + '\'/>';" />
<div id="view"> </div>

网上有些人说上面的代码可以在IE7下生效,但实际测试是不行的,因为IE7的img标签不支持本地路径,所以需要使用div和css的filter来实现这个效果,代码如下:

<input type="file" onchange=‘javascript:
document.getElementById("pic").filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src
= this.value;’ /><br />
<div id="pic"
style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);
width:400px;height:200px;"></div>

而关于Firefox的图片上传预览效果,网上几乎找不到相关资料,比较容易想到的解决方案无非是自动将图片上传到服务器再显示出来诸如此类,但这里我们不对此类技术进行讨论,我们要做的是正宗的上传前本地预览。

以下是最后的研究结果,同时兼容IE6,IE7,IE8和Firefox

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
var picPath;
var image;
// preview picture
function preview()
{
document.getElementById('preview').style.display = 'none';
// 下面代码用来获得图片尺寸,这样才能在IE下正常显示图片
document.getElementById('box').innerHTML
= "<img width='"+image.width+"' height='"+image.height+"' id='aPic' src='"+picPath+"'>";
}
// show view button
function buttonShow()
{
/*
这里用来解决图片加载延时造成的预览失败.
简单说明一下,当image对象的src属性发生改变时JavaScript会重新给image装载图片内容,
这通常是需要一些时间的,如果在加载完成之前想将图片显示出来就会造成错误,所以我们
通过图片的宽度和高度来判断图片是否已经被成功加载,加载完毕才会显示预览按钮.
这里我仍然有一个困惑,在IE7下预览效果偶尔会失效.
*/
if ( image.width == 0 || image.height == 0 ) {
setTimeout(buttonShow, 1000);
} else {
document.getElementById('preview').style.display = 'block';
}
}
function loadImage(ele) {
picPath   = getPath(ele);
image     = new Image();
image.src = picPath;
setTimeout(buttonShow, 1000);
}
function getPath(obj)
{
if(obj)
{
//ie
if (window.navigator.userAgent.indexOf("MSIE")>=1)
{
obj.select();
// IE下取得图片的本地路径
return document.selection.createRange().text;
}
//firefox
else if(window.navigator.userAgent.indexOf("Firefox")>=1)
{
if(obj.files)
{
// Firefox下取得的是图片的数据
return obj.files.item(0).getAsDataURL();
}
return obj.value;
}
return obj.value;
}
}
</script>
</head>
<body>
<input type="file" name="pic" id="pic" onchange='loadImage(this)' />
<input id='preview' type='button' value='preview' style='display:none;' onclick='preview();'>
<div id='box'></div>
</body>
</html>

补充:
上面的代码经过测试貌似不是那么稳定,一些机器上的IE7会失效,我在6台电脑上测试,FF全通过,IE7下有一台没有通过,估计是和IE的设置有关, 而且即使可以正常使用也不是每次都可以成功显示出预览按钮,这个原因也没有找到,估计是图片加载失败什么的,所以例子里特殊处理的预览按钮的显示,即时预览功能失败也不影响其他功能。

下面是在我机器上IE7的测试图片:

image-upload-preview-ie7

2009-02-11

在symfony中使用FCKeditor上传图片附件

类归于: symfony — 标签:, , maker @ 13:31

在项目中我们经常需要使用富文本编辑器(什么是富文本?), 很多时候我们需要在我们编辑的内容中插入媒体文件, 比如图片,视频等等, 这就要涉及到富文本编辑器的上传功能, 本文主要讲解如何在symfony中使用FCKeditor和如何配置上传文件. 富文本编辑器我是更喜欢tinyMCE的, 但由于tinyMCE对上传的支持并不好, ImageManager等插件都是收费使用的, 所以不得不转向了FCKeditor. 首先我们进入FCKeditor的官方主页www.fckeditor.net下载源码包(http://www.fckeditor.net/download), 当前最新版本是2.6.4. 下载完源之后我们将压缩包解压到项目的web/js目录下, 修改要使用FCKeditory的app的config/settings.yml, 添加代码如下: all:
  .settings:
    rich_text_fck_js_dir: js/fckeditor
如果不使用上传功能, 那么现在FCKeditory就可以使用了. // app/editor/modules/test/templates/indexSuccess.php
<?php use_helper('Form');?>
<?php echo textarea_tag('name', 'default content', array ('rich'=>'fck','tool'=>'Basic','size' => '30x30')) ?>
访问http://test/editor_dev.php/test/index 效果如下 2009-02-11-124911_350x517_scrot 接下来开始配置上传图片附件, 这个功能是FCKeditor的功能, 所以要在FCKeditor进行配置. 首先编辑web/js/fckeditor/fckconfig.js var _FileBrowserLanguage    = 'php' ;    // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage    = 'php' ;    // asp | aspx | cfm | lasso | php
然后编辑 web/js/fckeditor/editor/filemanager/connectors/php/config.php $Config['Enabled'] = true;
$Config['UserFilesPath'] = '/uploads/';
web/js/fckeditor/editor/filemanager/connectors/php/config.php中还可以配置上传的其他相关参数, 比如文件类型等等. 现在上传功能就设置好了. // app/editor/modules/test/templates/indexSuccess.php
<?php use_helper('Form');?>
<?php echo textarea_tag('name', 'default content', array ('rich'=>'fck','tool'=>'Default','size' => '30x30')) ?>
访问页面打开插入图片功能, 画面如图. 2009-02-11-130238_622x608_scrot进入上传面板, 画面如图 2009-02-11-130249_627x619_scrot我们在本地选择图片, 进行上传, 如果使用的是symfony默认的配置, 应该会报错如下. 2009-02-11-130954_591x406_scrot 错误内容, Error creating folder “redirect:/index.php” (Can’t create redirect: directory) 经过一番研究, 最终发现这个错误是由apache的mod_rewrite造成的, 最终发现是web/.htaccess中的这一行导致的 RewriteRule ^([^.]+)$ $1.html      [QSA] 由于本人道行还不够, 最终也没有参透.htaccess中的代码都是什么作用, 但经过测试发现将这行去掉程序是可以正常运行的, 不过既然存在就一定有存在的意义, 所以使用了另一个方法来解决这个问题. 我们在web/uploads目录下再建立一个.htaccess, 内容如下 <IfModule mod_rewrite.c>
   RewriteEngine Off
</IfModule>
这样我们可以正常上传图片了. 2009-02-11-125927_617x749_scrot 在generator.yml中使用富文本编辑器 这里看一个例子, 出自《symfony权威指南》 generator:
  class: sfPropelAdminGenerator
  param:
    model_class: Comment
    theme: default
    edit:
      fields:
        ## 不显示表单控件, 只显示文本
        id: {type:plain}
        ## 表单控件不可编辑
        author:  {disabled=true}
        ## 富文本编辑器 (object_textarea_tag)
        content: {type: textarea_tag, params: rich=true css=user.css tinymce_options=width:330}
        ## 下拉列表 (object_select_tag)
        article_id: {params: include_custom=Choose an article}
如何在form中使用富文本编辑器? 《How to use FCKeditor》里提供了一个widget, 我没有用过, 但听同事说可能不好用, 所以自己写了一个. //lib/widget/sfWidgetFormFCK.class.php
<?
class sfWidgetFormFCK extends sfWidgetFormTextarea
{
   public function render($name, $value = null, $attributes = array(), $errors = array())
   {
     sfContext::getInstance()->getConfiguration()->loadHelpers('Form');
     return textarea_tag($name, $value, array_merge($attributes, array('rich' => 'fck', 'tool' => 'Default' )));
   }
}
//lib/form/ShopForm.class.php
<?php
class ShopForm extends BaseShopForm
{
   public function configure()
   {
     $this->setWidget('sid', new sfWidgetFormFCK());
   }
}
参考: 《Symfony TinyMCE & FCKeditor》 《How to use FCKeditor》 (本文完)

2008-12-26

symfony1.2中的文件上传和验证

类归于: symfony — 标签:maker @ 16:02

symfony 1.2中将文件上传操作从webRequest对象转到了sfFormProple对象上, 使用save方法会调用proccessUploadFile, 然后调用saveFile

需要在form中声明上传的路径, 这个很重要.
比如我们给file字段增加上传功能, 则应该加上这样一行.

$this->validatorSchema['file']->setOption('path', sfConfig::get('sf_upload_dir'));

或者

$this->validatorSchema['file'] = new sfValidatorFile(array('path' => sfConfig::get('sf_uploads_dir')));

上面的代码可以完成symfony中文件的自动上传功能,symfony1.2的form中还有另外一个很强大的功能, 那就是表单验证, 同样的, 上传文件也是可以使用validator进行验证的, 下面是一个例子.

$this->setValidator('filename' , new sfValidatorFile(array('path' => sfConfig::get('sf_upload_dir'), 'required' => false, 'mime_types' => 'web_images', 'max_size' => SettingPeer::getSetting('shopPicMaxSize'))));

WordPress 所驱动