Ext.BLANK_IMAGE_URL

本文深入解析了在使用ExtJS时,设置Ext.BLANK_IMAGE_URL的重要性和其背后的原因,解释了不设置该变量可能带来的问题及解决方案,特别强调了如何利用CSS解决界面换肤问题。

在使用ExtJS时,我们往往需要在使用之前加入这么一句:
Ext.BLANK_IMAGE_URL = "....."其中省略部分为s.gif在extjs包中的路径。
那么ExtJS为什么要设置这样一个变量呢?如果我们不这样做会带来什么后果?
首先说后果:
如果没有以上那句代码,Ext会按照默认的地址:http://www.extjs.com/s.gif去下载这张图片,由于网络不通或者速度较慢等原因,可能导致这张图片加载不成功,造成页面上很多小白条。
设置这个变量的原因:
原来ExtJS中在创建组件的时候,组件中需要替换图标的地方,初始化时都是拿这个s.gif替代的,如果用户指定icon属性,它会将s.gif替换为icon的地址,说白了,s.gif就是一个占位的功能。
另外,如果看过ExtJS的源代码可能发现,它对于ie和air的默认实现是去url请求这张图片,而对于其它浏览器则直接使用图片解码,这是因为ie和air不支持图片解码。

----------------------------------------------------------------------------------------------------------

Ext.BLANK_IMAGE_URL

图片位置默认指向:
/resources/images/default/s.gif'

最近在看Ext中jack的window导航式例时,看到一个细节,让我顿时明白了作者的这一做法的初衷。
作者在对一些需要应用图片或者图标的地方,都没有显式写明要应用的图标(片)路径,
而都是通过css来配置,许多应用图标的地方刚开始都Ext.BLANK_IMAGE_URL来替代,
而在css在加载之后就会替换到真实的图标路径 。
这一招就彻底解决了界面的换肤问题。
看个例子:
在desktop例子中,快捷方式图标的初始路径是指向空白的images/s.gif
<dl id="x-shortcuts">
<dt id="grid-win-shortcut">
  <a href="#" mce_href="#">
   <img src="images/s.gif" mce_src="images/s.gif" />
   <div>Grid Window</div>
  </a>
</dt>
</dl>
然后,在css中修改为:
#grid-win-shortcut img {
    width:48px;
    height:48px;
    background-image: url(../images/grid48x48.png);
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/grid48x48.png', sizingMethod='scale');
}
有些需要图标修饰的组件在动态创建时,图标的src一般都是指向Ext.BLANK_IMAGE_URL ,
然后呢,再在css指向特定的图标位置。
然后以后要换肤的话,直接替换css文件就可以了。
最后实践也证明,如果没有正确配置这个BLANK_IMAGE_URL,
可能在许多控件上显示不了css文件中定义的装饰图标。

class FilePreviewHandler(tornado.web.RequestHandler): async def get(self): pool_name = self.get_argument("pool") raw_file_name = self.get_argument("file") file_name = urllib.parse.unquote(raw_file_name) if pool_name not in RESOURCE_POOLS: self.set_status(404) self.render("404.html") return pool_path = RESOURCE_POOLS[pool_name]["path"] file_path = os.path.normpath(os.path.join(pool_path, file_name)) real_request_path = os.path.realpath(file_path) real_pool_path = os.path.realpath(pool_path) if not real_request_path.startswith(real_pool_path): self.set_status(403) self.write("禁止访问此文件路径") return if not os.path.exists(file_path): self.set_status(404) self.render("404.html") return ext = os.path.splitext(file_name)[1].lower() # 特别处理 PDF 文件:使用本地 PDF.js 预览 if ext == ".pdf": # 构造预览链接,不要双重编码 proxy_url = f"/preview?pool={pool_name}&file={urllib.parse.quote(file_name)}" # 传递原始 URL,不要再次编码 pdf_url = f"/static/pdfjs/web/viewer.html?file={proxy_url}" self.redirect(pdf_url) return # 设置 MIME 类型 mime_type = { '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', '.pdf': 'application/pdf', '.txt': 'text/plain', '.md': 'text/markdown', '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.mp4': 'video/mp4', '.webm': 'video/webm', '.ogg': 'video/ogg', '.mp3': 'audio/mpeg', '.wav': 'audio/wav', '.flac': 'audio/flac', }.get(ext, mimetypes.guess_type(file_name)[0] or 'application/octet-stream') encoded_filename = urllib.parse.quote(file_name.encode('utf-8')) self.set_header("Content-Disposition", f'inline; filename*=UTF-8\'\'{encoded_filename}') file_size = os.path.getsize(file_path) range_header = self.request.headers.get('Range') is_download = not range_header and ext in ['.mp4', '.webm', '.ogg', '.pdf'] if is_download: self.set_header('Content-Type', mime_type) self.set_header('Content-Length', str(file_size)) self.set_status(200) if os.name == 'posix': fd = os.open(file_path, os.O_RDONLY) try: await tornado.ioloop.IOLoop.current().run_in_executor( None, os.sendfile, self.request.connection.fileno(), fd, None, file_size ) finally: os.close(fd) else: with open(file_path, 'rb') as f: while True: chunk = f.read(1024 * 1024 * 4) if not chunk: break try: self.write(chunk) await self.flush() except tornado.iostream.StreamClosedError: return self.finish() elif ext in ['.mp4', '.webm', '.ogg', '.pdf', '.mp3', '.wav', '.flac']: self.set_header('Accept-Ranges', 'bytes') start = 0 end = file_size - 1 if range_header: self.set_status(206) start_bytes, end_bytes = range_header.replace('bytes=', '').split('-') start = int(start_bytes) if start_bytes else 0 end = int(end_bytes) if end_bytes else file_size - 1 self.set_header('Content-Range', f'bytes {start}-{end}/{file_size}') self.set_header("Content-Length", str(end - start + 1)) self.set_header('Content-Type', mime_type) chunk_size = 4096 * 16 async with aiofiles.open(file_path, 'rb') as f: await f.seek(start) remaining = end - start + 1 while remaining > 0: chunk = await f.read(min(chunk_size, remaining)) if not chunk: break try: self.write(chunk) await self.flush() except tornado.iostream.StreamClosedError: return remaining -= len(chunk) self.finish() elif ext == '.txt': self.set_header('Content-Type', 'text/plain; charset=UTF-8') async with aiofiles.open(file_path, 'r', encoding='utf-8') as f: content = await f.read() self.write(content) self.finish() elif ext in ['.png', '.jpg', '.jpeg', '.gif', '.md', '.pdf', '.docx', '.xlsx', '.pptx']: self.set_header('Content-Type', mime_type) async with aiofiles.open(file_path, 'rb') as f: data = await f.read() self.write(data) self.finish() else: self.set_status(400) self.write("不支持预览此文件类型") 这是我的这个方法,你在我提供的这个方法代码中修改后给我把修改后的方法代码完整的给我提供过来吧
最新发布
08-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值