sumshare

sumshare 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

sumshare 回答了问题 · 2020-07-15

解决求问 react-native 新建项目后 const App: () => React$Node = () => 是什么意思

关注 5 回答 4

sumshare 回答了问题 · 2020-03-27

解决npm 的 --save 和 --save-dev 有什么区别?

用来对代码编译的比如less,babel等全都是开发依赖,是绝对不能放到dep里(增大了体积),而其他的放哪都无所谓,该打包还是会打包,不知道这样理解对不对

关注 9 回答 7

sumshare 收藏了问题 · 2020-03-27

npm 的 --save 和 --save-dev 有什么区别?

每次安装依赖的时候,不知道什么时候--save 什么时候 --save-dev。
我看别人说的 --save 是 生产环境 , --save-dev是开发环境,这个生产环境是什么意思,是打包后发布到线上的么?
可是 npm run build 后的,不是将所有的依赖都给打包了吗,感觉依赖安装--save和 --save-dev 没有太大区别。。不是很懂这一块~~~

sumshare 收藏了文章 · 2020-03-04

前端小知识--JavaScript事件流

JavaScript事件流

0.DOM级别与DOM事件

首先在介绍DOM事件之前我们先来认识下DOM的不同级别。针对不同级别的DOM,我们的DOM事件处理方式也是不一样的。
DOM级别一共可以分为4个级别:DOM0级,DOM1级,DOM2级和DOM3级,
而DOM事件分为3个级别:DOM0级事件处理,DOM2级事件处理和DOM3级事件处理。

如下图所示:

clipboard.png

其中1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。

1.事件

事件指可以被 JavaScript 侦测到的行为。即鼠标点击、页面或图像载入、鼠标悬浮于页面的某个热点之上、在表单中选取输入框、确认表单、键盘按键等操作。事件通常与函数配合使用,当事件发生时函数才会执行。
事件名称:click/mouseover/blur("不带on")

响应某个事件的函数就是事件处理程序(事件侦听器)。
事件处理程序函数名称:onclick/onmouseove/onblur

例子代码--点击事件触发alert函数
<button onclick="alert('hello')"></button>

更多事件类别请参考w3c中关于事件的详细类别。
JavaScript 事件
JavaScript 事件参考手册

2.事件流

事件流指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。

一点背景:
早期的IE事件传播方向为由上至下,即从document逐级向下传播到目标元素;
而Netscape公司的Netscape Navigator则是朝相反的方向传播,也就是从目标元素开始向上逐级传播最终至window。 两家公司对于事件流出现了截然相反的定义。

后来ECMAScript在DOM2中对事件流进行了进一步规范,基本上就是上述二者的结合。
当事件发生时,最先得到通知的是window,然后是document,由上至下逐级依次而入,直到真正触发事件的那个元素(目标元素)为止,这个过程就是捕获。
接下来,事件会从目标元素开始起泡,由下至上逐级依次传播,直到window对象为止,这个过程就是冒泡。
所以捕获比冒泡先执行。
其中DOM3级事件在DOM2的基础之上添加了更多的事件类型。

DOM2级事件规定的事件流包括三个阶段:
(1)事件捕获阶段(2)处于目标阶段(3)事件冒泡阶段。
下面图片来自:https://www.w3.org/TR/DOM-Lev...
clipboard.png

我们写一个例子:如下图,中间白色区域的盒子分别为box1,box2...box6,包含控制按钮设置我们的事件

    <div>
        <h4 id="currentBox">点击按钮设置类型后再点击中心</h4>
        <button class="btn" id="btnCapture" onclick="setCapture()">设置捕获</button>
        <button class="btn" id="btnBubble" onclick="setBubble()">设置冒泡</button>
        <button class="btn" id="btnAll" onclick="setAll()">设置捕获和冒泡</button>
        <button class="btn" onclick="clearAll()">动画完成后再清除设置</button>
    </div>
    <div class="box" id="box1">
        <div class="box" id="box2">
            <div class="box" id="box3">
                <div class="box" id="box4">
                    <div class="box" id="box5">
                        <div class="box" id="box6">
                            点击

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

大概流程图如下:

clipboard.png

演示效果如图:

图片描述

例子源码
参考链接————小侠同学

3.事件处理程序

前面我们已经说到了,事件处理程序就是响应某个事件的函数,简单地来说,就是函数。我们又把事件处理程序称为事件侦听器。事件处理程序是以"on"开头的,比如点击事件的处理程序是"onclick",事件处理程序大概有以下5种。
  • 1.HTML事件处理程序
  • 2.DOM0级事件处理程序
  • 3.DOM2级事件处理程序
  • 4.IE事件处理程序
  • 5.跨浏览器的事件处理程序

3.1 HTML事件处理程序

像我们的第一个例子,就是HTML事件处理程序,它是写在html里面的,是全局作用域:

例子代码--点击事件触发alert函数
<button onclick="alert('hello')"></button>

当我们需要使用一个复杂的函数时,将js代码写在这里面,显然很不合适,所以有了下面这种写法:

例子代码--点击事件触发doSomething()函数,这个函数写在单独的js文件或<script>之中。
<button onclick="doSomething()"></button>

这样会出现一个时差问题,当用户在HTML元素出现一开始就进行点击,有可能js还没有加载好,这时候就会报错。但我们可以将函数封装在try-catch块中来处理:

<button onclick="try{doSomething();}catch(err){}"></button>

同时,一个函数的改变,同时可能会涉及html和js的修改,这样是很不方便的,综上,我们有了DOM0级事件处理程序。

3.2 DOM0级事件处理程序

之所以有DOM0级事件处理程序,和我们之前提到的IE以及Netscape对应事件传播方向不同处理而产生的事件处理程序。

<button id="btn">点击</button>
 
<script>
  var btn=document.getElementById("btn");
  btn.onclick=function(){
    alert("hello");
  }
</script>

可以看到button.onclick这种形式,这里事件处理程序作为了btn对象的方法,是局部作用域。
所以我们可以用

btn.onclick = null;来删除指定的事件处理程序。

如果我们尝试给事件添加两个事件,如:

<button id="btn">点击</button>
 
<script>
  var btn=document.getElementById("btn");
  btn.onclick=function(){
    alert("hello");
  }
  btn.onclick=function(){
    alert("hello again");
  }
</script>

输出,hello again,很明显,第一个事件函数被第二个事件函数给覆盖掉了,所以,DOM0级事件处理程序不能添加多个,也不能控制事件流到底是捕获还是冒泡。

3.3 DOM2级事件处理程序(不支持IE)

进一步规范之后,有了DOM2级事件处理程序,其中定义了两个方法:
addEventListener() ---添加事件侦听器
removeEventListener() ---删除事件侦听器
具体用法看
1.https://developer.mozilla.org...
2.https://developer.mozilla.org...
函数均有3个参数,
第一个参数是要处理的事件名(不带on前缀的才是事件名)
第二个参数是作为事件处理程序的函数
第三个参数是一个boolean值,默认false表示使用冒泡机制,true表示捕获机制。

<button id="btn">点击</button>
 
<script>
  var btn=document.getElementById("btn");
  btn.addEventListener('click',hello,false);
  btn.addEventListener('click',helloagain,false);
  function hello(){
    alert("hello");
  }
  function helloagain(){
    alert("hello again");
  }
</script>

这时候两个事件处理程序都能够成功触发,说明可以绑定多个事件处理程序,但是注意,如果定义了一摸一样时监听方法,是会发生覆盖的,即同样的事件和事件流机制下相同方法只会触发一次,比如:

<button id="btn">点击</button>
 
<script>
  var btn=document.getElementById("btn");
  btn.addEventListener('click',hello,false);
  btn.addEventListener('click',hello,false);
  function hello(){
    alert("hello");
  }
</script>

removeEventListener()的方法几乎和添加时用法一摸一样:

<button id="btn">点击</button>
 
<script>
  var btn=document.getElementById("btn");
  btn.addEventListener('click',hello,false);
  btn.removeEventListener('click',hello,false);
  function hello(){
    alert("hello");
  }
</script>

这样的话,事件处理程序只会执行一次。
但是要注意,如果同一个监听事件分别为“事件捕获”和“事件冒泡”注册了一次,一共两次,这两次事件需要分别移除。两者不会互相干扰。
这时候的this指向该元素的引用。
这里事件触发的顺序是添加的顺序。

3.4 IE事件处理程序

对于 Internet Explorer 来说,在IE 9之前,你必须使用 attachEvent 而不是使用标准方法 addEventListener。
IE事件处理程序中有类似与DOM2级事件处理程序的两个方法:
1.attachEvent()
2.detachEvent()
它们都接收两个参数:
1.事件处理程序名称。如onclick、onmouseover,注意:这里不是事件,而是事件处理程序的名称,所以有on。
2.事件处理程序函数。
之所以没有和DOM2级事件处理程序中类似的第三个参数,是因为IE8及更早版本只支持冒泡事件流。
removeEventListener()的方法几乎和添加时用法一摸一样:

<button id="btn">点击</button>
 
<script>
  var btn=document.getElementById("btn");
  btn.attachEvent('onclick',hello);
  btn.detachEvent('onclick',hello);
  function hello(){
    alert("hello");
  }
</script>

这里事件触发的顺序不是添加的顺序而是添加顺序的相反顺序。
使用 attachEvent 方法有个缺点,this 的值会变成 window 对象的引用而不是触发事件的元素。

3.5 跨浏览器的事件处理程序

为了兼容IE浏览器和标准的浏览器,我们需要编写通用的方法来处理:
var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    removeHandler: function (element, type, handler) {
        if (element.removeEventListener()) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    }
};

这一部分需要创建两个方法:
addHandler() --这个方法职责是视情况来使用DOM0级、DOM2级、IE事件处理程序来添加事件。
removeHandler()--这个方法就是移除使用addHandler添加的事件。
这两个方法接收相同的三个参数:
1.要操作的元素--通过dom方法获取
2.事件名称--注意:没有on,如"click"、"mouseover"
3.事件处理程序函数--对应的函数

使用:

<button id="btn">点击</button>
 
<script>
  var btn=document.getElementById("btn");
  EventUtil.addHandler(btn,'click',hello);
  EventUtil.removeHandler(btn,'click',hello);
  function hello(){
    alert("hello");
  }
</script>

4.事件对象

事件对象是用来记录一些事件发生时的相关信息的对象,但事件对象只有事件发生时才会产生,并且只能是事件处理函数内部访问,在所有事件处理函数运行结束后,事件对象就被销毁!

属性和方法如图,详细请查看以下链接:
1.HTML DOM Event 对象:http://www.w3school.com.cn/js...
2.详细介绍请查看:http://www.jb51.net/article/9...
clipboard.png

4.1 属性

下面是一个例子:

<button id="btn">点击</button>
 
<script>
        var btn=document.getElementById("btn");
        btn.ddEventListener('click', doCurrent, true);
        // 判断事件的属性
        function doCurrent(event) {
            //获取当前事件触发的div
            var target = event.currentTarget;

            //通过判断事件的event.eventPhase属性返回事件传播的当前阶段
            //1:捕获阶段、2:正常事件派发和3:起泡阶段。
            //得到当前阶段和id值并输出
            var msg = (event.eventPhase == 1 ? '捕获阶段:' : '冒泡阶段:')+ target.attributes["id"].value;;
            console.log(msg);
        }
</script>

在这个例子里,我们用到了currentTargeteventPhase 属性。

4.2 方法

Event对象主要有以下两个方法,用于处理事件的传播(冒泡、捕获)和事件的取消。
stopPropagation()——冒泡机制下,阻止事件的进一步往上冒泡

    var btn1=document.getElementById("btn1");
    var content=document.getElementById("content");
    btn1.addEventListener("click",function(event){
        alert("btn1");
        event.stopPropagation();
    },false);
    content.addEventListener("click",function(){
        alert("content");
    },false);
    //这里会输出btn1,阻止了向content的冒泡

preventDefault()——用于取消事件的默认操作,比如链接的跳转或者表单的提交,主要是用来阻止标签的默认行为

<a id="go" href="https://www.baidu.com/">禁止跳转</a>
var go = document.getElementById('go');
function goFn(event) {
 event.preventDefault();
// 不会跳转
}
go.addEventListener('click', goFn, false);

4.3 兼容性

当然,事件对象也存在一定的兼容性问题,在IE8及以前本版之中,通过设置属性注册事件处理程序时,调用的时候并未传递事件对象,需要通过全局对象window.event来获取。解决方法如下:

function getEvent(event) {
 event = event || window.event;
}

在IE浏览器上面是event事件是没有preventDefault()这个属性的,所以在IE上,我们需要设置的属性是returnValue

window.event.returnValue=false

stopPropagation()也是,所以需要设置cancelBubble,cancelBubble是IE事件对象的一个属性,设置这个属性为true能阻止事件进一步传播。

event.cancelBubble=true

5.事件委托

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

例子说明,我们为ul添加新的li,其中对li标签元素绑定了click事件,但是发现,后增加的元素没有办法触发我们的click事件。

    <button id="btnAdd">添加</button>
    <ul id="ulList">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var btnAdd = document.getElementById('btnAdd');
        var ulList = document.getElementById('ulList');
        var list = document.getElementsByTagName('li');
        var num = 3;
        btnAdd.onclick = function () {
            num++;
            var li = document.createElement('li');
            li.innerHTML = num;
            ulList.appendChild(li)
        }
        for (i = 0; i < list.length; i++) {
            list[i].onclick = function(){
                alert(this.innerHTML);
            }
        }
    </script>

图片描述

这是因为如果事件涉及到更新HTML节点或者添加HTML节点时,新添加的节点无法绑定事件,更新的节点也是无法绑定事件,表现的行为是无法触发事件。
其中一种解决方法是,添加子节点的时候,再次为其添加监听事件

    <button id="btnAdd">添加</button>
    <ul id="ulList">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var btnAdd = document.getElementById('btnAdd');
        var ulList = document.getElementById('ulList');
        var list = document.getElementsByTagName('li');
        var num = 3;

        function doclick() {
            for (i = 0; i < list.length; i++) {
                list[i].onclick = function () {
                    alert(this.innerHTML);
                }
            }
        }
        doclick();


        btnAdd.onclick = function () {
            num++;
            var li = document.createElement('li');
            li.innerHTML = num;
            ulList.appendChild(li);
            doclick();
        }
    </script>

这也是问题所在:
 1.首先我们多次操作DOM获取元素,这样势必会降低浏览器处理性能
 2.事件不具有继承性,如果我们动态在页面中添加了一个元素,那么还需要重新走一遍上述程序为其添加监听事件

那么有没有更好的方法呢?根据事件的冒泡原理,我们还可以实现另外一个很重要的功能:事件委托

我们只监听最外层的元素,然后在事件函数中根据事件来源进行不同的事件处理。这样,我们添加事件监听时只需要操作一个元素,极大的降低了DOM访问,并且不用再给新增的元素添加监听事件了,因为元素的事件会冒泡到最外层,被我们截获。

    <button id="btnAdd">添加</button>
    <ul id="ulList">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var btnAdd = document.getElementById('btnAdd');
        var ulList = document.getElementById('ulList');
        var num = 3;

        ulList.onclick = function(event){
            var event = event || window.event;
            var target = event.target || event.srcElement;
            if(target.nodeName.toLowerCase() == 'li'){
                alert(target.innerHTML);
            }
        }

        btnAdd.onclick = function () {
            num++;
            var li = document.createElement('li');
            li.innerHTML = num;
            ulList.appendChild(li);
            doclick();
        }
    </script>

这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的,所以要判断点击的对象到底是不是li标签元素。

Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,当然,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,我们需要转成小写再做比较(习惯问题)。

这样,我们就实现了我们的事件委托,当然,不是所有的事件都是可以委托的。
适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。

当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,新增加的节点也可以触发事件效果。

参考:
1.http://www.cnblogs.com/souven...
2.https://www.cnblogs.com/st-le...
3.https://segmentfault.com/a/11...
4.http://www.jb51.net/article/9...
5.http://www.w3school.com.cn/js...
6.http://www.jb51.net/article/8...
7.http://www.jb51.net/article/9...

查看原文

sumshare 赞了文章 · 2019-09-04

移动端真机调试实战经验

本文首次发表于本人的个人博客:http://cherryblog.site/ ,欢迎大家到我的博客查看更多文章~

前言

在开发中前端免不了要进行移动端的开发,然而在电脑上看的样式和手机上还是有一定的差距的,因为手机上有顶部的状态栏和底部的菜单栏,特别是在qq内置浏览器中打开,差距还是蛮大的,所以在chrom中模拟手机显示的情况虽然有一定的效果,但是还是不能完全模拟,我们还需要在真机环境下测试。
本文介绍的调试方法有一下几种:

  • iphone+safari

  • android手机+pc

  • 微信开发者工具

  • weinre

  • 使用webstorm

  • 使用Fiddle抓包

这几种方法基本说涵盖了我们平时开发中所遇到的各种情况,各种主流设备都可以覆盖。其中最方便快捷的是使用webstorm自带的服务器,只需要一键就可以~,但是这样只能预览,不能调试。
我个人比较推荐的方法是iphone+safari或者安卓手机+pc的这种方式,比较简单方便快捷,然后根据具体的环境再选择更为合适的调试方法。
目前我认为使用weinre+fiddle是万能的,没有什么调试不了了~但是需要学习的成本也是最高的~
希望大家都能够写出漂亮的页面,不需要为调试发愁哈~

iphone+safari

之前使用的是mac,所以一直都是用的iphone+safari模拟真机环境,这种方法简单明了,只需要简单的设置一下以后都不要设置,插上数据线,打开mac上的safari就可以了,(๑•̀ㅂ•́)و,✧,但是对设备有要求,必须是iphone+mac的组合

iphone上设置

设置 → Safari → 高级 → Web 检查器 → 开。
这里写图片描述

pc端safari设置

Safari → 偏好设置 → 高级 → 在菜单栏中显示“开发”菜单
这里写图片描述

设置完之后用数据线连接电脑,然后在iphone上用打开safari需要调试的网址,然后在pc端打开safari,最上面的菜单栏中的“开发”然后就可以看到有iphone设备的名称显示然后就可以看见你在iphone中的safari中打开了哪些网址,之后就和调试网页版的一样了

android手机+pc

安卓手机只需要下载chrom浏览器,就可以再电脑上用chrom调试了,是不是很赞(づ ̄3 ̄)づ╭

  1. 首先需要装chrom浏览器

  2. 打开手机的开发者模式,一般是:设置->关于手机->版本号连按5次,之后设置菜单中会多出一个开发人员选项,进入将其中的“usb调试”打开

  3. 将手机与电脑通过usb连接,弹出对话框“是否允许usb调试”,选择确定

  4. 在手机chrom上打开要调试的页面

  5. 在电脑上打开chrom,新开一地址栏为chrome://inspect/的页面,然后就可以调试了

  6. 点击inspect弹出chrom调试工具

微信开发者工具

由于不可描述原因,有些页面只在微信里面出错,并且好多涉及到了微信相关的接口必须要使用微信环境的,比如自定义分享

前期准备

这个使用起来很方便。(我记得之前使用的时候(2016年),你要调试的页面必须是你是管理员的微信公众号下面的js安全域名下的地址),但是刚刚下载一个新版本的开发者工具(v0.7.0),现在的时间是2017年3月28日,发现好像没有这个限制了。所以这样开发起来就方便多了。

官方文档&下载地址

官方文档其中有下载地址

模拟微信环境调试

直接在地址栏输入地址就可以模拟微信环境调试,是不是很方便~这种方式可以满足大部分的需求

真机调试

在开发者工具中的移动调试中可以有详细的ios和安卓的调试方式,主要是使用代理,这里我没有调试成功,在手机微信中一直打不开网页,所以就不详细写了╥﹏╥...

---------------3.29更---------------------
我找到设置代理之后打不开网页的原因了,在使用fiddler抓包的时候也遇到了同样的问题,原来这里需要下载认证
在设置完当前网络的代理之后,在浏览器输入本机的ip地址和ip号,下载fiddler的证书

然后根据提示一步一步安装就可以了。
安装完证书就可以打开网页了

weinre

跟着我念三遍weinre大法好,weinre大法好,weinre大法好~
之前介绍的几种方式或多或少都有一些条件限制,但是weinre没有啊喂!就比如我是ios+windows的组合,就不能使用iphone+safari和安卓+pc的方式调试,所以使用weinre就可以!!
缺点就是配置起来有削微的麻烦~

什么是weinre

weinre是web inspector remote(远程web检查器)的缩写

安装weinre

目前安装weinre我了解到有两种方式:node和java两种方式

node方式安装weinre

首先确保你的电脑上有node环境,然后使用npm来安装
windows下
npm install weinre -g --registry=https://registry.npm.taobao.org
mac下
sudo npm install weinre -g --registry=https://registry.npm.taobao.org

java环境下安装weinre

首先确认你电脑上装好的java环境,然后下载weinre的jar包,上百度云盘的链接:链接: https://pan.baidu.com/s/1slRiOl3 密码: dsmp

运行weinre

node环境下

weinre --httpPort 8081 --boundHost -all-
8081是调试服务器运行的端口号,
boundHost是调试服务器绑定的ip地址或域名,默认是localhost,设置为-all-是为了在本地能使用localhost打开,在移动设备或本地环境用ip地址打开weinre调试工具

java环境下

在weinre所在文件夹的地址栏输入代码:java -jar weinre.jar --httpPort 8081 --boundHost -all-

开始调试

设置好端口之后我们在本地打开http://192.168.0.126:8081然后就可以看见weinre的基本信息

之后我们需要在需要调试的页面上加上一段script标签
<script data-original="http://192.168.0.126:8081/target/target-script-min.js#anonymous"></script>
需要改为你自己的ip地址

ip的查询方式

在cmd输入ipconfig,然后ipv4中后面跟的就是本机的ip地址

手机打开需要调试的链接

在staticWebDir目录下

本地的源文件貌似只能在staticWebDir目录下才可以访问到(这是因为在没有使用任何服务器的情况下,weinre自带有服务器,所以只能放在默认的根目录下),将你的源文件放在staticWebDir目录下,staticWebDir的目录是你安装weinre的根目录,我的是:C:\Users\supfn\AppData\Roaming\npm\node_modules\weinre\web,然后手机访问:http://192.168.0.126/contact_page/index.html,然后在电脑上打开刚刚的页面http://196.168.0.126:8081点击debug client user interface之后出现
,点击蓝色的链接,变为绿色的之后就说明链接成功了。在后面的elements和其他的tag就可以进行调试

在xampp下

因为公司的项目是在xampp下的,已经配置好了apache,可以直接在平时的项目前加上本地的ip,在手机上访问就好。
项目存放的地址是xampp\htdocs\app
修改配置:
C:\Windows\System32\drivers\etc\hosts文件下
最后一行
127.0.0.1 localhost ltrip.com fzc.com m.fzc.com m.ltrip.com
然后在C:\xampp\apache\conf\extra文件里面修改

<VirtualHost *:80>
    DocumentRoot "C:\xampp\htdocs\ltrip"
    ServerName ltrip.com 
    ServerAlias 
  <Directory "C:\xampp\htdocs\ltrip">
      Options FollowSymLinks ExecCGI
      AllowOverride All
      Order allow,deny
      Allow from all
      Require all granted
  </Directory>
</VirtualHost>

其中的ServerName ltrip.com 中的ltrip.com就代替了 "C:\xampp\htdocs\ltrip"这个路径,
所以就不需要放在staticWebDir目录下了,这样手机打开的地址就变成了:http://192.168.0.168/ltrip.com

使用webstorm

在最先开始使用weinre的时候,一直卡在一个地方,就是手机访问的地址问题,在看教程的时候我就卡在不知道怎么输入手机打开的网址,因为我是自己写的一个简单的html的demo,在本地打开的地址是使用本地的绝对路径比如file:///C:/Users/supfn/Desktop/contact_page/index.html这样子的,在手机肯定访问不到我的电脑上的路径。
这里是需要在本地搭建一个服务器,这样才能在手机访问到你电脑上的资源,通过服务器其他人也可以访问你电脑上的资源,常见的服务器有apache,使用Java的还可以用tomcat。这些使用起来都比较麻烦,这里推荐一个简单的方式,使用webstorm。
webstorm集成了debugger服务器,所以可以直接在你项目html页面的右上角点击浏览器的图标,在对应浏览器打开项目,然后将地址栏上的localhost改为你的ip地址,手机访问这个地址就可以了~
简直不要太方便!!所以webstorm真的是web开发利器,而不止是一个编辑器

使用Fiddle抓包

如果是要调试线上代码的话经常是无法再页面中直接加入script标签的,然后我们可以利用fiddler为页面设置断点,然后注入js代码,在run就可以了~
fiddler是用过改写http代理,让数据从它这通过,来监控截取到的数据。在打开fiddler的时候,就已经自动设置好了浏览器的代理了,关闭的时候,它又把代理还原了

下载fiddler

Fiddler 下载地址 :https://www.telerik.com/downl...
Fiddler 离线下载地址:http://pan.baidu.com/s/1i3NvE8P 密码:ozem

使用fiddler抓取数据包

在手机上设置同一个局域网上的代理,代理服务器设置为电脑的ip地址,端口为8888
在fiddler上,点击菜单栏中的 [Tools] –> [Fiddler Options]

点击 [Connections] ,设置代理端口是8888, 勾选 Allow remote computers to connect, 点击OK

使用weinre与fiddler组合

我们要实现的目标就是要调试线上的代码,使用fiddler在代码中注入weinre需要加上的script标签
在完成配置之后打开要调试的链接,然后在fiddler中设置断点
我们在fiddler中打下页面断点,bpafter + 想要打断点的网址
再次访问该网站,发现本条请求被block住了
这里写图片描述
然后在右边加上weinre需要的script标签<script data-original="http://192.168.0.126:8081/target/target-script-min.js#anonymous"></script>
然后点击右边代码上面绿色的run to completion就可以看到注入js的效果了,之后我们就可以在weinre中调试了~

参考文章

查看原文

赞 8 收藏 19 评论 2

sumshare 提出了问题 · 2019-06-18

Chrome是禁止自动播放音频的,但是当切换其他tab做一次交互,再刷新当前页面,就可以自动播了

问题描述

未经任何处理,audio.play()能自动播放,Chrome autoplay策略是default,没有做过设置,所以理应报一个promise错误,启动一个http服务,访问页面,的确不能播,但是切换tab做一次交互后返回当前页刷新就会自动播放

问题出现的平台版本及自己尝试过哪些方法

MAC Chrome 75

相关代码

//创建audio对象
let ccGlobalMusic = document.createElement('audio')
//设置默认音乐
ccGlobalMusic.src = './bgm.mp3'
// 默认播放
ccGlobalMusic.play()
//默认开启循环
ccGlobalMusic.loop = 'loop'

注意,脚本需要引入,不能内置在页面,才能重现这问题

关注 1 回答 0

sumshare 关注了问题 · 2019-06-18

Chrome是禁止自动播放音频的,但是当切换其他tab做一次交互,再刷新当前页面,就可以自动播了

问题描述

未经任何处理,audio.play()能自动播放,Chrome autoplay策略是default,没有做过设置,所以理应报一个promise错误,启动一个http服务,访问页面,的确不能播,但是切换tab做一次交互后返回当前页刷新就会自动播放

问题出现的平台版本及自己尝试过哪些方法

MAC Chrome 75

相关代码

//创建audio对象
let ccGlobalMusic = document.createElement('audio')
//设置默认音乐
ccGlobalMusic.src = './bgm.mp3'
// 默认播放
ccGlobalMusic.play()
//默认开启循环
ccGlobalMusic.loop = 'loop'

注意,脚本需要引入,不能内置在页面,才能重现这问题

关注 1 回答 0

sumshare 回答了问题 · 2017-08-10

解决vue-router两种模式,到底什么情况下用hash,什么情况下用history模式呢?

hash模式的话路由地址会带上#,但是浏览器发送给服务端的却实#之前的URL,hash模式的好处是,虽然你是个单页面应用,但你可以刷新当前页。history的话需要服务端配合,如果服务端配置仅仅是找不到路由,就重定向到index.html,那么刷新会跳首页,如果服务端对于匹配不到URL不做配置,那么一般返回404页面

关注 15 回答 4

认证与成就

  • 获得 1 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-04-20
个人主页被 432 人浏览