JavaScript dispatchEvent未分派

时间:2019-01-11 01:08:59

标签: javascript

我在让<form method="post"> un: <br><input type="text" placeholder="Enter username" name = "username"><br><br> pword: <br><input type="text" placeholder="Enter Password" name = "password"><br><br> <input type ="submit" name = "submit"> </form> <?php mysql_connect('localhost',"root","usbw"); @mysql_select_db("Login") or die("unable to select database"); $UN = $_POST['un']; $query = 'SELECT * FROM users WHERE username = "$UN"'; $result = mysql_query($query= 'SELECT * FROM users WHERE username= "dday"'); $user_info = mysql_fetch_assoc($result); $temp = md5($_POST['password']); if (isset($_POST['password'])) { echo $user_info['pword']; echo "<br>"; if($user_info['pword'] == $temp AND $user_info['username'] == $UN) { echo "You have logged in. <br>" ; } else { echo "'" . $_POST['password'] . "'" . " is the incorrect password. <br>"; } echo "your password is:" . $_POST['password'] . "<br>"; echo "your encrypted password is :" . $temp; } mysql_close(); ?> 开始工作时遇到了问题。我试图消除对jQuery的依赖,并且一直在对本机API进行一些扩展,但是我无法使用dispatchEvent来使用trigger这个版本。

在控制台记录所有内容之后,我知道正在传递dispatchEvent,正在创建eventType对象,并且event引用了正确的目标元素。这是我得到的代码,非常感谢您的帮助。

this

修改

这是其余的代码。其实没有什么,因为我主要专注于构建扩展。

if (!EventTarget.prototype.trigger) {
    function triggerFunction(
        eventType) {
        const event = new CustomEvent(eventType, {
            bubbles: true,
            cancelable: true
        });

        this.dispatchEvent(event);
    }

    EventTarget.prototype.trigger = triggerFunction;
}

和HTML:

if (!EventTarget.prototype.on) {
    function onFunction(
        eventType,
        targetElement,
        listener) {
        if (targetElement) {
            this.addEventListener(eventType, function (
                event) {
                const target = event.target;

                if (target
                    && target.nodeName !== targetElement) {
                    return;
                }

                listener.call(target, event);
            }, false);

            return this;
        }

        this.addEventListener(eventType, listener, false);

        return this;
    }

    EventTarget.prototype.on = onFunction;
}

const _pointerTap = "click";

const photosFunction = () => {
    const $buttonPhotosUpload = document.getElementById("button-photos-upload"),
        $fieldPhotosUpload = document.getElementById("field-photos-upload");

    const onButtonPhotosUploadTap = () => $fieldPhotosUpload.trigger(_pointerTap);

    $buttonPhotosUpload.on(_pointerTap, null, onButtonPhotosUploadTap);
};

document.getElementById("photos") && photosFunction();

基本上,当按下按钮时,我想触发input:file的click事件,以便可以使用CSS可视地隐藏它。在我的jQuery版本中,这很好用。

3 个答案:

答案 0 :(得分:1)

问题在于,浏览器不仅要查看您事件的type属性,而且还要求它从正确的事件子类继承。

在这种情况下,他们想要的Event的一个子类是MouseEvent,因此您不必执行dispatchEvent(new CustomEvent('click'));来代替dispatchEvent(new MouseEvent('click'))

(从@CertainPerformance答案借来的MCVE)。

function triggerMouseFunction(eventType) {
  // here event must be MouseEvent for it to work on <input>
  const event = new MouseEvent(eventType, {
    bubbles: true,
    cancelable: true
  });
  this.dispatchEvent(event);
}
if (!EventTarget.prototype.triggerMouse) {
  EventTarget.prototype.triggerMouse = triggerMouseFunction;
}

const button = document.querySelector('button');
const input = document.querySelector('input');
button.addEventListener('click', () => {
  input.triggerMouse('click'); // Works
});
<div>
  <button type="button">{UPLOAD}</button>
  <input type="file">
</div>

但是,如果您只想触发点击事件,则一定要使用HTMLElement.click()

不需要任何库,也不需要修改EventTarget的原型,这真是个坏主意。

const button = document.querySelector('button');
const input = document.querySelector('input');
button.addEventListener('click', () => {
  input.click(); // Works
});
<div>
  <button type="button">{UPLOAD}</button>
  <input type="file">
</div>

答案 1 :(得分:0)

这是最小得多的MCVE:

function triggerFunction(eventType) {
  const event = new CustomEvent(eventType, {
    bubbles: true,
    cancelable: true
  });
  this.dispatchEvent(event);
}
if (!EventTarget.prototype.trigger) {
  EventTarget.prototype.trigger = triggerFunction;
}

const button = document.querySelector('button');
const input = document.querySelector('input');
button.addEventListener('click', () => {
  // input.click(); // Works
  // input.trigger('click'); // Doesn't work
});
<div>
  <button type="button">{UPLOAD}</button>
  <input type="file">
</div>

问题在于,分派的事件不会触发打开输入对话框的(浏览器的内置)功能。分派的事件确实会触发其他正常的侦听器。

我怀疑是否有任何方法可以在不调用内置click函数的情况下执行此操作,该函数调用浏览器的本机代码,从而允许出现对话框。一种可能性是检查eventType是否为click,以及EventTarget是否为HTMLElement。似乎已经绕开了这个问题,但是当目标需要为对话框调用浏览器的本机代码时,我认为没有另一种方法。

function triggerFunction(eventType) {
  if (this instanceof HTMLInputElement && eventType === 'click') {
    return HTMLElement.prototype.click.call(this);
  }
  const event = new CustomEvent(eventType, {
    bubbles: true,
    cancelable: true
  });
  this.dispatchEvent(event);
}
if (!EventTarget.prototype.trigger) {
  EventTarget.prototype.trigger = triggerFunction;
}

const button = document.querySelector('button');
const input = document.querySelector('input');
button.addEventListener('click', () => {
  input.trigger('click'); // Works
});
<div>
  <button type="button">{UPLOAD}</button>
  <input type="file">
</div>

当调用任何需要运行本机代码的方法时(例如console.logXMLHttpRequest(如果fetch不可用,或setTimeout),则需要类似的模式-有些事情无法使用您自己的Javascript进行模拟,而需要调用浏览器的某些本机代码。

还请注意,您似乎只是想将自定义方法添加到 HTML元素,在这种情况下,最好将trigger分配给HTMLElement.prototypeEventTarget.prototype

function triggerFunction(eventType) {
  if (this instanceof HTMLInputElement && eventType === 'click') {
    return HTMLElement.prototype.click.call(this);
  }
  const event = new CustomEvent(eventType, {
    bubbles: true,
    cancelable: true
  });
  this.dispatchEvent(event);
}
if (!HTMLElement.prototype.trigger) {
  HTMLElement.prototype.trigger = triggerFunction;
}

const button = document.querySelector('button');
const input = document.querySelector('input');
button.addEventListener('click', () => {
  input.trigger('click'); // Works
});
<div>
  <button type="button">{UPLOAD}</button>
  <input type="file">
</div>

答案 2 :(得分:0)

感谢@Kaiido,现在我可以再次使用它了。我添加了一个getEvent函数来打开eventType并返回正确的Event对象。更新后的代码如下:

function getEvent(
    eventType): Event {
    switch (eventType) {
        case "keydown":
        case "keypress":
        case "keyup":
            return new KeyboardEvent(eventType);
        case "click":
        case "dblclick":
        case "mouseup":
        case "mousedown":
            return new MouseEvent(eventType);
        default:
            return new CustomEvent(eventType);
    }
}

function triggerFunction(
    eventType) {
    const event = getEvent(eventType);

    event.bubbles = true;
    event.cancelable = true;

    this.dispatchEvent(event);
}

if (!EventTarget.prototype.trigger) {
    EventTarget.prototype.trigger = triggerFunction;
}