Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【富文本】268- 富文本原理了解一下?

【富文本】268- 富文本原理了解一下?

作者头像
pingan8787
发布于 2019-07-25 03:15:48
发布于 2019-07-25 03:15:48
2.1K00
代码可运行
举报
文章被收录于专栏:前端自习课前端自习课
运行总次数:0
代码可运行

缘起

最近产品想让我在富文本里加个旋转图片的功能,我一想?,就觉得事情并不简单,因为印象中好像没见过这种操作。果然,经过一番百度之后,确实没怎么看到相关信息,这也就意味着要自己动手丰衣足食了?。但我自己对富文本又没什么了解,所以顺带稍微看了下富文本的实现方式,特此来沉淀一下,还是那句话不喜勿喷哈?。 ok,这里先简要说下为什么会有富文本这种东西吧?!大概可能也许是因为有一天产品用着用着 textarea 感觉太单调了,单纯的文字已经无法表达他们内心的需求?,于是就想来点样式,顺便加个图片,来篇图文并茂的文章,就像小型 Word 那样,就再好不过了!于是富文本就这样诞生了,开发者们也纷纷开始了踩坑之旅???。

前置知识

好了,交代完了背景,让我们先补充一些基础知识吧,不懂的请务必不要跳过?!

contenteditable 属性

假如我们给一个标签加上 contenteditable="true" 的属性,就像这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div contenteditable="true"></div>

那么在这个 div 中我们就可以对其进行任意编辑了。如果想要插入的子节点不可编辑,我们只需要把子节点的属性设置为 contenteditable="false" 即可,就像这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div contenteditable="true">
    <p>这是可编辑的</p>
    <p contenteditable="false">这是不可编辑的</p>
</div>

该属性最早是在 IE 上实现的(厉害哦?),且可以作用于其它标签,不限于 div,大家应该或多或少都听说过这个属性。

document.execCommand 方法

既然我们可以对上面的 div 随意编辑,那具体怎么编辑呢,目前好像也还是只能输入文本,要怎样才能进行其他操作呢(比如加粗、倾斜、插入图片等等)??其实浏览器给我们提供了这样的一个方法 document.execCommand,通过它我们就能够操纵上面的可编辑区。具体语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// document.execCommand(命令名称,是否展示用户界面,命令需要的额外参数)
document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

其中第一个参数就是一些命令名称,具体的可以查看 MDN;第二个参数写死为 false 就行了,因为早前 IE 有这样一个参数,为了兼容吧,不过这个参数在现代浏览器中是没有影响的;第三个参数就是一些命令可能需要额外的参数,比如插入图片就要多传个 urlbase64 的参数,没有的话传个 null 就行。 我们简要列举下它的几个使用方式,大家就知道怎么用了?:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 加粗
document.execCommand('bold', false, null);
// 添加图片
document.execCommand('insertImage', false, url || base64);
// 把一段文字用 p 标签包裹起来
document.execCommand('formatblock', false, '<p>');

这个命令就是富文本的核心(所以务必记住),浏览器把大部分我们能想到的功能也都实现了,当然各浏览器之间还是有差异的,这里就不考虑了。

Selection 和 Range 对象

我们在执行 document.execCommand 这个命令之前首先要知道对谁执行,所以这里会有一个选区的概念,也就是 Selection 对象,它用来表示用户选择的范围或光标位置(光标可以看做是范围重合的特殊状态),一个页面用户可能选择多个范围(比如 Firefox)。也就是说 Selection 包含一个或多个 Range 对象( Selection 可以说是 Range 的集合),当然对于富文本编辑器来说,一般情况下,我们只会有一个选择区域,也就是一个 Range 对象,事实上大部分情况也是如此。 所以通常我们可以用 letrange=window.getSelection().getRangeAt(0) 来获取选中的内容信息( getRangeAt 接受一个索引值,因为会有多个 Range,而现在只有一个,所以写0)。 看得一头雾水??没关系,看下面两张图就懂了?:

一句话说就是:通过上面那句命令我们能够获取到当前的选中信息,一般会先保存下来,然后在需要的时候还原。此外 Selection 对象还有几个常用的方法, addRangeremoveAllRangescollapsecollapseToEnd 等等。 这个知识点是很重要的,因为它让我们有了操纵光标的能力(比如插入内容之后设置光标的位置),不过这篇文章中我并没有去深入它,只是浅出?。

目标

开篇一顿扯,下面让我们抓紧时间做一个属于自己的富文本吧?,大概会包含以下几个功能:加粗、段落、H1、水平线、无序列表、插入链接、插入图片、后退一步、向前一步等等。?,Let's do it!

起步

首先一个富文本大体分为两个区域,一个是按钮区,一个是编辑区。所以它的大致结构就像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
    <div class="xr-editor">
        <!--按钮区-->
        <div class="nav">
            <button>加粗</button>
            ...
        </div>
        <!--编辑区-->
        <div class="editor" contenteditable="true"></div>
    </div>
<template>
<!--全部样式就这些,这里就都先给出来了-->
<style lang="scss">
.xr-editor {
  margin: 50px auto;
  width: 1000px;
  .nav {
    display: flex;
    button {
      cursor: pointer;
    }
    &__img {
      position: relative;
      input {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        opacity: 0;
      }
    }
  }
  .row {
    display: flex;
    width: 100%;
    height: 300px;
  }
  .editor {
    flex: 1;
    position: relative;
    margin-right: 20px;
    padding: 10px;
    outline: none;
    border: 1px solid #000;
    overflow-y: scroll;
    img {
      max-width: 300px;
      max-height: 300px;
      vertical-align: middle;
    }
  }
  .content {
    flex: 1;
    border: 1px solid #000;
    word-break: break-all;
    word-wrap: break-word;
    overflow: scroll;
  }
}
</style>

嗯,起步工作到此结束,接下来就可以直接开始实现功能了?。

加粗

现在假如我们要实现加粗的效果,该怎么做呢?很简单,只要在点击加粗按钮的时候执行 document.execCommand('bold',false,null) 这句话,就能达到加粗的效果,就像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
    <div class="nav">
        <button @click="execCommand">加粗</button>
    </div>
    ...
</template>
<script>
export default {
  name: 'XrEditor',
  methods: {
    execCommand() {
      document.execCommand('bold', false, null);
    }
  }
};
</script>

让我们运行一下看看效果:

嗯,是的,就是这么简单的一句话就能搞定?。 当然了,我们开篇也说了我们的一切命令都是基于 document.execCommand 的,所以我们先小小改写一下上面代码中的 execCommand 方法,就像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
    <div class="nav">
        <button @click="execCommand('bold')">加粗</button>
    </div>
    ...
</template>
<script>
export default {
  name: 'XrEditor',
  methods: {
    execCommand(name, args = null) {
        document.execCommand(name, false, args);
    }
  }
};
</script>

这样一来代码就更具通用性了。实现列表、水平线、前进、后退功能和加粗是一样样的,只需传入不同的命令名即可,就像下面这样,这里就不一一赘述了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<button @click="execCommand('insertUnorderedList')">无序列表</button>
<button @click="execCommand('insertHorizontalRule')">水平线</button>
<button @click="execCommand('undo')">后退</button>
<button @click="execCommand('redo')">前进</button>

顺带给大家说几个注意点✍️:

  1. 有的同学可能用的不是 button 标签,然后执行命令就会无效,是因为点击其他标签大多都会造成先失去焦点(或者不知不觉就突然失去焦点了),再执行点击事件,此时没有选区或光标所以会没有效果,这点要留意一下。
  2. 我们执行的是原生的 document.execCommand 方法,浏览器自身会对 contenteditable 这个可编辑区维护一个 undo 栈和一个 redo 栈,所以我们才能执行前进和后退的操作,如果我们改写了原生方法,就会破坏原有的栈结构,这时就需要自己去维护,那就麻烦了。
  3. style 里面如果加上 scope 的话,里面的样式对编辑区的内容是不生效的,因为编辑区里面是后来才创建的元素,所以要么删了 scope,要么用 /deep/ 解决(Vue 是这样)。
段落

这个功能就是把光标所在行的文字用 p 标签包裹起来,为了演示方便,我们顺便把编辑区的 html 结构打印出来,所以让我们稍微改一下代码,就像下面这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
    <div class="xr-editor">
        <div class="nav">
            <button @click="execCommand('bold')">加粗</button>
            <button @click="execCommand('formatBlock', '<p>')">段落</button>
        </div>
        <div class="row">
            <div class="editor" contenteditable="true" @input="print"></div>
            <div class="content">{{ html }}</div>
        </div>
    </div>
</template>
<script>
export default {
  name: 'XrEditor',
  data() {
    return {
      html: ''
    };
  },
  methods: {
    execCommand(name, args = null) {
      document.execCommand(name, false, args);
    },
    print() {
      this.html = document.querySelector('.editor').innerHTML;
    }
  }
};
</script>

运行效果如下:

怎么样,是不是也很 easy,同理, h1 ~ h6 也是一样的,命令为 execCommand('formatBlock','<h1>'),也不赘述了。

插入链接

这个功能因为需要第三个参数,所以我们一般会给个提示框获取用户输入,然后再执行 execCommand('createLink',链接地址),代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<button @click="createLink">链接</button>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
createLink() {
  let url = window.prompt('请输入链接地址');
  if (url) this.execCommand('createLink', url);
}

效果如下:

插入图片链接也是异曲同工,只不过命令名不一样而已:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
insertImgLink() {
    let url = window.prompt('请输入图片地址');
    if (url) this.execCommand('insertImage', url);
}
插入图片

图片除了可以通过添加地址的形式外,还可以添加 base64 格式的图片,这里我们通过 readAsDataURL(file) 来读取图片,并执行 execCommand('insertImage',base64) 就大功告成啦,具体代码如下,并不复杂:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<button class="nav__img">插入图片
    <!--这个 input 是隐藏的-->
    <input type="file" accept="image/gif, image/jpeg, image/png" @change="insertImg">
</button>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
insertImg(e) {
    let reader = new FileReader();
    let file = e.target.files[0];
    reader.onload = () => {
        let base64Img = reader.result;
        this.execCommand('insertImage', base64Img);
        document.querySelector('.nav__img input').value = ''; // 解决同一张图片上传无效的问题
    };
    reader.readAsDataURL(file);
}

运行一下,看看效果:

这应该也不是很难。当然了,你也可以先上传到服务器处理返回 url 地址再插入也是可以的。 ?至此,一个简易版的富文本就完成了(当然了 bug 也是有的?,不过并不妨碍我们理解),具体代码可以参考 npm 上的 pell 包,它已经是个极简版的了。

进阶

其实富文本对文本的操作大多都可以用原生命令来实现,但是对图片的操作也许就不那么容易了,来个拉伸、旋转啥的就够我们折腾了?,所以这里以图片拉伸为例子着重讲解一下。

图片拉伸

我们先看下大致效果,大家也可以先停下来思考一分钟看看如何实现?:

?,首先我们要知道的是图片已经在编辑区了,所以当用户点击编辑区里面的图片时我们需要做些事件监听并有所处理,具体思路如下(这部分代码较多,不想看的可以略过,但标题要看):

1. 判断用户点击的是否是编辑区里面的图片

这个就是看点击事件 e.target.tagName 是不是 img 标签了,代码如下,应该比较简单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mounted() {
    this.editor = document.querySelector('.editor');
    this.editor.addEventListener('click', this.handleClick);
},
methods: {
    handleClick(e) {
        if (
            e.target &&
            e.target.tagName &&
            e.target.tagName.toUpperCase() === 'IMG'
        ) {
            this.handleClickImg(e.target);
        }
    }
}
2. 在点击的图片上创建个大小一样的 div

如果点击的是一个图片,那我们就创建一个 div ,暂且把这个 div 叫做蒙层吧,顺便先看张示意图:

也就是动态创建一个蒙层(和图片一样大小)以及四个拖拽顶点,并定位到和图片一样的位置,代码如下(代码有点多,可跳过,知道大致意思就行?):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
handleClickImg(img) {
    this.nowImg = img;
    this.showOverlay();
}
showOverlay() {
    // 添加蒙层
    this.overlay = document.createElement('div');
    this.editor.appendChild(this.overlay);
    // 定位蒙层和大小
    this.repositionOverlay();
},
repositionOverlay() {
    let imgRect = this.nowImg.getBoundingClientRect();
    let editorRect = this.editor.getBoundingClientRect();
    // 设置蒙层宽高和位置
    Object.assign(this.overlay.style, {
        position: 'absolute',
        top: `${imgRect.top - editorRect.top + this.editor.scrollTop}px`,
        left: `${imgRect.left -
          editorRect.left -
          1 +
          this.editor.scrollLeft}px`,
        width: `${imgRect.width}px`,
        height: `${imgRect.height}px`,
        boxSizing: 'border-box',
        border: '1px dashed red'
    });
    // 添加四个顶点拖拽框
    this.createBox();
},
createBox() {
    this.boxes = [];
    this.addBox('nwse-resize'); // top left
    this.addBox('nesw-resize'); // top right
    this.addBox('nwse-resize'); // bottom right
    this.addBox('nesw-resize'); // bottom left
    this.positionBoxes(); // 设置四个拖拽框位置
},
addBox(cursor) {
    const box = document.createElement('div');
    Object.assign(box.style, {
        position: 'absolute',
        height: '12px',
        width: '12px',
        backgroundColor: 'white',
        border: '1px solid #777',
        boxSizing: 'border-box',
        opacity: '0.80'
    });
    box.style.cursor = cursor;
    box.addEventListener('mousedown', this.handleMousedown);  // 顺便添加事件
    this.overlay.appendChild(box);
    this.boxes.push(box);
},
positionBoxes() {
    let handleXOffset = `-6px`;
    let handleYOffset = `-6px`;
    [{ left: handleXOffset, top: handleYOffset },
    { right: handleXOffset, top: handleYOffset },
    { right: handleXOffset, bottom: handleYOffset },
    { left: handleXOffset, bottom: handleYOffset }].forEach((pos, idx) => {
        Object.assign(this.boxes[idx].style, pos);
    });
},
3. 在四个顶点框上添加拖拽事件

这里我们会在四个顶点监听 mousedown 事件,按下鼠标时,首先会改变鼠标样式(就是鼠标会变成调整大小的那种图标),然后监听 mousemovemouseup 事件,计算出水平拖拽距离,然后重新设置图片大小和浮层大小,大概这么个意思,简要代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
handleMousedown(e) {
    this.dragBox = e.target;
    this.dragStartX = e.clientX;
    this.preDragWidth = this.nowImg.width;
    this.setCursor(this.dragBox.style.cursor);
    document.addEventListener('mousemove', this.handleDrag);
    document.addEventListener('mouseup', this.handleMouseup);
},
handleDrag(e) {
    // 计算水平拖动距离
    const deltaX = e.clientX - this.dragStartX;
    // 修改图片大小
    if (this.dragBox === this.boxes[0] || this.dragBox ===     this.boxes[3]) { // 左边的两个框
        this.nowImg.width = Math.round(this.preDragWidth - deltaX);
    } else { // 右边的两个框
        this.nowImg.width = Math.round(this.preDragWidth + deltaX);
    }
    // 同时修改蒙层大小
    this.repositionOverlay();
},
handleMouseup() {
    this.setCursor('');
    // 拖拽结束移除事件监听
    document.removeEventListener('mousemove', this.handleDrag);
    document.removeEventListener('mouseup', this.handleMouseup);
},
setCursor(value) {
    // 设置鼠标样式
    [document.body, this.nowImg].forEach(el => {
        el.style.cursor = value;
    });
}

当然问题还是有的,不过我们知道这个思路就行。具体代码可以去看下 npm 上的 quill-image-resize-module 包,我也是按照这个包的思路来讲解的?。。。

操纵光标

除了不好对图片进行处理外,光标应该也是一大坑,你可能不知道什么时候就失去焦点了,此时再点击按钮执行命令就无效了;有时你又需要还原或设置光标的位置,比如插入图片后,光标要设置到图片后面等等之类的。 所以我们需要具有控制光标的能力,具体操作就是在点击按钮之前我们可以先存储当前光标的状态,执行完命令或者在需要的时候后再还原或设置光标的状态即可。由于在 chrome 中,失去焦点并不会清除 Seleciton 对象和 Range 对象,所以就像我一开始说的我没怎么去了解?。。。这里就只简要展示两个方法给大家看下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function saveSelection() { // 保存当前Range对象
    let selection = window.getSelection();
    if(selection.rangeCount > 0){
        return sel.getRangeAt(0);
    }
    return null;
};
let selectedRange = saveSelection();
function restoreSelection() {   
    let selection = window.getSelection();   
    if (selectedRange) {   
        selection.removeAllRanges();  // 清空所有 Range 对象
        selection.addRange(selectedRange); // 恢复保存的 Range
    }
}

以上就是今天所要分享的内容,感谢你的阅读,大赞无疆? 。。。。

结语

回到开头我们讲的那个需求,关于图片旋转的,根据上面的思路,你可以在蒙层上加个旋转图标,并添加点击事件,然后修改图片和蒙层 transform 属性,当然了位置也要变,可能需要些计算,我也没试过,不知道效果咋样?。 另外一种方法就是在插入图片之前先对图片进行处理(比如多一步类似裁剪的功能)再上传,这样就可以不用在编辑区里面处理图片啦,嘿嘿,目前我就想到这两种方案了,实际工作中采用的是第二种方式,因为产品的需求不止于旋转?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端自习课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
2025大厂Android面试直通车:8道必问源码解析+性能优化高频考点
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。
AntDream
2025/02/18
6480
2025大厂Android面试直通车:8道必问源码解析+性能优化高频考点
大厂Android高级面试核心命题:从源码到实战的降维打击(2025版)
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。
AntDream
2025/02/20
3680
大厂Android高级面试核心命题:从源码到实战的降维打击(2025版)
Android资深岗突围指南:拆解Framework层8个高频灵魂拷问
这是之前作为面试官时,三个让87%候选人当场挂掉的Framework层"送命题"。
AntDream
2025/02/12
1410
Android资深岗突围指南:拆解Framework层8个高频灵魂拷问
年薪50万的Android岗,为什么连这7个Jetpack原理都答不上?
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。
AntDream
2025/02/26
1571
年薪50万的Android岗,为什么连这7个Jetpack原理都答不上?
Android开发3年,九月份面试12家大厂跳槽成功,我有一些面试经验想分享给你们
在下2017年毕业,目前从事android开发工作已经3年了,前段时间刚完成一次跳槽,面试了几家公司,将一些面试经验分享给大家,希望对大家有所帮助。
Android技术干货分享
2020/09/28
1.7K0
Android开发3年,九月份面试12家大厂跳槽成功,我有一些面试经验想分享给你们
Android性能优化(一)
一个应用App的启动速度能够影响用户的首次体验,启动速度较慢(感官上)的应用可能导致用户再次开启App的意图下降,或者卸载放弃该应用程序。
xiangzhihong
2021/01/22
2.8K0
大厂P7面试官亲授:3个让90%候选人挂掉的性能优化场景题
某音视频社交APP在直播连麦场景下,当观众数超过500人时,主播端出现帧率从60FPS暴跌至15FPS的现象。候选人需要定位性能瓶颈并提供优化方案。
AntDream
2025/02/12
2230
大厂P7面试官亲授:3个让90%候选人挂掉的性能优化场景题
前方高能!这是最新的一波Android大厂面试题汇总,不学则已,一学惊人
面试大厂,那就是考察你技术方向的一些专业技能,如果你面试Android岗位,那 Android 方向的专业技能就是考察很重要的一个方向。
Android技术干货分享
2021/08/25
1.3K0
前方高能!这是最新的一波Android大厂面试题汇总,不学则已,一学惊人
字节P7面试官亲述:90%Android候选人挂在这5个Binder机制细节
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。
AntDream
2025/03/03
1470
字节P7面试官亲述:90%Android候选人挂在这5个Binder机制细节
Android冷启动优化终极指南:让APP比微信还快的7个黑科技
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。
AntDream
2025/03/18
3180
Android冷启动优化终极指南:让APP比微信还快的7个黑科技
当大潮退去没有谁还能Android这行“裸泳”,10家大厂面试题,掌握这些让你轻松面试
现在Android开发的现状大致是这个样子,人才严重过饱和,加上跨端和小程序盛行,原生客户端(安卓 iOS)岗位进一步萎缩,入行之后就业极为困难。目前行情是移动端严重过剩,服务端供需平衡,前端供不应求。市场上前端工作好找,服务端职业上限整体较高。。客户端上百人抢一个工作岗位,竞争激烈,内卷惨烈。
Android技术干货分享
2021/08/26
1.1K0
当大潮退去没有谁还能Android这行“裸泳”,10家大厂面试题,掌握这些让你轻松面试
你想要的Android性能优化系列:启动优化 !
手机桌面点击一个应用,用户希望应用能 及时响应、快速加载。启动时间过长的应用可能会令用户失望。这种糟糕的体验可能会导致用户在 Play 商店针对您的应用给出很低的评分,甚至完全弃用您的应用。
胡飞洋
2020/07/23
1.7K0
Android性能优化笔记(一)——启动优化
从上面的总结可以看出,在应用的启动过程中,冷启动是最慢最耗时的,系统以及应用本身都有大量的工作需要处理,所以,冷启动对于应用的启动速度是最具挑战以及最有必要进行优化的。
分你一些日落
2021/12/13
1.1K0
❤️Android 性能优化之启动优化❤️
用户希望应用能够快速打开。启动时间过长的应用不能满足这个期望,并且可能会令用户失望。轻则鄙视你,重则直接卸载你的应用。
Android 帅次
2021/11/12
1K0
❤️Android 性能优化之启动优化❤️
金九银十Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!
无他,就是靠自己的毅力以及决心。一天不行,一个月;一个月不行,一年;有决心的人,啥学历、或者资历,那些都是借口。
Android技术干货分享
2021/08/30
8870
金九银十Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!
Android性能优化系列之App启动优化
应用的启动速度缓慢是我们在开发过程中经常会遇到的问题,比如启动缓慢导致的黑屏,白屏问题,本篇博客就将介绍App启动优化的相关知识。
老马的编程之旅
2022/06/22
7530
Android性能优化系列之App启动优化
2020安卓面试心得②:疫情下的安逸,九场面试后险获三个offer,这份面试总结值得反思
历时一个半月,斩获3个大厂offer,在上一篇文章中整理了大厂常考知识点和一些面试技巧,今天就把我面试的几家公司的面试经历整理出来,分享一波。
Android技术干货分享
2021/01/28
7900
2020安卓面试心得②:疫情下的安逸,九场面试后险获三个offer,这份面试总结值得反思
2025大厂Android岗薪资倒挂真相:精通这3个Jetpack原理=涨薪50%
大家好,我是稳稳,一个曾经励志用技术改变世界,现在为随时失业做准备的中年奶爸程序员,与你分享生活和学习的点滴。
AntDream
2025/03/03
960
2025大厂Android岗薪资倒挂真相:精通这3个Jetpack原理=涨薪50%
Android性能优化(一)—— 启动优化,冷启动,热启动,温启动
App启动方式分三种:冷启动(cold start)、热启动(hot start)、温启动(warm start)
233333
2024/06/28
4740
Android性能优化(一)—— 启动优化,冷启动,热启动,温启动
Android性能优化
讲到Android开发,就不得不谈一下Android的优化,不管是平时开发中我们需要注意的一些Android对Java的一些类的优化,还是实际开发中对性能的优化,其实早在15年的google全球大会上google就Android的性能优化就给我们做了很好的介绍:点击打开链接。 接下来本文从几个方面入手讲一讲Android 的优化,主要从以下几点:布局优化,绘制优化,内存优化,响应速度优化,bitmap优化(主要结合listview),线程优化,其他常用性能优化;内存检测工具mat分析与提高。 为了达到优化的
xiangzhihong
2018/02/05
1.2K0
Android性能优化
推荐阅读
2025大厂Android面试直通车:8道必问源码解析+性能优化高频考点
6480
大厂Android高级面试核心命题:从源码到实战的降维打击(2025版)
3680
Android资深岗突围指南:拆解Framework层8个高频灵魂拷问
1410
年薪50万的Android岗,为什么连这7个Jetpack原理都答不上?
1571
Android开发3年,九月份面试12家大厂跳槽成功,我有一些面试经验想分享给你们
1.7K0
Android性能优化(一)
2.8K0
大厂P7面试官亲授:3个让90%候选人挂掉的性能优化场景题
2230
前方高能!这是最新的一波Android大厂面试题汇总,不学则已,一学惊人
1.3K0
字节P7面试官亲述:90%Android候选人挂在这5个Binder机制细节
1470
Android冷启动优化终极指南:让APP比微信还快的7个黑科技
3180
当大潮退去没有谁还能Android这行“裸泳”,10家大厂面试题,掌握这些让你轻松面试
1.1K0
你想要的Android性能优化系列:启动优化 !
1.7K0
Android性能优化笔记(一)——启动优化
1.1K0
❤️Android 性能优化之启动优化❤️
1K0
金九银十Offer收割机:Android 面试核心知识点精讲,不打没准备的仗!
8870
Android性能优化系列之App启动优化
7530
2020安卓面试心得②:疫情下的安逸,九场面试后险获三个offer,这份面试总结值得反思
7900
2025大厂Android岗薪资倒挂真相:精通这3个Jetpack原理=涨薪50%
960
Android性能优化(一)—— 启动优化,冷启动,热启动,温启动
4740
Android性能优化
1.2K0
相关推荐
2025大厂Android面试直通车:8道必问源码解析+性能优化高频考点
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验