【问题标题】:Knockout drag and drop : On drag enter hiding div and on drag leave show div [Mine is different]淘汰赛拖放:在拖动时进入隐藏 div,在拖动时离开显示 div [我的不同]
【发布时间】:2015-07-10 00:11:51
【问题描述】:

我是淘汰 JavaScript 的新手。在我的项目中,我使用 Knockout 拖放功能。最初我有两个部门,一个是可见的,另一个是没有属性显示的。当我在做拖动输入功能时,我需要隐藏第一个分区并显示第二个分区。一旦拖动离开隐藏第二师并显示第一师。但问题是当我拖动进入第二个部门时,功能正在改变我不想隐藏第二个部门直到下降。请帮我解决。

我不想更改“.typeTextareaSection”(在代码中)块中的任何 html。

这是我的小提琴Knockout Drag and drop Fiiddle

function ViewModel(){
    var self = this;
    this.dropZones = ko.observableArray([{
        'elements' : ko.observableArray([])  // just to see that the output is correct
    }]);

   
    this.dragoverTextarea = function(e){
        console.log('dragOver');
        e.stopPropagation();
        e.preventDefault();
    }

    this.dropTextarea = function(e, data){
        console.log('drop');
        e.stopPropagation();
        e.preventDefault();
        var files = e.dataTransfer.files;
        for (var i = 0, f; f = files[i]; i++) {
            data.elements.push(f.name);
        }
        $('.typeTextarea').children('.typeTextareaSection').css('display', 'block');
			$('.typeTextarea').children('#dragtimeTextarea').css('display', 'none');

    }

    this.dragenterTextarea = function(e, index){
        console.log('dragEnter');
              $('.typeTextarea').eq(index).children('.typeTextareaSection').css('display', 'none');
			$('.typeTextarea').children('#dragtimeTextarea').css('display', 'block');
    }

    this.dragleaveTextarea = function(e, index){
        console.log('end');        
        $('.typeTextarea').children('.typeTextareaSection').css('display', 'block');
			$('.typeTextarea').children('#dragtimeTextarea').css('display', 'none');
    }
}

ko.applyBindings(new ViewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>

<div class="col-md-12" data-bind="foreach: dropZones">
    <div class="typeTextarea" style="margin-top: 20px; height: 120px; border: 2px dashed #bbb; padding: 10px;" data-bind="event: {
        dragover: function (data, e) { $root.dragoverTextarea(e); },
        drop: function (data, e) { $root.dropTextarea(e, $data); },
        dragenter: function (data, e) { $root.dragenterTextarea(e, $index()); },
        dragleave: function (data, e) { $root.dragleaveTextarea(e, $index()); }
    }">
		<div class="typeTextareaSection">
			<div class="headerForTypeArea">
				
	            <img style="text-align: right; float: right; cursor: pointer;" src="Content/images/cancel27.png" alt="Cancel" title="Cancel" />
				<img style="text-align: right; float: right; cursor: pointer;padding-right:5px;" src="Content/images/correctBox2.png" alt="Save" title="Save" />
				<div style="clear: both;"></div>
			</div>

			<div class="ContentEditableSection">
                <textarea  class="ediitableTestAreaPlaceHolders" maxlength="25000" style="margin-bottom: 0px; height: 70px; width: 99%;" placeholder="drop files here..." ></textarea>

			</div>
		</div>

		<textarea id="dragtimeTextarea" placeholder="Over this area to check my problem" style="display:none;font-size:20px;color:#000;"></textarea>

	</div>
</div>

【问题讨论】:

标签: jquery html css knockout.js


【解决方案1】:

您解决此问题的方法不够结构化。

要内化的最重要的事情是每次从视图模型中修改 DOM 时,您都在做错事。您的视图模型必须不了解您的页面结构、元素、CSS 类或 DOM 事件。您的视图应该取决于您的视图模型,而不是相反。

进行 DOM 交互的唯一地方是:在绑定中。如果没有内置绑定可以满足您的需求,那么您可以create a custom one

在您的情况下,您希望封装将文件拖放到元素上的操作。这应该有两个效果:

  • 当您将鼠标悬停时,某些元素应该会做出明显的反应
  • 删除的文件应放入可观察数组中

这有效地确定了绑定的接口:

  • 一个可观察对象,在悬停时将存储 true,否则将存储 false
  • 将接收已删除文件的可观察对象

所以让我们调用新的绑定filedrop,这就是它的使用方式:

<div data-bind="filedrop: {hover: hovering, drop: files}"></div>

hoveringfiles 在您的视图模型中是可观察的。下面是绑定的样子:

ko.bindingHandlers.filedrop = {
    init: function (element, valueAccessor) {
        var options = valueAccessor();

        ko.utils.registerEventHandler(element, "dragenter", function (e) {
            if (ko.isWriteableObservable(options.hover)) options.hover(true);
            e.preventDefault();
        });
        ko.utils.registerEventHandler(element, "dragleave", function (e) {
            if (ko.isWriteableObservable(options.hover)) options.hover(false);
            e.preventDefault();
        });
        ko.utils.registerEventHandler(element, "dragover", function (e) {
            e.preventDefault();
        });
        ko.utils.registerEventHandler(element, "drop", function (e) {
            if (ko.isWriteableObservable(options.drop)) {
                if (typeof options.drop.push === "function") {
                    options.drop.push.apply(options.drop, e.dataTransfer.files);
                } else {
                    options.drop(e.dataTransfer.files);
                }
            }
            if (ko.isWriteableObservable(options.hover)) options.hover(false);
            e.preventDefault();
        });
    }
};

现在您可以通过创建包含 hoveringfiles 可观察对象和其他相关内容的专用 DropZone 视图模型来清理您的视图模型图:

function DropZone() {
    var self = this;
    self.text = ko.observable();
    self.files = ko.observableArray();
    self.hovering = ko.observable(false);
    self.filenames = ko.computed(function () {
        return ko.utils.arrayMap(self.files(), function (element) {
            return element.name;
        });
    });
}

现在您的主视图模型应该是这样的:放置区列表。

function ViewModel() {
    var self = this;
    self.dropZones = ko.observableArray([
        new DropZone()
    ]);
}

在此之后,构建视图也不再是问题。

<div class="col-md-12" data-bind="foreach: dropZones">
    <div class="dropZone" data-bind="filedrop: { hover: hovering, drop: files }">
        <div class="textPane" data-bind="visible: !hovering()">
            <div class="buttonBar">
                <img src="Content/images/cancel27.png" alt="Cancel" title="Cancel" />
                <img src="Content/images/correctBox2.png" alt="Save" title="Save" />
            </div>
            <textarea maxlength="25000" data-bind="value: text" placeholder="Start typing here&hellip;"></textarea>
        </div>
        <div class="dropPane" data-bind="visible: hovering">Drop files here&hellip;</div>
    </div>
</div>

所有这些都留给你

  • 您可以在不同的地方或项目中重复使用的自定义绑定
  • 一组实际上只包含它们应该包含的视图模型
  • 整体干净且可维护的设置

http://jsfiddle.net/kd7umbj4/2/

【讨论】:

  • 这个解决方案非常感谢。但我需要改变我的实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-30
  • 2021-05-11
  • 2013-08-30
  • 2017-04-18
  • 2010-12-28
  • 2021-06-13
  • 1970-01-01
相关资源
最近更新 更多