【问题标题】:onchange event not getting triggered when user select empty directory用户选择空目录时未触发 onchange 事件
【发布时间】:2016-02-28 12:06:10
【问题描述】:

我想使用 angularjs 实现一个场景,其中用户选择一个目录,选择后需要对该目录中的每个文件进行一些处理。

请在下面找到相同的代码 HTML 文件:

<div ng-app="myApp" ng-controller="myCtrl">
  <input id="folder" type="file" onchange="angular.element(this).scope().checkFiles(this.files)" webkitdirectory="" directory="" multiple="" />
</div>

Javascript 代码

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {

  $scope.checkFiles = function(files) {
    console.log(files);

    //add below line of code to trigger onchange event if user select same directory
    angular.element(document.querySelector('#folder'))[0].value = null;
  };
});

Plunker 链接https://plnkr.co/edit/lDhoShIVgCXLd33mPtbh?p=preview

当所选目录中有一些文件时,编写的代码工作。但是当我选择空目录时,它会触发 onchange 事件。

我尝试了很多,但没有找到导致这种行为的根本原因。

我注意到的一件事是,当我删除下面的代码行时

    //add below line of code to trigger onchange event if user select same directory
    angular.element(document.querySelector('#folder'))[0].value = null;

并选择一个包含一些文件的目录,然后选择一个空的目录 onchange 事件被触发。但是如果我第一次尝试直接选择空目录,则不会触发 onchange 事件。

需要知道为什么没有为空目录触发 onchange 事件。

注意:请在其他浏览器不支持的 chrome 浏览器上尝试此代码

【问题讨论】:

  • Angular 与否,您无法选择目录。但是您可以选择一个或多个文件,然后文件输入将触发更改事件。
  • @IgweKalu 我想选择目录,我可以做到,请检查 plunker 链接plnkr.co/edit/lDhoShIVgCXLd33mPtbh?p=preview 只是想知道为什么 onchange 事件在选择空目录时被触发。
  • 每次我选择一个目录并单击选择,它只是简单地打开目录以显示其内容。之后只启用取消选项,除非您选择一个文件或目录(在这种情况下,它只会再次打开该目录)。我不知道你是怎么做到的。我希望我能帮助你...
  • 此外,请注意除非确实发生了更改,否则不会触发更改事件。例如,如果您之前选择了文件 a.text,然后再次选择它,则不会触发更改事件。当且仅当当前选择不同于之前的选择时才会触发更改。

标签: javascript angularjs onchange


【解决方案1】:

文件输入用于选择文件。当您选择一个目录时(在 Chrome 中),它相当于选择了文件树中的所有文件(即包括所选目录内的目录文件)。

因此,如果您选择了一个空目录,则相当于没有选择文件 - 因此,触发更改事件没有任何意义。

【讨论】:

  • 但是如果你在 plunker angular.element(document.querySelector('#folder'))[0].value = null;并首先选择一个非空目录,然后选择一个空目录 onchnge 事件被触发。
  • 我明白了。我希望我能提供更多。如果它根本没有帮助,我可以删除这个答案。
【解决方案2】:

这看起来不太“有棱角”。 Angular 的方式是在 directive 中进行 DOM 操作,而不是在您的控制器中。所以你可以尝试像jsfiddle 这样的文件浏览器指令。理想情况下,对于您的 on-change 指令,您可以为其分配一个函数,例如 on-change="doSomething()",然后在您的控制器中,您可以为此函数添加逻辑。有关其他示例,请参阅 this post

请参阅this cheat sheet,了解以 Angular 的方式做事。

HTML:

<div ng-controller="parentController">
    <p><a ng-click="load('one.tpl')">One</a> | <a ng-click="load('two.tpl')">Two</a></p>
    <hr>
    <div ng-include="tpl"></div>
</div>

<script type="text/ng-template" id="one.tpl">
    <p>Template One</p>
    <div file-browser>
        <input type="file" name="upload-file">
    </div>
</script>

JS:

angular.module('testapp').controller('parentController', function($scope) {
    $scope.load = function(tpl) {
        $scope.tpl = tpl;
    };
    $scope.load('one.tpl');
});
angular.module('testapp').directive('fileBrowser', function() {
    return {
        restrict: 'A',
        replace: true,
        transclude: true,
        scope: false,
        template:
            '<div class="input-prepend extended-date-picker">'+
                '<input type="button" class="btn" value="browse...">'+
                '<input type="text" readonly class="override">'+
                '<div class="proxied-field-wrap" ng-transclude></div>'+
            '</div>',
        link: function($scope, $element, $attrs, $controller) {
            var button, fileField, proxy;
            fileField = $element.find('[type="file"]').on('change', function() {
                proxy.val(angular.element(this).val());
            });
            proxy = $element.find('[type="text"]').on('click', function() {
                fileField.trigger('click');
            });
            button = $element.find('[type="button"]').on('click', function() {
                fileField.trigger('click');
            });
        }
    };
});

【讨论】:

    【解决方案3】:

    Chrome 使用未触发更改事件原因的空文件夹初始化 FileList 对象。 我在铬https://bugs.chromium.org/p/chromium/issues/detail?id=590715 中提出了一个问题,它已合并到现有问题https://bugs.chromium.org/p/chromium/issues/detail?id=590715

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-07
      • 1970-01-01
      • 2015-08-09
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多