Knockout.js 使用自定义bindingHandler的文本输入水印
我一直在尝试创建一个自定义bindingHandler,我可以使用它为文本输入字段提供水印行为 我所说的Knockout.js 使用自定义bindingHandler的文本输入水印,knockout.js,watermark,Knockout.js,Watermark,我一直在尝试创建一个自定义bindingHandler,我可以使用它为文本输入字段提供水印行为 我所说的watermark的意思是:为文本字段添加默认值,这些默认值在聚焦时被删除,如果文本字段仍然为空,则在模糊时被替换 我已经成功地实现了这一点,如本JSFIDLE中所示: 关于此解决方案,我有3个问题: 是否有办法更改它,以便我只需声明一次水印值?目前,我必须将其放置在声明绑定的位置,并且我还必须在viewModel中使用相同的值初始化可观察对象,否则它将没有初始值 是否有更好的方法来获取元素值
watermark
的意思是:为文本字段添加默认值,这些默认值在聚焦时被删除,如果文本字段仍然为空,则在模糊时被替换
我已经成功地实现了这一点,如本JSFIDLE中所示:
关于此解决方案,我有3个问题:
$(element).val(“”)
设置值,但这也感觉不对。哪种方法最好,还是有更好的方法我认为您使用的所有绑定都是不必要的。事实上,我认为水印根本不需要意识到可观察性,因为这是水印通常做的事情,即
占位符
属性
这对你有用吗
ko.bindingHandlers.watermark = {
init: function (element, valueAccessor, allBindingsAccessor) {
var value = valueAccessor(), allBindings = allBindingsAccessor();
var defaultWatermark = ko.utils.unwrapObservable(value);
var $element = $(element);
setTimeout(function() {
$element.val(defaultWatermark);}, 0);
$element.focus(
function () {
if ($element.val() === defaultWatermark) {
$element.val("");
}
}).blur(function () {
if ($element.val() === '') {
$element.val(defaultWatermark)
}
});
}
};
希望这能有所帮助。只要你的应用程序逻辑非常简单,前面的方法就可以了。请注意,解决方案会弄乱你的视图模型的值,这些值是可以观察到的,它们可以有订阅或计算关联到它,所以通过更改值,你可以更改你的视图模型。这是一个不更新视图模型的不同解决方案
ko.bindingHandlers.fakePlaceHolderWhenNeedIt = {
init: function (element, valueAccessor, allBindings, vm) {
if (!Modernizr.input.placeholder) {
var placeHolderVal = $(element).attr("placeholder");
if (placeHolderVal != null || placeHolderVal != '') {
var $element = $(element);
var value = valueAccessor()
var valueUnwrapped = ko.utils.unwrapObservable(value);
$element.keyup(function () {
var inputValue = $(this).val();
var $watermark = $(this).prev('.ie-placeholder');
if (inputValue == null || inputValue == '') {
$watermark.show();
}
else {
$watermark.hide();
}
});
var display = valueUnwrapped != null || valueUnwrapped != '' ? "block" : "none";
var left = $element.position().left;
var top = $element.position().top;
var paddingLeft = $element.css('padding-left');
var paddingRight = $element.css('padding-right');
var paddingTop = $element.css('padding-top');
var paddingBottom = $element.css('padding-bottom');
var height = $element.css('height');
var placeHolder = '<div class="ie-placeholder" style="position:absolute;left:' + left + ';top:' + top + ';padding-top: ' + paddingTop + ';padding-bottom: ' + paddingBottom + ';padding-left: ' + paddingLeft + ';padding-right: ' + paddingRight + ';height: ' + height + ';line-height:' + height + ';display:' + display + ';">' + placeHolderVal + '</div>';
$(placeHolder).click(function () { $element.focus(); }).insertBefore(element);
}
}
},
update: function (element, valueAccessor, allBindings, vm) {
if (!Modernizr.input.placeholder) {
var placeHolderVal = $(element).attr("placeholder");
if (placeHolderVal != null || placeHolderVal != '') {
var $element = $(element);
var value = valueAccessor()
var valueUnwrapped = ko.utils.unwrapObservable(value);
var $watermark = $element.prev('.ie-placeholder');
if (valueUnwrapped == null || valueUnwrapped == '') {
$watermark.show();
}
else {
$watermark.hide();
}
}
}
}
ko.bindingHandlers.fakePlaceholder WhenneEdit={
init:函数(元素、valueAccessor、allBindings、vm){
if(!modernizer.input.placeholder){
变量占位符val=$(元素).attr(“占位符”);
如果(占位符val!=null | |占位符val!=''){
变量$element=$(element);
var value=valueAccessor()
var valueUnwrapped=ko.utils.unwrapObservable(值);
$element.keyup(函数(){
var inputValue=$(this.val();
var$watermark=$(this.prev('.ie占位符');
如果(inputValue==null | | inputValue==“”){
$watermark.show();
}
否则{
$watermark.hide();
}
});
变量显示=valueUnwrapped!=null | | valueUnwrapped!=“块”:“无”;
var left=$element.position().left;
var top=$element.position().top;
var paddingLeft=$element.css('padding-left');
var paddingRight=$element.css('padding-right');
var paddingTop=$element.css('padding-top');
var paddingBottom=$element.css('padding-bottom');
var height=$element.css('height');
变量占位符=“”+占位符val+“”;
$(占位符)。单击(函数(){$element.focus();});
}
}
},
更新:函数(元素、valueAccessor、allBindings、vm){
if(!modernizer.input.placeholder){
变量占位符val=$(元素).attr(“占位符”);
如果(占位符val!=null | |占位符val!=''){
变量$element=$(element);
var value=valueAccessor()
var valueUnwrapped=ko.utils.unwrapObservable(值);
var$watermark=$element.prev('.ie占位符');
如果(valueUnwrapped==null | | valueUnwrapped==“”){
$watermark.show();
}
否则{
$watermark.hide();
}
}
}
}
是的,这几乎与我更改为使用allBindingsAccessor之前的情况完全相同。在尝试设置初始值时,我缺少了setTimeout
。您能否简要解释一下为什么需要这样做?另外,您知道是否有更好的方法?或者您认为这是一种好(足够)的方法(就整个解决方案而言)?例如,我注意到有一个hasfocus绑定(内置)。这可能是一种更好的方法吗?如果您想支持旧浏览器,我认为这种方法很好。对于新浏览器,只需使用占位符属性。需要setTimeout,因为在设置输入值之前,KO内部使用setTimeout。这意味着您的代码在KO代码设置值之前运行,因此您需要设置再次超时以确保您的代码在执行过程中是最后一个。非常感谢您的解释和帮助。哇。我不希望找到完整的解决方案。谢谢!关于设置超时非常有趣,我直到现在才意识到这是必需的。谢谢。